Duvida Avançada de um Principiante ( Spring Boot + Hibernate + JPD)

Bom Dia pessoal…
Estou com um duvida, tenho lido e estuda bastante, sobre Spring, comprei cursos, livros e etc…
Ja considero um certa evolução no mesmo, mas estou com uma duvida…

Eu terei em minhas aplicações varias consultas complexas no banco de dados, como essa por exemplo:

     DECLARE @SQLStr              VARCHAR(8000)
    DECLARE @EMPR_ID              VARCHAR(8000)
    DECLARE @ANO                 INT

    SET @ANO = ?    
    SET @EMPR_ID = ?
    SET @SQLStr        = ''

    SELECT @SQLStr = @SQLStr + '[' + [a].[Column]+'], '
      FROM (select CONVERT(VARCHAR(50),DATA,3 ) AS [Column] from [dbo].[FN_LISTA_DATA] (Convert(Varchar(10),@ANO)+'0101',Convert(Varchar(10),@ANO)+'1231')
              )as a 

    SET @SQLStr = LEFT(@SQLStr,len(@SQLStr)-1)

    SET @SQLStr = 'SELECT EMPR_NOME,'  + @SQLStr +CHAR(13)
                +' FROM (SELECT EMPR.EMPR_NOME, SUM(MVFO_VALOR) AS VALOR, CONVERT(VARCHAR(50),MVFO_DATA,3) as MVFO_DATA '+CHAR(13)
                +'         FROM MOVIMENTO_FINANCEIRO_ORCAMENTO MVFO '+CHAR(13)
                +'              INNER JOIN UNIDADES_EMPRESARIAIS UNEM ON UNEM.UNEM_ID = MVFO.UNEM_ID'+CHAR(13)
                   +'                                                   AND UNEM.UNEM_NOME_REF <> '''' '+CHAR(13)
                +'              INNER JOIN EMPRESAS EMPR ON EMPR.EMPR_ID = UNEM.EMPR_ID '+CHAR(13)
                +'              INNER JOIN CONTA CONT ON CONT.CONT_ID = MVFO.CONT_ID '+CHAR(13)
                +'                                   AND CONT.CONT_ID = EMPR.EMPR_CONT_RECEITA_LIQ '+CHAR(13)
                +'        WHERE YEAR(MVFO_DATA) = '+ Convert(Varchar(10),@ANO)
                +'          AND UNEM.EMPR_ID IN (  '+ @EMPR_ID +')'+CHAR(13)
                +'        GROUP BY  EMPR.EMPR_NOME, UNEM.EMPR_ID ,MVFO_DATA '+CHAR(13)
                + ' ) sq PIVOT (SUM(VALOR ) FOR MVFO_DATA IN(' +@SQLStr+')) AS pt '+CHAR(13)
                + ' ORDER BY EMPR_NOME '+CHAR(13)
     EXEC(@SQLStr);

Na minha aplicação web pura, eu criaria um método assim :

 public String[][] getListaEntradas(String ano, String empr, String linha) throws SQLException {
        String sql = "DECLARE @SQLStr              VARCHAR(8000)\n"
                + "      , @SQLStr2              VARCHAR(8000)\n"
                + "DECLARE @ANO INT\n"
                + "      , @EMPR_ID VARCHAR(8000)\n"
                + "	  , @COFC_TIPO_CONF VARCHAR(8000)\n"
                + "\n"
                + "SET @ANO = ?  \n"
                + "SET @EMPR_ID = ?  \n"
                + "SET @COFC_TIPO_CONF = ?\n"
                + "SET @SQLStr         = ''\n"
                + "SET @SQLStr2        = ''\n"
                + "\n"
                + "SELECT @SQLStr = @SQLStr + 'isnull([' + [a].[Column]+'],0) as[' + [a].[Column]+'], '\n"
                + "  FROM (select CONVERT(VARCHAR(50),DATA,3 ) AS [Column] from [dbo].[FN_LISTA_DATA] (Convert(Varchar(10),@ANO)+'0101',Convert(Varchar(10),@ANO)+'1231')\n"
                + "          )as a \n"
                + "\n"
                + "SET @SQLStr = LEFT(@SQLStr,len(@SQLStr)-1)\n"
                + "\n"
                + "SELECT @SQLStr2 = @SQLStr2 + '[' + [a].[Column]+'], '\n"
                + "  FROM (select CONVERT(VARCHAR(50),DATA,3 ) AS [Column] from [dbo].[FN_LISTA_DATA] (Convert(Varchar(10),@ANO)+'0101',Convert(Varchar(10),@ANO)+'1231')\n"
                + "          )as a \n"
                + "\n"
                + "SET @SQLStr2 = LEFT(@SQLStr2,len(@SQLStr2)-1)\n"
                + "\n"
                + "SET @SQLStr = 'SELECT FCTO_LINHA,EMPR_NOME,'  + @SQLStr +CHAR(13)\n"
                + "            +' FROM (SELECT FCTO_LINHA, EM.EMPR_NOME, FCTO_ORDENACAO, SUM(FCTO_VALOR)  AS FCTO_VALOR, CONVERT(VARCHAR(50),FCTO_DATA,3) as FCTO_DATA '+CHAR(13)\n"
                + "            +'         FROM FLUXO_TOTALIZADORES FT'+CHAR(13)\n"
                + "			+'         INNER JOIN EMPRESAS      EM on EM.EMPR_ID = FT.EMPR_ID'+CHAR(13)\n"
                + "            +'          WHERE YEAR(FCTO_DATA) = '+ Convert(Varchar(10),@ANO)          \n"
                + "			+'            AND CharIndex(FCTO_LINHA,'''+@COFC_TIPO_CONF+''') <> 0'+CHAR(13)\n"
                + "            +'        GROUP BY FCTO_LINHA, EM.EMPR_NOME, FCTO_ORDENACAO, FCTO_DATA  '+CHAR(13)\n"
                + "            + ' ) sq PIVOT (SUM(FCTO_VALOR ) FOR FCTO_DATA IN(' +@SQLStr2+')) AS pt '+CHAR(13)\n"
                + "            + ' ORDER BY FCTO_ORDENACAO '+CHAR(13)\n"
                + "\n"
                + "exec(@SQLStr);";

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = connection.prepareStatement(sql);
            ps.setString(1, ano);
            ps.setString(2, empr);
            ps.setString(3, linha);
            rs = ps.executeQuery();

            ResultSetMetaData rsmd = rs.getMetaData();
            int numColunas = rsmd.getColumnCount();
            int numLinha = 0;

            while (rs.next()) {
                numLinha++;
            }

            rs.close();
            ps.close();

            ps = connection.prepareStatement(sql);
            ps.setString(1, ano);
            ps.setString(2, empr);
            ps.setString(3, linha);
            rs = ps.executeQuery();

            String[][] dados = new String[numLinha][numColunas];
            while (rs.next()) {
                for (int i = 1; i <= numColunas; i++) {
                    dados[rs.getRow() - 1][i - 1] = rs.getString(i);
                }
            }
            return dados;

        } catch (SQLException e) {
            Logger.getLogger(SubCategoriaForecastDao.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            // connection.close();
            // rs.close();
            //ps.close();
        }
        return null;
    }

Como eu deverei fazer esse tipo de consulta no Spring ??
Existem outras inúmeras consultas criando objetos específicos, como vou criar as classes, sem que elas sejam entidades, pois seriam classes somente para resgate dos dados, não sendo necessário criação de tabelas…

Se alguém puder me indicar materiais a respeito.

Você quis dizer consulta usando algum recurso da Spring ou quis dizer Hibernate?

Uma opção da Spring para acesso a dados:
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html

Se for em relacão a Hibernate, pesquise por “native Sql query”

1 curtida

Agora que você me fez essa pergunta, me levou a outra duvida, se estou usando Spring ou Hibernate nas consultas, ou os dois né…

Tenho feitos consultas simples, criando a clase e utilizando o @Entity, e realizando as instruções no banco via repositório.

Exemplo:

@Entity
@Table(name = "MENU")
public class Menu implements Serializable {
    
    @Id
    @Basic(optional = false)
    @Column(name = "MENU_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int menuId;
    @Size(max = 200)
    @Column(name = "MENU_NOME")
    private String menuNome;
    @OneToMany(mappedBy = "menuId", targetEntity = MenuItem.class, orphanRemoval = true, fetch = FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    @JsonBackReference
    private List<MenuItem> itensMenu = new ArrayList<MenuItem>();
    @Size(max = 200)
    @Column(name = "MENU_ICONE")
    private String menuIcone;
    @Size(max = 10)
    @Column(name = "MENU_ORDEM")
    private String menuOrdem;
}


public interface MenuRepository extends JpaRepository<Menu, Integer> {

}

Você está usando JpaRepository da Spring. Pode se guiar por esse exemplo: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.named-queries

Qualquer coisa que implemente JPA eu particularmente acho confuso e engessado. Olha o quanto de lixo tem pendurado na sua classe.

1 curtida

Realmente, eu li em algum tópicos e livros, que só se usa JpaRepository quando realmente necessário, outros lugares vi utilizando o CrudRepository… Essas documentações do Spring já me ajudam muito…

Qual e a maneira que você trabalha ??
Eu poderia por exemplo criar minha própria classe com os comando específicos, e usar a anotação @Repository ??

Não trabalho com Java no momento. De ORM Java já trabalhei com Hibernate, mas em todas as consultas/relatórios eu usava diretamente SQL nativo.

Você pode seguir a parte “Example 50. Declare a native query at the query method using @Query” do último link que te passei.

1 curtida