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
可能包含来自Serial1
或Serial2
的值来自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-
和ClassCastException
s)。
【讨论】:
虽然我没有使用注解并且所有的映射都是基于 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.jpa.criteria.BasicPathUsageException:无法加入基本类型的属性