Hibernate标准API-如何按收集尺寸订购?
-
12-09-2019 - |
题
假设我有类用户和用户组。有一个可选的1次小组到用户关联,并且关联是从两边绘制的(通过属性的属性“成员”,这是一个标签,用户端通过属性“组”)。
使用标准API,我如何查询所有小组,按小组成员计数排序?
(编辑)当我问这个分页时,我应该指出的是在SQL中执行分页,因此如果可能的话,也应在SQL中执行订购。
解决方案
另一个选项是使用@formula注释,基本上是创建嵌套选择的等效物,以便您可以计数。
在您的数据库对象属性 /成员(您应该创建的)上,将注释添加到Getter上:
@formula(“(从表中select count(table_name.id)where ...)”)public long getNewProperty {return newproperty; }
然后直接定位会员以持有您的计数值...
注意:请注意,在公式注释中指定SQL时,您必须在引用当前对象表(this)作为Hibernate处理此本身时直接指定字段名。因此,在您的Where子句中,在引用我怀疑是用户组的当前对象表时,只需使用ID或任何内容。
我必须有一个新物业的设置者,以使Hibernate工作并防止编译器抱怨。
可能还有其他使用@formula的聪明方法,但是我很陌生,而且似乎没有太多关于该主题的文档。
如果您以前从未使用过嵌套选择,那么首先在SQL中重新创建可能是一个想法 - 这对我有帮助。
希望这可以帮助
其他提示
默认情况下使用Citeria API不可能,但您可以扩展org.hibernate.criterion.order类。本文涉及如何扩展该类: http://blog.tremend.ro/2008/06/10/how-to-to--cord-by-a-custom-sql-sql-formulaexpression-when-- using-hibernate-criteria-api
我的征服是:
public class SizeOrder extends Order {
protected String propertyName;
protected boolean ascending;
protected SizeOrder(String propertyName, boolean ascending) {
super(propertyName, ascending);
this.propertyName = propertyName;
this.ascending = ascending;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String role = criteriaQuery.getEntityName(criteria, propertyName) + '.' + criteriaQuery.getPropertyName(propertyName);
QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory().getCollectionPersister(role);
String[] fk = cp.getKeyColumnNames();
String[] pk = ((Loadable) cp.getOwnerEntityPersister())
.getIdentifierColumnNames();
return " (select count(*) from " + cp.getTableName() + " where "
+ new ConditionFragment()
.setTableAlias(
criteriaQuery.getSQLAlias(criteria, propertyName)
).setCondition(pk, fk)
.toFragmentString() + ") "
+ (ascending ? "asc" : "desc");
}
public static SizeOrder asc(String propertyName) {
return new SizeOrder(propertyName, true);
}
public static SizeOrder desc(String propertyName) {
return new SizeOrder(propertyName, false);
}
}
TOSQLSTRING方法基于org.hibernate.criterion.sizeexpression类。 (资源: http://javasourcecode.org/html/open-source/hibernate/hibernate-3.6.0.final/org/hibernate/criterion/criterion/sizeexpression.java.java.html)
示例用法:
hibernateSession.createCriteria(UserGroup.class).addOrder( SizeOrder.asc("members") ).list();
这将列出按成员升序订购的用户组,其中“成员”是用户集团实体中的用户集合。
您可能可以通过在实体上定义“派生属性”来这样做,这将是一个只读的属性,可返回该实体内部集合的大小。定义派生属性的最简单方法是 在这里记录:
更新,插入(可选 - 默认为true):指定映射的列应包含在SQL Update和/或插入语句中。将两者都设置为Fals,允许纯“派生”属性,其值是从某些其他属性初始化为同一列或触发器或其他应用程序的属性初始化的属性。
定义属性后,您应该能够将属性名称用作标准API中的订单条款,就像其他任何属性一样。不过,我自己没有尝试过。
如果有效,它可能会作为内存形式进行,因为它无法将其映射到SQL。如果这是一个问题,那么上面的相同链接记录了如何使用自定义SQL片段实现派生属性:
强大的功能是派生属性。根据定义,这些属性是只读的。属性值是在加载时间计算的。您将计算声明为SQL表达式。然后,这将转化为SQL查询中加载一个实例的Select子句子查询: