Hibernate - 有没有办法加入 2 列反对 1?

Posted

技术标签:

【中文标题】Hibernate - 有没有办法加入 2 列反对 1?【英文标题】:Hibernate - Is there a way to join 2 columns against 1? 【发布时间】:2015-11-07 20:48:36 【问题描述】:

我正在使用 Spring 和 Hibernate 开发 webapp。

表 1:基表

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| Id         | bigint(20)   | NO   | PRI |         | auto_increment |
| Serial1    | varchar(255) | YES  |     | NULL    |                |
| Serial2    | varchar(255) | YES  |     | NULL    |                |
| ModelNum   | varchar(255) | YES  |     | NULL    |                |
| ...        | ....         | ..   | 0   |         |                |
+------------+--------------+------+-----+---------+----------------+ 

表2:明细表

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| Id1        | varchar(20)  | NO   | PRI |         |                |
| Id2        | varchar(20)  | NO   | PRI |         |                |
| Id3        | varchar(20)  | NO   | PRI |         |                |
| Serial     | varchar(255) | YES  |     | NULL    |                |
| ...        | ....         | ..   | 0   |         |                |
+------------+--------------+------+-----+---------+----------------+

我需要根据连续剧加入表格。 Table2 中的Serial 可能包含来自Serial1Serial2 的值来自Table1,因此它应该像OR 运算符一样进行比较。我将 hbm.xml 用于表格。没有注释映射。我加入了如下表格:

<one-to-one name="notes"
    class="Notes" entity-name="Notes">
</one-to-one>

我以前使用过这个查询:

SELECT A.* FROM Table2 As a INNER JOIN Table1 As b 
ON (a.Serial = b.Serial1 or a.Serial = b.Serial2);

我浏览了这个http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/associations.html,但只使用了 1 个键列。

在这种情况下如何使用 HBM.XML 加入?有可能吗?

【问题讨论】:

示例:T1.Serial1 包含 A,T1.Serial2 包含 B Table2 有两行,一行用于 Serial A,一行用于 Serial B?您的预期结果是什么?您可能希望两次加入同一个表并为您的结果设置别名,但我可能错了...Select * from table1 T1 LEFT JOIN table2 T2a on T1.Serial1 = T2a.Serial LEFT JOIN table2 T2b on T1.Serial = T2b.Serial这会将表 2 合并到表 1 中作为一行。使用 OR,您将获得每个 table1 ID 的多行...这可能是您想要的...因此需要看到预期的结果。 它应该选择两行。 @xQbert :我已经添加了我正在使用的查询。我想用用于 Spring/Hibernate 的 Java 代码替换 Query 啊,与其说是一个 SQL 问题,不如说是一个 spring/hibernate 陷阱。 是的,没错。我不清楚。现在我改变了它。 【参考方案1】:

解决方案 1

Table1 上创建一个数据库视图,它公开引用Table2 的外键。从您发布的查询中投影外键,无论如何您都将用于视图。然后将您的实体映射到视图。

解决方案 2

使用join formula:

例如,在映射到Table1 的实体中定义与映射到Table2 的实体的多对一关联(似乎是您的用例):

@ManyToOne
@JoinColumnsOrFormulas(
      @JoinColumnOrFormula(formula=@JoinFormula(value="(SELECT t2.serial FROM Table2 t2 WHERE serial1 = t2.serial OR serial2 = t2.serial)", referencedColumnName="serial"))
    )
private Entity2 entity2;

但是,暂时在 Hibernate 中加入公式似乎非常脆弱(我设法使这项工作仅适用于多对一关联,我必须使 Entity2 实现 Serializable;否则它没有工作并抛出了一些奇怪的NullPointer-ClassCastExceptions)。

【讨论】:

虽然我没有使用注解并且所有的映射都是基于 xml 的,但这似乎是一个可行的选择。感谢您的回答。【参考方案2】:

您需要为此目的使用本机查询

String sql = "SELECT A.* FROM Table2 As a INNER JOIN Table1 As b "
           + " ON (a.Serial = b.Serial1 or a.Serial = b.Serial2);";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Table2.class);
List<Table2> tableContent  = query.list();

【讨论】:

我目前正在使用相同的代码。只是我想用对象替换 Query 。有没有办法使用 hbm.xml 加入 2 列 vs 1 列?

以上是关于Hibernate - 有没有办法加入 2 列反对 1?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate - 加入策略选择了太多列

hibernate.jpa.criteria.BasicPathUsageException:无法加入基本类型的属性

加入反对意见:性能问题

hibernate y映射失败track is not mapped的解决办法

休眠:加入带有额外列的表,从一侧删除子项

记录使用Hibernate查询bean中字段和数据库列类型不匹配问题