Pergunta

Esta é a mesma pergunta que:

Como gerar dinamicamente consulta SQL com base no usuário seleções?

A única diferença é que eu estou interessado em ver soluções também utilizando Java / JPA (+ possivelmente EclipseLink ou Hibernate extensões específicas).

Eu preciso criar uma GUI, usando o que os usuários podem selecionar vários atributos que serão utilizados para consultar o banco de dados para encontrar pessoas adequadas. Estou à procura de idéias de como gerar dinamicamente a consulta de banco de dados de acordo com as escolhas do usuário.

Consulta irá conter vários campos, mas para obter a ideia que irá incluir apenas três dos que estão abaixo como um exemplo:

  • Ocupação - não pode ser 0 para cordas n ocupação. Se cordas ocupação são dadas, um deles tem que corresponder.

  • Idade - idade pode ser dado como:

    1. correspondência exata (30)
    2. gama (por exemplo 30-40)
    3. inferior a um valor (-40)
    4. mais de um valor (30 -)
parâmetro

Idade é opcional na consulta. Além disso, o usuário pode especificar se a idade é um parâmetro obrigatório. Se não é necessário, e uma pessoa não tem a idade é sua / seu perfil, critérios de idade é ignorado para esta pessoa.

  • Altura - semelhante como idade

Consultas de Exemplo:

Nenhum critério foi dado:

select * from persons

Apenas ocupação foi dado:

select * from persons where occupation = 'dentist'

Várias ocupações foram deixados:

select * from persons where (occupation = 'dentist' or occupation = 'engineer')

Idade tem sido dado como um maior do que o valor, e é exigido de existir no perfil da pessoa:

select * from persons where age >= 30

Altura foi dado como um intervalo, e não é necessário para existir no perfil da pessoa:

select * from persons where (height is null or (height >= 30 and height <= 40))

A combinação de diferentes critérios:

select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40))

Eu já implementaram código que é capaz de gerar consultas como cordas, mas certamente não é muito bonito. Estou à procura de ideias que seria a maneira mais eficiente e mais bonita para alcançar este objectivo.

Foi útil?

Solução

No Hibernate, você pode usar Critérios consultas.

Em Toplink, temos Expressão e ExpressionBuilder .

Outras dicas

Existem muitas ferramentas diferentes o melhor que eu acho que são querydsl , torpedoquery e objeto de consulta , este três permitem a escrever typesafe consulta, caso contrário, você pode usar critérios api, e se você estiver usando jpa 2 também JPA2 Typesafe consulta .

com todas estas ferramentas você pode construir uma consulta em tempo de execução !!

Se você quiser fazer isso em JPA 1.x, você pode usar o construtor de consulta personalizada, conforme descrito aqui http://rrusin.blogspot.com/2010/02/jpa-query-builder.html . Isso permite consultas criando assim:

return new JpaQueryBuilder().buildQuery(em,
                new Object[] {
                    "select c from Car c where c.name is not null",
                    new JQBParam("name", name, " and c.name = :name"),
                    new JQBParam("type", type, " and c.type = :type")
                }
            )

No meu código, estou usando AND e objetos OR para isso. Eles tomam listas como parâmetros (aparência agradável com argumentos variádicos do Java 5) e concatenar-los em Cordas com os espaços e parênteses necessárias. pseudo-código:

AND(WhereCond ... conds) { this.conds = conds; }
toString() { return conds.length == 0 ? "" : "(" + join(conds, " AND ") + ")" };

onde join() converte a matriz objeto a matriz de cadeia e, em seguida, junta-se aos elementos com o parâmetro.

scroll top