Hibernate Criteria查询多个类(或通过子类列表限制)

时间:2015-01-07 02:45:08

标签: java hibernate hibernate-criteria

假设我有一些类,如下所示:

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 + { {1}}?

我的问题:我怎样才能使用Hibernate Criteria?请不要HQL。

注意:我不知道我是否应该将此问题视为"查询多个班级" (其中所有字段都具有与我查询的字段相同的字段),或者如果我将其视为"通过子类列表限制查询"。

修改:如果我可以创建界面OpC,然后创建课程TheOnesIWantOpA2OpB1和{{1}实现这个接口,这将产生我想要的结果:OpB3但是我不能这样做,因为我只知道我想在运行时查询的类。上面的类层次结构只是一个例子。

1 个答案:

答案 0 :(得分:7)

通常,Hibernate对加入无关实体的支持非常有限。由"无关"我的意思是没有相互引用的实体。 Critera API根本不支持它,HSQL只能交叉连接。不要误解我,底层的Criteria / HQL实现能够加入不相关的实体,但API不会暴露这个功能。 (您可以在相关实体上执行各种连接(内部,左侧,右侧,完整)。) 在不相关的实体上进行内/左/右/完全连接的唯一方法是本机sql。 但是,如果不相关的实体具有共同的父级,则可以使用名为"隐式多态的"的hibernate功能:选择父级,将返回父级及其所有子类。然后,您可以将结果限制为子类列表。
所以试试这个:

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();

修改
以下是如何查询父类中不存在的属性的示例: 在这个例子中,属性&#34; f&#34;和&#34;价值&#34;不存在于Operation类中,它们只存在于OpA2 abd OpC类中。

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();