2013-05-15 1 views
6

내 기준에 GROUP BY을 사용하려고합니다.최대 절전 기준 GROUP BY 및 RETURN ENTITY리스트 사용

SELECT b FROM Book b GROUP BY volumeCode; 

것은 내가 코드를 다음과 같습니다 :

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    List<Book> result = c.list(); 

그러나이 기준은 volumeCode의 (문자열의 목록)를 반환 나는이 작업을 수행해야합니다. Book의 목록을 가져와야합니다. 그래서 저는 트랜스포머를 사용하려고했습니다 :

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    c.setResultTransformer(Transformers.aliasToBean(Book.class)); 
    List<Book> result = c.list(); 

이 코드는 null 값 목록을 반환합니다. 기준으로 할 수 있습니까?

답변

5

우선, 프로젝트에서 검색된 데이터의 양을 필터링합니다. 추가 데이터가 필요하면 해당 속성을 프로젝션에도 추가해야합니다.

예 :

자, 변압기는 "콩에 별칭은"그것은 당신의 자바 빈 "Book.java"의 속성 별칭 일치하지 말하는 않습니다
c.setProjection(Projections.projectionList() 
    .add(Projections.property("id").as("id")) 
    .add(Projections.property("descripction").as("description")) 
    .add(Projections.groupProperty("volumeCode").as("volumeCode"))); 

.

편집 : 투사 하나 개 이상의 속성이있는 경우 변압기없이

, 결과는 다음과 같이 나온다 :

for(Object[] item:criteria.list()){ 
    System.out.println((String)item[0]); //ID 
    System.out.println((String)item[1]); //Description 
    System.out.println((String)item[2]); //Volume code 
} 

그게 전부가 왜 변압기에 대해, 캐스트 예외를 얻고 있었다, 모든 별명을 Java bean의 특성 이름과 일! 시키십시오.

+0

안녕 Ziul, thx 답장을 보내 주셔서 감사합니다. 당신의 충고로 객체 목록을 얻지 만 목록에서 객체로 캐스트하려고하면 Java가 예외를 throw합니다. –

+0

Ehm, 변압기가있는 행을 삭제합니다. O : -) ...이 행을 다시 추가 한 후에도 null 객체의 List를 얻습니다. –

+0

게시물을 편집 해 주셔서 감사합니다. 나는 단지 하나의 물건을 얻고 싶지는 않지만 전체 물건을 얻고 싶다. 나는'SELECT b FROM Book b GROUP BY volumeCode'를 호출 한 후에 같은 결과를 얻을 필요가있다. 결과는 List

2

나는 당신이 사용할 수있는 생각 : criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

+0

생각하십니까? 왜? 방법? – rayryeng

+1

@rayryeng 'SELECT p FROM person p GROUP BY personId'를 기준으로 사용하는 것과 같은 문제가 발생하지만 setProjection을 사용하면'select distint (personId) from person'을 선택하고 personId wheres 목록을 반환합니다. 전체 person 객체가 필요하고'List list = session.createCriteria ("Person", "p") .setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY);'사람 객체 목록을 반환합니다. 왜 그리고 이것이 어떻게 도움이 될지에 관해서는 [여기] (http://stackoverflow.com/questions/10961048/setresulttransformer-in-criteria) – Mazrul

+0

귀하의 게시물에 추가하십시오. 왜 이것이 처음에 당신을 도왔는지 알 수 없었습니다. – rayryeng

3

cz_Nesh합니다. 첫 대답에 대해 사과드립니다. 나는 Hibernate API를 읽고 그것을 발견하는 Hibernate 소스 코드를 읽는다. 이 코드를

session.createCriteria(EmpUserImpl.class).list(); 

을 사용하는 경우 이 목록 EmpUserImpl를 반환합니다. 이 코드

 criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
     List list = criteria.list(); 

이 목록을 반환을 사용하는 경우 왜 , EmpUserImpl를 나열되지 않는 이유는 무엇입니까? 기준의 상위 클래스 인 CriteriaSpecification을 볼 수 있습니다.

public interface CriteriaSpecification { 

/** 
* The alias that refers to the "root" entity of the criteria query. 
*/ 
public static final String ROOT_ALIAS = "this"; 

/** 
* Each row of results is a <tt>Map</tt> from alias to entity instance 
*/ 
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE; 

/** 
* Each row of results is an instance of the root entity 
*/ 
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE; 

/** 
* Each row of results is a distinct instance of the root entity 
*/ 
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE; 

/** 
* This result transformer is selected implicitly by calling <tt>setProjection()</tt> 
*/ 
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE; 

/** 
* Specifies joining to an entity based on an inner join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#INNER_JOIN} 
*/ 
@Deprecated 
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a full join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#FULL_JOIN} 
*/ 
@Deprecated 
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a left outer join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN} 
*/ 
@Deprecated 
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue(); 

은}

당신은 공공 정적 최종의 ResultTransformer 투영을 볼 수 있습니까? 이 결과 변환기가 setProjection()을 호출하여 암시 적으로 선택되었음을 나타냅니다.은 criteria.setProjection을 사용할 때 의미가 있습니다. ResultTransformer가 "ROOT_ENTITY"에서 "PROJECTION"로 변경되기 때문에 EmpUserImpl을 나열하지 않습니다. 같은 이름을 선택, oid ..). List EmpUserImpl을 반환하려면 Projections.property ("name"). as ("name")을 설정해야합니다. (name just set name이 필요한 경우). 이것은 내 코드입니다.

 Criteria criteria = session.createCriteria(EmpUserImpl.class); 
    criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
    criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class)); 
    List<EmpUserImpl> list = criteria.list(); 
    for (EmpUserImpl empUserImpl : list) { 
     System.out.println(empUserImpl.getName()); 
    } 

이 가능합니다. 나는 그것이 당신을 도울 수 있기를 바랍니다.