Hibernate Criteria 查询多个 class (或受子 class 列表限制)
Hibernate Criteria to query more than one class (or restrict by a list of subclasses)
假设我有一些 classes,像这样:
OpA extends Operation
OpA1 extends OpA
OpA2 extends OpA
OpB extends Operation
OpB1 extends OpB
OpB2 extends OpB
OpB3 extends OpB
OpC extends Operation
Operation
|
/-----------------------------\
/ | \
OpA OpB OpC
/ |
/ |
/------\ /-----------\
/ \ / | \
OpA1 OpA2 OpB1 OpB2 OpB3
如果我想找一些操作,我可以这样做:
session.createCriteria(Operation.class)
.add(...)
.add(...)
.addOrder(...)
.setFirstResult(...)
.setMaxResults(...)
.list();
但是,如果我不想将这些条件应用到类型 Operation.class
的所有操作,而只应用到以下类型的操作,该怎么办:OpA2
+ OpB1
+ OpB3
+ OpC
?
我的问题:如何仅使用 Hibernate Criteria 来做到这一点?没有 HQL,请。
注意:我不知道是否应该将此问题视为 "querying more than one class"(其中所有字段的名称都与我正在查询的字段同名),或者我是否应将其视为 "restricting a query by a list of subclasses".
编辑: 如果我可以创建一个接口 TheOnesIWant
,然后制作 classes OpA2
、OpB1
, OpB3
和 OpC
实现了这个接口,这会产生我想要的结果: session.createCriteria(TheOnesIWant.class)
但是我不能这样做,因为我只知道我想要的 classes在 运行时 查询。上面的 class 层次结构只是一个例子。
一般来说,Hibernate 对加入不相关 实体的支持非常有限。 "unrelated" 我的意思是没有相互引用的实体。 Critera API 完全不支持,HSQL只能做cross join。不要误会我的意思,底层 Criteria/HQL 实现能够加入不相关的实体,但 API 不公开此功能。 (您可以对相关实体进行各种类型的连接(内连接、左连接、右连接、全连接)。)
inner/left/right/full 加入不相关实体的唯一方法是原生 sql。
但是,如果不相关的实体有共同的父实体,您可以使用称为 "implicit polymorphism" 的休眠功能:选择父实体,将 return 父实体及其所有子 class 实体。然后您可以将结果限制为 sub-classes 的列表。
所以试试这个:
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Property.forName("class").eq(OpA2.class)
,Property.forName("class").eq(OpB1.class)
,Property.forName("class").eq(OpB3.class)
,Property.forName("class").eq(OpC.class)))
.list();
编辑:
下面是一个如何查询父 class 中不存在的属性的示例:
在此示例中,属性 "f" 和 "value" 不存在于操作 class 中,它们仅存在于 OpA2 abd OpC classes.
中
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Restrictions.and(Property.forName("class").eq(OpA2.class), Restrictions.eq("f", 1))
, Property.forName("class").eq(OpB1.class)
, Property.forName("class").eq(OpB3.class)
, Restrictions.and(Property.forName("class").eq(OpC.class), Restrictions.eq("value", "b"))))
.list();
假设我有一些 classes,像这样:
OpA extends Operation
OpA1 extends OpA
OpA2 extends OpA
OpB extends Operation
OpB1 extends OpB
OpB2 extends OpB
OpB3 extends OpB
OpC extends Operation
Operation
|
/-----------------------------\
/ | \
OpA OpB OpC
/ |
/ |
/------\ /-----------\
/ \ / | \
OpA1 OpA2 OpB1 OpB2 OpB3
如果我想找一些操作,我可以这样做:
session.createCriteria(Operation.class)
.add(...)
.add(...)
.addOrder(...)
.setFirstResult(...)
.setMaxResults(...)
.list();
但是,如果我不想将这些条件应用到类型 Operation.class
的所有操作,而只应用到以下类型的操作,该怎么办:OpA2
+ OpB1
+ OpB3
+ OpC
?
我的问题:如何仅使用 Hibernate Criteria 来做到这一点?没有 HQL,请。
注意:我不知道是否应该将此问题视为 "querying more than one class"(其中所有字段的名称都与我正在查询的字段同名),或者我是否应将其视为 "restricting a query by a list of subclasses".
编辑: 如果我可以创建一个接口 TheOnesIWant
,然后制作 classes OpA2
、OpB1
, OpB3
和 OpC
实现了这个接口,这会产生我想要的结果: session.createCriteria(TheOnesIWant.class)
但是我不能这样做,因为我只知道我想要的 classes在 运行时 查询。上面的 class 层次结构只是一个例子。
一般来说,Hibernate 对加入不相关 实体的支持非常有限。 "unrelated" 我的意思是没有相互引用的实体。 Critera API 完全不支持,HSQL只能做cross join。不要误会我的意思,底层 Criteria/HQL 实现能够加入不相关的实体,但 API 不公开此功能。 (您可以对相关实体进行各种类型的连接(内连接、左连接、右连接、全连接)。)
inner/left/right/full 加入不相关实体的唯一方法是原生 sql。
但是,如果不相关的实体有共同的父实体,您可以使用称为 "implicit polymorphism" 的休眠功能:选择父实体,将 return 父实体及其所有子 class 实体。然后您可以将结果限制为 sub-classes 的列表。
所以试试这个:
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Property.forName("class").eq(OpA2.class)
,Property.forName("class").eq(OpB1.class)
,Property.forName("class").eq(OpB3.class)
,Property.forName("class").eq(OpC.class)))
.list();
编辑:
下面是一个如何查询父 class 中不存在的属性的示例:
在此示例中,属性 "f" 和 "value" 不存在于操作 class 中,它们仅存在于 OpA2 abd OpC classes.
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Restrictions.and(Property.forName("class").eq(OpA2.class), Restrictions.eq("f", 1))
, Property.forName("class").eq(OpB1.class)
, Property.forName("class").eq(OpB3.class)
, Restrictions.and(Property.forName("class").eq(OpC.class), Restrictions.eq("value", "b"))))
.list();