Como selecionar os valores de determinada coluna do Banco com Criteria?
Consulta com Criteria
12 Respostas
quando vc da um
objeto.list()
ele lhe traz tudo, ai basta vc especificar qual “coluna” voce quer pegar. Exemplo:
objeto.getPropriedade();
abraços!
geralmente o Criteria popula um objeto todo, vc está usando uma entidade mapeada?
Sim, estou usando uma entidade mapeada!
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??
Na anotação @Column vc não precisa inserir o nome respectivo da coluna no banco?
@Column(name="nome_coluna")
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!
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);
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?
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
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.
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. 
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
}
@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
}
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: