2008-11-05 8 views
9

나는이 문제를 설명하는 방법을 잘 모르겠어요, 그래서 예를 들어 내 질문 요청하는 가장 좋은 방법이라고 생각 :쿼리 ManyToMany 관계는

:

가 나는 manyToMany 관계 두 테이블이를

DriversLicence < -> LicenceClass

LicenceClass는 "Car", "Motorbike"및 "Medium Rigid"와 같은 것입니다.

Hibernate Criteria를 사용하면 "Car"와 "Motorbike"LicenceClasses가 모두있는 라이센스를 어떻게 찾을 수 있습니까?

업데이트 12/11/2008 사용자 정의 ResultTransformer를 사용하면 쉽게 달성 할 수 있음을 발견했습니다. 그러나 문제는 쿼리가 결과를 반환 한 후에 만 ​​결과 변환기가 적용된다는 것이며 실제로 SQL의 일부가되지 않는다는 것입니다. 그래서 내 질문에 "처음에 SQL에서 설명한 것을 할 수 있습니까? 그리고 Hibernate Criteria 아날로그가 있습니까?"

답변

5

입니다 driversLicence와 LicenceClass 간의 일 대 다 관계.

0

도트 표기법을 사용하여 관계 전체에서 작업 할 수 있습니다. 예를 들어, 다음 DriversLicence.licenceClass 속성과 LicenceClass.type 속성이 가정 : 개인적으로 생각

session.createCriteria(DriversLicence.class) 
    .add(Expression.or(
    Expression.eq("licenceClass.type", "Car"), 
    Expression.eq("licenceClass.type", "Motorbike") 
    ) 
).list(); 

을, 나는 단순히 동적 쿼리 아니기 때문에이 경우에는 기준을 사용하지 않고 대신 사용하십시오 :

session.createQuery("from DriversLicence where licenceClass.type in (:types)") 
    .setParameterList("types", myListOfTypes) 
    .list(); 
+0

나는 이것이 작동하지 않을 것이라고 생각합니다. ** "Car"및 "Motorbike"LicenceClasses를 모두 보유한 모든 라이센스를 찾고 싶습니다. ** ** 아닙니다 **. –

+0

아 ... 좋은 지적이야. 가장 효율적인 것은 아니지만, 당신은 할 수 : DriversLicence의 DL에서 선택 DL은 "자동차"일부 요소 (lt.type) 와 "오토바이를"= LT d.licenceType 참여가 일부 요소를 = (lt.type) 이를 (문자 외) 기준을 사용하도록 변경할 수도 있습니다. – Nick

+0

예, 제가 원한 것입니다. 그러나 기준으로 어떻게합니까? 원한다면 다른 답변을 게시하십시오! –

-1

'나는 이것이 작동하지 않을 것이라고 생각합니다. 나는 모두 "자동차"와 "오토바이" '

사용자 Expression.and (....) 대신 조각에 Expression.or (....) 닉에서 제공하는 모든 라이선스를 찾으려면

+1

아니요 너무 잘못되었습니다. 이 겉으로보기에는 단순한 유스 케이스가 최대 절전 모드에서 가능하지 않다고 생각하기 시작했습니다. 누구나 확인하고 이유를 설명해 주시겠습니까? –

0

비슷한 문제가 있었지만 HQL을 사용하여 수정했습니다. 클래스 "사용자"와 관련이 있으며 "역할"클래스와 관련이있는 "엔터프라이즈"클래스가 있습니다. 특정 사용자와 관련된 모든 기업 나는 다음을 수행합니다.

Select e from Enterprise As e inner join e.Users As u inner join u.Roles As r 
Where u.UserCode=? 

나는 당신이 뭔가를해야한다고 가정합니다;

Select dl from LicenceClass As l inner join l.DriversLicences As dl 
Where 
l.LicenseClass.Name = ? OR 
l.LicenseClass.Name=? OR 
l.LicenseClass.Name=? 

희망이 있습니다. sqlRestriction와

public List<DriversLicence> findDriversLicencesWith(List<LicenceClass> licenceClasses) { 
    String hqlString = "select dl from DriversLicenceImpl dl where 1=1 "; 
    for (int i = 0; i < licenceClasses.size(); i++) { 
     hqlString += " and :licenceClass" + i + " = some elements(dl.licenceClasses)"; 
    } 

    Query query = getSession().createQuery(hqlString); 
    for (int i = 0; i < licenceClasses.size(); i++) { 
     query.setParameter("licenceClass" + i, licenceClasses.get(i)); 
    } 
    return query.list(); 
} 

또는 사용하여 최대 절전 모드 기준 :

for (LicenceClass licenceClass : licenceClasses) {    
    criteria.add(Restrictions.sqlRestriction("? = some(select " + LicenceClass.PRIMARY_KEY + " from " + 
        LICENCE_CLASS_JOIN_TABLE + " where {alias}." + 
        DriversLicence.PRIMARY_KEY + " = " + DriversLicence.PRIMARY_KEY + ")", 
        licenceClass.getId(), Hibernate.LONG)); 
} 

LICENCE_CLASS_JOIN_TABLE 최대 절전 모드가 많은 -을 지원하기 위해 생성하는 테이블의 이름입니다 드디어 HQL을 사용하여 달성 방법은 다음과

0

또 다른 옵션은 체인 조인 (각 LicenseClass 당 하나의 조인)입니다. 나는 루트 클래스의 객체이며 CriteriaQuery 클래스에서 그것을 얻을 수있는이

List<Predicate> predicates = new ArrayList<>(); 
for(Integer lcId : licenceClassIdList) { 
    SetJoin<DriversLicence, LicenceClass> dlClasses = dlRoot.join(DriversLicence_.licenceClasses); 
    predicates.add(builder.equal(dlClasses.get(LicenseClass_.id), lcId)); 
} 
Predicate predicate = builder.and(predicates.toArray(new Predicate[predicates.size()])); 

공지 사항 dlRoot 같은 기준 빌더와 술어를 사용했다.결과 술어는 무엇을 찾고 있습니까 ...