我最近深入研究了 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
中拥有多条订单记录 table 。这里有一个需求,我们想找到Tom单独的一些订单信息以及他的名字,如果是原始的sql
我们可以这样做:
select user.userId, user.userName, order.orderId, order.fee from user join order where user.userId=order.userId and user.userId=1002;
但是进入 hibernate 状态后,我发现了两种可以实现此目的的方法:
使用
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;
这两种查询方式有什么不同?我应该使用哪一个?
最佳答案
两者都是错误的,顺便说一句,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
注意左连接的用法以及获取的用法。
第二个是错误的,因为它使用了 O.userId
,它不应该存在。如果订单实体需要知道其用户,那么您应该有一个从订单到用户的多对一关联。绝不是保存另一个实体的 ID 的字段。
关于java - hibernate中这两种查询方式有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30437438/