我不确定如何描述这个问题,所以我认为一个例子是提出问题的最佳方式:
我有两个表与manyToMany关系:
DriversLicence< - > LicenceClass
LicenceClass是“Car”,“Motorbike”和“Medium Rigid”之类的东西。
使用Hibernate Criteria,我怎样才能找到同时拥有“Car”和“Motorbike”LicenceClasses的所有许可证?
更新12/11/2008 我发现使用自定义ResultTransformer可以很容易地实现这一点。但问题是结果转换器仅在查询返回其结果后才应用,它实际上不会成为SQL的一部分。所以我想我现在的问题是“你能做我最初在SQL中描述的内容吗?是否有Hibernate Criteria模拟?”
答案 0 :(得分:6)
以下是我最终使用HQL实现它的方法:
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();
}
或者使用带有sqlRestriction的Hibernate Criteria:
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是hibernate生成的表的名称,用于支持driversLicence和LicenceClass之间的多对多关系。
答案 1 :(得分: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();
答案 2 :(得分: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=?
希望它有所帮助。
答案 3 :(得分:0)
另一种选择是链接(每个LicenseClass一个连接)。我使用了像这样的标准构建器和谓词
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是Root类的对象,您可以从CriteriaQuery类中获取它。结果谓词是你在寻找什么...
答案 4 :(得分:-1)
'我不认为这会起作用。我想查找所有两者“Car”和“Motorbike”的许可证
用户表达式和(....)代替尼克提供的代码段中的Expression.or(....)