Consulta com Criteria

12 respostas
J

Como selecionar os valores de determinada coluna do Banco com Criteria?

12 Respostas

D

quando vc da um

objeto.list()

ele lhe traz tudo, ai basta vc especificar qual “coluna” voce quer pegar. Exemplo:

objeto.getPropriedade();

abraços!

R

geralmente o Criteria popula um objeto todo, vc está usando uma entidade mapeada?

J

Sim, estou usando uma entidade mapeada!

J

Minha classe está desta forma

@Entity
@Table(name="operacao")
public class Operacao 
{
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int codOperacao;
	
	@Column
	private String nome;
	
	@Column
	@Temporal(TemporalType.DATE)
	private Date dataCadastro;
	
	
	public Operacao(){
		Calendar cal = Calendar.getInstance();
		this.dataCadastro = cal.getTime();
	}
	
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public Date getDataCadastro() {
		return dataCadastro;
	}
	public void setDataCadastro(Date dataCadastro) {
		this.dataCadastro = dataCadastro;
	}
	
	

}

Como ficaria a minha Criteria??

R

Na anotação @Column vc não precisa inserir o nome respectivo da coluna no banco?

@Column(name="nome_coluna")
J

Não, ele coloca o nome do próprio atributo da classe.
Você especifica o nome, quando você quer que o nome do atributo no banco, seja diferente do seu atributo da classe!

F

Pelo que entendi, você quer apenas algumas colunas da tabela.
Se for isso mesmo, use Projection.

DetachedCriteria criteria = DetachedCriteria.forClass(Entidade.class);
ProjectionList projection = Projections.projectionList();
projection.add("nomeDaPropriedade", "aliasDaPropriedade");
criteria.setProjection(projection);
D

finotti:
Pelo que entendi, você quer apenas algumas colunas da tabela.
Se for isso mesmo, use Projection.

DetachedCriteria criteria = DetachedCriteria.forClass(Entidade.class); ProjectionList projection = Projections.projectionList(); projection.add("nomeDaPropriedade", "aliasDaPropriedade"); criteria.setProjection(projection);

Projections serve para selecionar apenas as colunas da tabela?

F

Nesse exemplo que passei, vc consegue definir as colunas que vc quer trazer ao invés de trazer o objeto inteiro. Imagine que vc precise de apenas 2 campos de uma tabela que tem 30 colunas…
Mas Projections tem muita coisa útil (count, sum, avg, min, max, etc…)
http://docs.jboss.org/hibernate/core/3.5/javadoc/org/hibernate/criterion/Projections.html

D

Nesse exemplo que passei, vc consegue definir as colunas que vc quer trazer ao invés de trazer o objeto inteiro. Imagine que vc precise de apenas 2 campos de uma tabela que tem 30 colunas…
Mas Projections tem muita coisa útil (count, sum, avg, min, max, etc…)
http://docs.jboss.org/hibernate/core/3.5/javadoc/org/hibernate/criterion/Projections.html

nossa muito interessante. não conhecia… obrigado.

G

Boa Noite,

Revivendo o tópico… :twisted:

Bom o caso é que aproveitando o embalo da discussão, minha criteria tem algumas @Entity envolvidas, e o retorno até vem certo, porem ao ver o SQL que ele gera… é de dar medo.

Já li que com Projections você consegue pegar apenas determinada coluna… mas o caso é que queria pegar TODAS as colunas, mas só de DETERMINADA @Entity.

Exemplo de Criteria

// (Desculpem pelo exemplo.. é bem idiota mesmo... só p/ ilustrar minha necessidade)
Criteria criteria = session.createCriteria(Usuario.class, "main")
 				                   .createCriteria("main.tabAtivo", "main_tabAtivo")
 				                   .createCriteria("main.grupoUsuario", "main_grupoUsuario")
 				                   .createCriteria("main_grupoUsuario.empresa", "main_grupoUsuario_empresa")
 				                        .add( Restrictions.eq("main.nome", "Guilherme") )
 				                        .add( Restrictions.eq("main_tabAtivo.chAtivo", TabAtivo.ATIVO) )
 				                        .add( Restrictions.eq("main_grupoUsuario.desc", "Administradores") )
 				                        .add( Restrictions.eq("main_grupoUsuario_empresa.chave", "chave-empresa") );

Então como podem ver… temos ai 3 tabelas envolvidas além do from principal.

Queria saber fazer com criteria oq conseguimos fazer com HQL/SQL como abaixo:

// Novamente outro exemplo idiota  =P
SELECT  usuario.*  FROM usuario JOIN grupoUsuario JOIN empresa WHERE ....... (condicoes);

Ou seja, independente de quantas Entitys estão envolvidas na Criteria, gostaria de pegar TODAS as colunas de determinada @Entity.

Ou não tem jeito? nesse caso teria que dar "add(Projections… " até atender todas as colunas que quero ?

Vlw. :wink:

G

Bom Pessoal,

Acabei resolvendo meu problema com uma implementação que não sei até que ponto é o correto fazer.
Mas se enquadrou muito bem no meu cenário e estou disponibilizando a solução p/ que eu tinha questionado.

O problema é que ao montar uma Criteria com relacionamentos, todos os atributos das classes envolvidas na critéria sempre vem no "select".
E eu queria que minhas criterias retornassem apenas os atributos da classe que originou a critéria.

Oq eu fiz foi montar um Map com as fields da minha @Entity, e navegar por esse Map adicionando à ProjectionList que foi adicionado na Criteria.

SegModulo.java
@Entity
@Table(name="seg_modulo", schema="public")
public class SegModulo extends Persistivel implements Jsonable {
	
	@Column(length=20)
	private String text;
	
	@Column(name="icon_cls", length=50)
	private String iconCls;
	
	@Column(name="fl_expanded", length=1)
	private String flExpanded;
	
	@Column(name="item_id", length=200)
    private String itemId;
	
	@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="id_tab_ativo")
    private TabAtivo tabAtivo;

    // Getters & Setters
}
TabAtivo.java
@Entity
@Table(name="tab_ativo", schema="public")
public class TabAtivo extends Persistivel implements Jsonable {
    
    public final static Long ATIVO = new Long("1");
    public final static Long INATIVO = new Long("0");

    @Column(name="ch_ativo")
    private Long chAtivo;

    @Column(length=10)
    private String descricao;

    // Getters & Setters
}
Criando a critéria selecionando apenas os Atributos da Classe Main (O ideal é que este codigo seja separado em métodos bunitinhos p/ que fique bem definido quem é responsável pelo que, mas aqui, p/ fins de exemplo vou colocar tudo junto)
Class tClass = SegModulo.class;

// Listando todos os atributos da classe main
Map<String, String> atributosClasseMain = new HashMap<String, String>();
atributosClasseMain.put("main.id", "id");
Field[] fields = this.tClass.getDeclaredFields();
for (Field field : fields) {
   if(!field.getType().getSuperclass().equals(Persistivel.class) &&   // Filtrando apenas atributos que não são Classes do projeto 
     (field.getModifiers() == 2)){                                    // Filtrando apenas atributos private
            atributosClasseMain.put("main." + field.getName(), field.getName());
    }
}

// Criando a ProjectionList
ProjectionList projectionList = Projections.projectionList();
Set setAtributosClasseMain = atributosClasseMain.entrySet();
Iterator iteratorSetAtributosClasseMain = setAtributosClasseMain.iterator();
while(iteratorSetAtributosClasseMain.hasNext()){
   Entry atributoFinal = (Entry)iteratorSetAtributosClasseMain.next();
   projectionList.add(Projections.property(atributoFinal.getKey().toString()).as(atributoFinal.getValue().toString()));
}

Criteria criteria = session.createCriteria(this.tClass, "main")
                                     .createAlias("main.tabAtivo", "main_tabAtivo")
                                     .add(Restrictions.eq("main_tabAtivo.chAtivo", TabAtivo.ATIVO))
                                     .criteria.setProjection( projectionList )
                                     .setResultTransformer(new AliasToBeanResultTransformer(this.tClass));

Pronto, dessa forma evita que venham todas as colunas de SegModulo e TabAtivo no SELECT gerado pela Criteria.

Espero que seja útil para alguem.

:wink:

Criado 29 de agosto de 2011
Ultima resposta 28 de out. de 2011
Respostas 12
Participantes 5