답변:
다음은 우리가 사용하는 hql의 일부입니다. (신분 보호를 위해 이름이 변경되었습니다.)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
distinct
HQL의 distinct
키워드가 SQL 의 키워드에 직접 매핑되지 않는다는 점은 주목할 가치가 있습니다.
distinct
HQL 에서 키워드 를 사용하면 Hibernate는 distinct
SQL 키워드를 사용하지만 어떤 상황에서는 결과 변환기를 사용하여 별개의 결과를 생성합니다. 예를 들어 다음과 같은 외부 조인을 사용하는 경우 :
select distinct o from Order o left join fetch o.lineItems
이 경우 SQL 수준에서 중복을 필터링하는 것은 불가능하므로 Hibernate는 SQL 쿼리가 수행 ResultTransformer
된 후 중복을 필터링하기 위해 a 를 사용합니다 .
다음에 이렇게 해주세요
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
Criteria.DISTINCT_ROOT_ENTITY
Hibernate HQL 쿼리와 함께 사용할 수도 있습니다 .
예:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
HQL 쿼리와 결합 된 결과 변환기에 몇 가지 문제가있었습니다. 내가 시도했을 때
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
작동하지 않았습니다. 다음과 같이 수동으로 변환해야했습니다.
final List found = trans.transformList(qry.list());
Criteria API 변환기는 잘 작동했습니다.
내 주요 쿼리는 모델에서 다음과 같이 보입니다.
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
그리고 나는 여전히 "명확한"결과를 얻지 못했습니다. 테이블의 기본 키 조합에 따라 구별되었습니다.
그래서 DaoImpl
나는 한 줄 변경을 추가하고 내가 원하는 "명확한"반환을 얻었습니다. 예를 들어 00을 네 번 보는 대신 한 번만 보는 것입니다. 다음에 추가 한 코드는 다음과 같습니다 DaoImpl
.
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
도움이 되었기를 바랍니다. 다시 한번 말하지만, 이것은 프로젝트의 서비스, dao 및 모델 유형을 구현하는 코딩 관행을 따르는 경우에만 작동 할 수 있습니다.
CUSTOMER_INFORMATION 테이블에 매핑 된 고객 엔터티가 있고 고유 한 고객 이름의 목록을 가져 오려고한다고 가정합니다. 아래 스 니펫을 사용하여 동일하게 얻을 수 있습니다.
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
도움이되기를 바랍니다. 그래서 여기서는 별개의 키워드를 사용하는 대신 그룹 별을 사용합니다.
또한 이전에는 여러 열에 적용 할 때 고유 한 키워드를 사용하는 것이 어려웠습니다. 예를 들어, 나는 구별되는 firstName, lastName의 목록을 얻고 싶습니다. 이 경우에는 distinct를 사용하는 데 어려움이있었습니다.
Hibernate Query Language가 Distinct 필드를 사용하는 데 대한 답을 얻었습니다. * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *를 사용할 수 있습니다. SQL 쿼리 를 사용하면 String List를 반환합니다. 엔티티 클래스별로 반환 값을 사용할 수 없습니다. 따라서 이러한 유형의 문제를 해결하는 답은 SQL 과 함께 HQL 을 사용하는 것 입니다.
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
에서 SQL의 쿼리 문은 목록으로 DISTINCT ROUTE_ID 입력을 얻었다. 그리고 IN 쿼리는 IN (목록)과 구별되는 TO_CITY를 필터링합니다.
반환 유형은 Entity Bean 유형입니다. 따라서 AutoComplement 와 같은 AJAX에서 할 수 있습니다 .
모두 괜찮을 수 있습니다
이와 같이 기준 작성기에서 고유 한 키워드를 사용할 수 있습니다.
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
그리고 모델 클래스에 필드 생성자를 만듭니다.