Session.get 方法如何在休眠中工作

How Session.get method works in hibernate

我试图了解对象初始化如何为 Session Get 返回的对象工作 method.Please 验证我的理解。当它执行时,它会在一级缓存中检查具有给定标识符的对象,然后在二级缓存中(如果已配置),如果没有找到则触发 select 查询以从数据库中检索数据。 我的问题是,它是否在 select 查询中包含为延迟加载配置的关联,或者在返回的对象中为此类关联设置了空值?

如果是这种情况,那么 session.get 不会对返回的对象进行完整的初始化,这与网上提供的大多数 hibernate 教程中的内容相矛盾。

简单

get()方法被调用时,它会直接访问数据库,获取结果和return。如果没有找到匹配的字段,它会很乐意 return null.

根据引用的注释,Lazy 或 Eager,数据将被 returned。如果 Lazy,代理将被 returned 而不是 null,如果 Eager,完全初始化的对象将被 returned。

最好在后端监控查询,以便更好地理解。

Hibernate Session 提供了不同的方法从数据库中获取数据。其中两个是 - get() 和 load()。 get() returns 通过从数据库或休眠缓存中获取对象。 当我们使用 get() 检索不存在的数据时,它 returns null,因为它会在调用时尝试加载数据。

  • 当我们想确保数据存在于数据库中时,我们应该使用 get()。

例如:

在 Stock 应用程序中,Stock 和 StockTransactions 应该是“一对多”的关系,当您想保存股票交易时,通常会像下面这样声明。

       Stock stock = (Stock)session.get(Stock.class, new Integer(2));
       StockTransaction stockTransactions = new StockTransaction();
       //set stockTransactions detail
       stockTransactions.setStock(stock);        
       session.save(stockTransactions);

输出:

Hibernate: 
select ... from mkyong.stock stock0_ 
where stock0_.STOCK_ID=?
Hibernate: 
insert into mkyong.stock_transaction (...) 
values (?, ?, ?, ?, ?, ?)

在 session.get() 中,Hibernate 将访问数据库以检索 Stock 对象并将其作为对 StockTransaction 的引用。

回答问题:

Does it include associations in select query which are configured for lazy loading or null value is set for such associations in returned object?

1) session.get() 不会 启动懒惰的东西。绝不。事实上,这就是设计的中心思想。否则 - 我们将能够一次加载整个数据库(在一次 JAVA 调用 session.get() 中)

2) 还有 WILL NOT 为 null。每个引用或集合将由 proxy 表示。这就是我们如何避免一次加载完整的数据库的方法(所有的东西都用一种方法初始化)。因为每个代理实际上都是一个承诺——一旦我们触及它……它就会加载真实数据。

等等。所以 get 是一种非常安全的方式来接收配置的尽可能少的数据....

1) 映射 T_CUSTOMER 数据库的客户实体 class table:

@Entity
@Table(name= “T_CUSTOMER”)
public class Customer {
    @Id
    @Column (name=“cust_id”)
    private Long id;

    @OneToMany(fetch=FetchType.EAGER)
    @JoinColumn (name=“cid”)
    private Set<Address> addresses;
    …
    …
    …
}

2) 地址实体 class 映射 T_ADDRESS 数据库 table:

@Entity
@Table(name= “T_ADDRESS”)
public class Address {
    // Fields and Properties
}

考虑这个客户 table :

----------------------------------------------------------------------------
| Cust_id  | Cust_firstname | Cust_lastname  |  Cust_email  |  Cust_mobile |
----------------------------------------------------------------------------
|   101    |       XXXX     |    YYYYY         |xxx@xyz.com |  8282263131  |
----------------------------------------------------------------------------

以上客户table有一条记录cust_id为101。

现在考虑这个地址 Table :

----------------------------------------------------------------------------
| id       |   street    |    suburb     |   city   |  zipcode |    cid    |
----------------------------------------------------------------------------
|   1      |   streetX   |    AreaY      | cityZ    |  54726   |    101    |
----------------------------------------------------------------------------
|   2      |   streetXA  |    AreaYB     | cityZS   |  60660   |    101    |
----------------------------------------------------------------------------

现在当你调用时:

Customer cust = (Customer)session.get(Customer.class, 101);

然后 Hibernate 将触发一个 SQL 查询 类似于:

1). 如果 EAGER LOADING :

SELECT * FROM T_CUSTOMER cust JOIN T_ADDRESS add ON cust.cust_id=add.cid

即,它将加载与 T_CUSTOMERS table 相关的所有数据及其关联的 tables,即 T_ADDRESS table这种情况。

2). I 例 延迟加载 :

SELECT * FROM T_CUSTOMER WHERE cust_id=101;

所以,它只获取对应于 T_CUSTOMER table 的数据,并使用 Proxy 作为 T_ADDRESS table 的代理,正如@Radim Köhler 所说。仅当您调用 :

时,它才会从 T_ADDRESS TABLE 获取数据
cust.getAddresses();