我最近深入研究了Hibernate并找到了两种使用HQL进行内部连接查询的方法,但我不知道它们之间的区别以及使用哪种方式
我们假设我们有两个表:
Table user
+-------+-----------+-----------+
|userId |userName | userLevel |
+-------+-----------+-----------+
|1001 |James | 0 |
+-------+-----------+-----------+
|1002 |Tom | 2 |
+-------+-----------+-----------+
Table order
+----------+-----------+-----------+----------+
|orderId |userId |productId |fee |
+----------+-----------+-----------+----------+
|1001 |1002 |1003 | 5 |
+----------+-----------+-----------+----------+
|1002 |1002 |1005 | 50 |
+----------+-----------+-----------+----------+
|1003 |1001 |1010 | 30 |
+----------+-----------+-----------+----------+
用户Tom可以在order
表中拥有多个订单记录。这里有一个要求,我们想要找到汤姆的一些订单信息,如果它是原始的sql
,我们可以这样做:
select user.userId, user.userName, order.orderId, order.fee from user join order where user.userId=order.userId and user.userId=1002;
但是在进入休眠状态时,我找到了两种可以实现这一目标的方法:
使用one-to-many
映射连接用户和订单之间的关系,并在orderEntities<Set>
定义中生成userEntity
,然后进行如下的HQL查询:
FROM UserEntity as U INNER JOIN U.orderEntities as O WHERE U.userId=1002;
或者
省略one-to-many
定义,只需进行如下的HQL查询:
FROM UserEntity U, OrderEntity O WHERE U.userId = O.userId AND U.userId=1002;
这两种查询方式之间的区别是什么?我应该使用哪一个?
答案 0 :(得分:0)
两者都错了,顺便说一下,SQL查询也是错误的。
第一个有一个无用的内连接。连接的唯一效果是,如果用户没有任何订单,它将导致查询不返回任何内容。如果目标是按ID检索用户,然后访问其订单,那么您甚至不应该使用查询:
UserEntity u = em.find(UserEntity.class, 1002);
Set<OrderEntity> orders = u.getOrderEntities();
然而,这将执行两个查询:一个用于加载用户,另一个用于加载订单(如果您实际上对它们执行某些操作(例如迭代它们,获取集合的大小或其他)
如果目标是在单个查询中加载用户及其订单,则查询应为
select distinct u from UserEntity u
left join fetch u.orderEntities
where u.id = 1002
请注意左联接的使用情况,以及 fetch 的使用情况。
第二个是错误的,因为它使用O.userId
,它不应该存在。如果订单实体需要知道其用户,那么您应该拥有从订单到用户的ManyToOne关联。永远不会是持有另一个实体ID的字段。