这两种查询方式在hibernate中的区别是什么?

时间:2015-05-25 11:34:14

标签: java mysql hibernate

我最近深入研究了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;

但是在进入休眠状态时,我找到了两种可以实现这一目标的方法:

  1. 使用one-to-many映射连接用户和订单之间的关系,并在orderEntities<Set>定义中生成userEntity,然后进行如下的HQL查询:

    FROM UserEntity as U INNER JOIN U.orderEntities as O WHERE U.userId=1002;
    
  2. 或者

    1. 省略one-to-many定义,只需进行如下的HQL查询:

      FROM UserEntity U, OrderEntity O WHERE U.userId = O.userId AND U.userId=1002;
      
    2. 这两种查询方式之间的区别是什么?我应该使用哪一个?

1 个答案:

答案 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的字段。