0

我正在使用 Hibernate 3.6
User 是一个实体类
Contact 是一个实体类
User 有一个 Set<Contact>
关系是单向的,并且映射为一对多。
我已经尝试了以下延迟加载和获取组合。这是我的理解和实际结果的列表

使用 session.get(User.class, <some userId>) 或 session.load(User.class, <some userId>)

  lazy      fetch       result

* true      join        ignores lazy loading
*                       1 select for retrieving the User and his contacts with a left outer join
*           select      1 select for a User record
*                       1 select for all contacts of the user
*           subselect   1 select for a User record
*                       1 select for all contacts of the user
* false     join        1 select for retrieving the User and his contacts with a left outer join
*           select      1 select for a User record
*                       1 select for all contacts of the user
*           subselect   1 select for a User record
*                       1 select for all contacts of the user

使用 session.createQuery(来自用户)

   lazy     fetch           result

 * true     join            1 select for all User records
 *                          1 select for each User record to retrieve their contacts
 *                          respect lazy loading
 *                          probable n + 1
 *          select          1 select for all User records
 *                          1 select for each User record to retrieve their contacts
 *                          probable n + 1
 *          subselect       1 select for all User records
 *                          1 sub-select to retrieve all contact records in one go
 * false    join            1 select for all User records
 *                          1 select for each User record to retrieve their contacts
 *                          probable n + 1      
 *          select          1 select for all User records
 *                          1 select for each User record to retrieve their contacts
 *                          probable n + 1
 *          subselect       1 select for all User records
 *                          1 sub-select to retrieve all contact records in one go

以下是我的几个问题:

  1. 我的理解正确吗?
  2. 使用 session.get() 当 lazy=true, fetch=subselect 为什么 Hibernate 不执行 subselect ?我想这是因为它绝对没有必要。我对么 ?
  3. 使用 session.get() when lazy=false, fetch=subselect 为什么 Hibernate 不执行 subselect ?它应该在这里执行一个,但它没有。我想知道为什么 ?
  4. 使用 session.createQuery() when lazy=true, fetch=join 为什么 Hibernate 延迟加载?session.get() 之前没有这样做
  5. 使用 session.createQuery() when lazy=false, fetch=join 为什么 Hibernate 不使用 join ?

提前致谢

4

1 回答 1

0

好的,经过大量挖掘,这就是我可以得出的结论。只是想和大家分享我的战利品。如果有人觉得他们可以添加更多内容,欢迎您。让我从一个示例数据集开始。

用户表
--------------------------------------------------
USER_ID 用户名
--------------------------------------------------
1 用户一
2 用户二
3 用户三

联系表
-------------------------------------------------- -------------------------------------------------- ---------------
CONTACTID TITLE FIRSTNAME LASTNAME CITY COUNTRY EMAIL USER_ID
-------------------------------------------------- -------------------------------------------------- ---------------
1 Clark Kent 先生 纽约 美国 man-of-steel@anywhere.earth 1
2 Hank Ketcham 先生 美国 dennis-mitchell@somewhere.us 2
3 Tony Stark Malibu 先生 美国 iron-man@anywhere.earth 2
4 Bruce Wayne Gotham 先生 美国 dark-knight@gotham.us 2

Q2。使用 session.get() 当 lazy=true, fetch=subselect 为什么 Hibernate 不执行 subselect ?我想这是因为它绝对没有必要。我对么 ?

A2。是的,这里绝对不需要子选择。这是子选择的样子

选择   
    u.USER_ID AS USER1_1_,   
    u.USERNAME AS USERNAME1_,   
    c.USER_ID AS USER15_1_1_,   
    c.CONTACTID AS CONTACTID1_,   
    c.CONTACTID AS CONTACTID0_0_,   
    c.TITLE AS TITLE0_0_,   
    c.FIRSTNAME AS FIRSTNAME0_0_,   
    c.LASTNAME AS LASTNAME0_0_,   
    c.CITY AS CITY0_0_,   
    c.COUNTRY AS COUNTRY0_0_,   
    c.EMAIL AS EMAIL0_0_,   
    从   
        用户u,联系人c   
    在哪里   
        u.USER_ID = 2  
    和   
        c.USER_ID IN    
        (   
            SELECT USER_ID FROM user WHERE USER_ID = u.USER_ID   
        )  

我看不出在这里执行子选择比当前简单地为联系人记录执行单独选择的策略有任何好处。事实上,子选择可能是不必要的性能消耗。

Q3。使用 session.get() when lazy=false, fetch=subselect 为什么 Hibernate 不执行 subselect ?它应该在这里执行一个,但它没有。我想知道为什么 ?

A3。好的。同样,这里是子选择的样子(与上面带有其他 ID 的完全相似)

选择   
    u.USER_ID AS USER1_1_,   
    u.USERNAME AS USERNAME1_,   
    c.USER_ID AS USER15_1_1_,   
    c.CONTACTID AS CONTACTID1_,   
    c.CONTACTID AS CONTACTID0_0_,   
    c.TITLE AS TITLE0_0_,   
    c.FIRSTNAME AS FIRSTNAME0_0_,   
    c.LASTNAME AS LASTNAME0_0_,   
    c.CITY AS CITY0_0_,   
    c.COUNTRY AS COUNTRY0_0_,   
    c.EMAIL AS EMAIL0_0_,   
    从   
        用户u,联系人c   
    在哪里   
        u.USER_ID = 3  
    和   
        c.USER_ID IN    
        (   
            SELECT USER_ID FROM user WHERE USER_ID = u.USER_ID   
        )  

如您所见,这不会产生任何记录,因为 USER_ID=3 没有任何联系人记录。这违背了为用户记录执行 session.get() 的全部目的,其中 get() 将返回 null,尽管表中有有效的用户记录。同样,单独选择联系人记录是唯一的出路。

Q4。使用 session.createQuery() when lazy=true, fetch=join 为什么 Hibernate 延迟加载?session.get() 之前没有这样做

Q5。使用 session.createQuery() when lazy=false, fetch=join 为什么 Hibernate 不使用 join ?

答。我目前的理解是,这可能仅仅是因为 Hibernate 不希望最终触发一个连接,该连接选择一个巨大的数据集(包括所有用户记录及其联系人记录)并在内存中加载一个巨大的集合。

于 2013-04-30T10:02:04.907 回答