繁体   English   中英

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

[英]Hibernate Criteria to query more than one class (or restrict by a list of subclasses)

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

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。

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

编辑:如果我能创建一个接口TheOnesIWant ,然后进行类OpA2OpB1OpB3OpC实现了这个接口,这将产生我想要的结果: session.createCriteria(TheOnesIWant.class)但我不能这样做,因为我只知道我想在运行时查询的类。 上面的类层次结构只是一个例子。

通常,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();

编辑:
下面是一个如何查询父类中不存在的属性的示例:在此示例中,属性“f”和“value”在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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM