Spring Boot > Função para executar todas as querys da aplicação

3 respostas
springmysqlspring-bootjava
S

Estou numa equipe de programadores onde a maioria é desenvolvedor Delphi. E eles decidiram que seria melhor seguir e transcrever os padrões de programação e funções que existem hoje nas aplicações Delphi da empresa para Java.
Aplicação que está sendo desenvolvida é um Web Service REST API com Spring Boot, com Spring Data JPA e MySQL. Estava sendo utilizado padrões para comunicação com o banco de dados, com JPARepository, PagingAndSortingRepository e para situações de Querys dinâmicas CriteriaBuilder, Predicate, seguindo a ideia dos exemplos demonstrados nos links: (JpaPagination
Spring Data Jpa Query

Porém a maioria dos programadores, decidiram que seria melhor usar o padrão da empresa das Aplicações Delphi, que seria montar uma String concatenando os parâmetros seguindo o exemplo simples a seguir:
String sql = “SELECT t.a, t.b, t.c FROM table t " +
“WHERE t.a LIKE '%”+parametroA+”%’"
"AND t.b = "+parametroB
execSQL(sql);

Mesmo alertando sobre os riscos dos SQLInjections, eles acham melhor criar uma função desta maneira, tratando os riscos dos SQLInjections, do que usar parâmetros nas Querys. Pois acham que o JPA vai limitar a aplicação, como exemplo utilizar subquerys. Não conseguir montar uma query mais robusta, apenas concatenando novos ‘ANDs’ a query principal, entre outras situações.

Eu gostaria de uma ajuda para construir está função, não encontrei nenhum exemplo que me ajudasse a fazer da maneira que eles pediram, tratando os perigos do SQLInjection, e outros problemas que desconheço que possam surgir, e ninguém da equipe tem conhecimento em Java e Spring Boot, então eu fiquei responsável por isso, estou sem ideias de como resolver está situação.

Desde já Agradeço, fico a disposição.

3 Respostas

J

Usar diretamente SQL é muito mais prático, ter total controle da query não tem preço. Criteria é a maior aberração que já vi. Jpql/Hql embora seja legível cai nas burocracias do modelo orientado a objetos. Ambos acrescentam overhead e pode cair em limitações, nao podendo usar todos os recursos do banco específico.

Voce pode usar SQL com Spring Data JPA. Prefiro JdbcTemplate por ser mais leve, mais enxuto pra SQL e DTO. Avaliem cada opção. Embora eu nao goste de Jpa com Jpql/Hql, avaliem tambem.

Mesmo no Delphi é errado fazer esse tipo de concatenação que mostrou. Nao é “padrão Delphi”, foi coisa do programador. Trabalhei anos e anos com Delphi sempre usando parameters do ADOQuery por exemplo. Entao quanto a isso voce está certo, basta mandar pra eles artigos sobre SQL injection, isso é um assunto bem antigo até.

Mesmo setando parâmetros corretamente, garanto que nao terá nenhuma limitação se usar diretamente SQL. Pra deixar um AND opcional basta fazer isso:

and (:parametro is null or campo = :parametro)

Se setar o parametro como nulo, o banco vai ignorar o outro lado do OR, anulando esse AND, sem onerar em nada na performance, pois é uma simples comparacao com parametro, sem acessar nada físico no banco. Caso contrário, se tiver valor, vai fazer a condição do AND. Isso nao tem haver com sql injection, mas deixa a query mais organizada. Se precisar concatenar AND pode também, com JdbcTemplate ou com JPA usando createNativeQuery.

S

Creio que me expressei mal falando “padrão Delphi”, é o padrão da empresa, que eles utilizam no Delphi. Hoje comentei sobre a parametrização, eles me disseram que usaram tempos atrás nos projetos, mas eles decidiram que aquilo engessava muitos eles nas Queries e na programação por isso optaram pela concatenação. Que na minha opinião é errado.

“Um desabafo: Por ser o mais novo de experiência na empresa, todos tentam fazer me ‘converter’ ao padrão deles, mesmo que seja em plataformas distintas (Todos: Desktop, Eu: Web/Mobile) e soluções diferentes, mesmo que seja soluções ‘erradas’. Como concatenação de parâmetros. Não programar Orientado a Objeto, pq o código fica extenso, entre outras situações.”

Sobre a utilização do SQL diretamente, achei bem interessante o uso do JDBCTemplate, acho que será uma utilização válida, próximo dos dois mundos dos grupo do nossos programadores.

Me aventurei utilizando o Spring Data JDBC, para continuar aproveitando os PaginantionRepository do Spring, porém ainda estou com algumas dificuldades para configurar conforme minha necessidade, não encontrei bons exemplos para usar como base.

Exemplo a utilização de namedParameters conforme me auxiliou no SQL acima, utilizando o filtro de exemplo ele realiza busca sem erro, porém não tenho resultado, mesmo tendo resultado válidos para Query. Ainda estou na busca de bons exemplos, se tiver algum, agradeço muito.

Mas ainda tenho dúvidas, não sei se seria o caso de um novo tópico. Estou precisando elaborar uma solução parecida com algo que vi com Criteria: Consulta Criteria, Criteria Spring Boot
A ideia seria gerar o meu SQL baseado em uma Lista de filtros, onde teria meus campos, a forma de comparação e o valor a sem comparado, seguindo a ideia dos exemplos do Criteria.
Com isso gerar uma abstração, onde pudesse gerar SQL com junção de ‘OR’, ‘AND’, etc. Podendo gerar algo conforme exemplo:

String param1 = "ALGUÉM";
Integer param2 = 1;

FiltroBusca filtroBuscaNome = new FiltroBusca("nome", LIKE, params1);
FiltroBusca filtroBuscaSobreNome = new FiltroBusca("sobrenome", LIKE, params1);
FiltroBusca filtroBuscaCidade = new FiltroBusca("cidade", EQUAL, params2);

filtrarCliente(Arrays.asList(filtroBuscaCidade, filtroBuscaNome, filtroBuscaSobreNome), pageable)`

Com isso gerando uma SQL próxima á isso:

SELECT * FROM cliente c
WHERE 1=1
AND (c.nome LIKE %param1% OR c.sobrenome LIKE %param1%)
AND c.cidade = param2
LIMIT 0, 20

Claro setando que busca por nome e sobrenome são uma SQL ‘única’ comparadas por OR que está SQL resultante, se torna uma única com a de cidade unidos por AND, estou em busca de algo como isso, qualquer ajuda é bem vinda.

Irei tentar me aprofundar mais na sua dica do JDBCTemplate.

Desde já agradeço

J

Já que é um padrão da empresa e não deram a mínima pro alerta, problema deles ficarem sob esses riscos. Nem se estresse, você é só um funcionário que poderá ter melhores oportunidades. Importante que você alertou sobre os perigos.

Sobre abstrações eu evito ao máximo. Prefiro que cada funcionalidade fique com sua própria query e livre pra escrever SQL. Na hora da manutenção uma coisa nao impacta a outra. Senão fica aquele código caseiro engenhoso que só uma pessoa domina, todo mundo tem medo de mexer e corre o risco de quebrar várias funcionalidades.

Sobre materiais sobre JdbcTemplate, tem muita coisa se pesquisar no google. Alguns exemplos:

https://dzone.com/articles/native-queries-with-spring-boot

Ideal é estudar e conforme tiver dúvida postar novos tópicos com base no que está produzindo.

Criado 10 de junho de 2020
Ultima resposta 11 de jun. de 2020
Respostas 3
Participantes 2