簡體   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