【问题标题】:Hibernate polymorphic queryHibernate 多态查询
【发布时间】:2010-11-02 08:35:13
【问题描述】:

我有两个类,Person 和 Company,派生自另一个类 Contact。它们在两个表(Person 和 Company)中以多态形式表示。简化的类如下所示:

public abstract class Contact {

  Integer id;

  public abstract String getDisplayName();

}

public class Person extends Contact {

  String firstName;
  String lastName;

  public String getDisplayName() {
    return firstName + " " + lastName;
  }

}

public class Company extends Contact {

  String name;

  public String getDisplayName() {
    return name;
  }

}

问题是我需要进行查询,以查找具有包含特定字符串的 displayName 的所有联系人。我无法使用 displayName 进行查询,因为它不是任一表的一部分。关于如何进行此查询的任何想法?

【问题讨论】:

    标签: java hibernate hql polymorphism


    【解决方案1】:

    因为你在 Java 类中做连接,Hibernate 无法真正帮助你,抱歉。它根本看不到你在这个方法中在做什么,因为它实际上与持久性无关。

    解决方案取决于您如何映射这些类的继承:

    如果是按层次结构的表,则可以使用以下方法:为条件查询编写 SQL where 子句,然后使用 case 语句:

    s.createCriteria(Contact.class)
     .add(Restrictions.sqlRestriction("? = case when type='Person' then firstName || ' '|| lastName else name end"))
     .list();
    

    如果它是每个具体子类的表,那么你最好编写两个查询(因为这是 Hibernate 无论如何都会做的)。

    【讨论】:

    • 我将它作为每个具体类的表格。也许最快的解决方案是编写两个查询并在 java 端组合它们。
    【解决方案2】:

    您可以在 Contact 表中创建一个包含相应 displayName 的新列,您可以通过 Hibernate Interceptor 填充该列,因此它始终会自动包含正确的字符串。

    另一种方法是有两个查询,一个用于Person,一个用于Company 表,每个都包含各自的搜索逻辑。您可能必须使用本机查询来通过 LIKE 查询来查找连接的字符串(不过,我不是 HQL 专家,这很有可能)。

    如果您有大型表,则应该考虑全文索引,因为LIKE '%...%' 查询需要全表扫描,除非您的数据库支持全文索引。

    【讨论】:

      【解决方案3】:

      如果您将 displayName 更改为映射属性(在 Company 中设置为 name 列,在 Person 中设置为 first||' '||last 等公式),则可以查询 Contract,Hibernate 将同时运行两个查询现在有一个 displayName。您将返回一个包含两个列表的列表,一个包含公司,一个包含人员,因此您必须将它们重新合并在一起。我认为您需要通过 Contract 的完整包名称查询或设置一个 typedef 来告诉 Hibernate。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多