我试图通过Session Get方法了解对象初始化如何为返回的对象起作用。请验证我的理解。执行时,它会检查第一级缓存中具有给定标识符的对象,然后检查第二级缓存(如果已配置),如果未找到,则触发select查询以从数据库中检索数据。 我的问题是,它是否包含为延迟加载配置的select查询中的关联,或者为返回对象中的此类关联设置了空值?
如果是这种情况,那么session.get不会对返回的对象进行完整的初始化,这与在Web上提供的大多数hibernate教程上所写的内容相矛盾。
答案 0 :(得分:2)
Hibernate Session提供了从数据库中获取数据的不同方法。其中两个是 - get()和load()。 get()通过从数据库或从hibernate缓存中获取对象来返回对象。 当我们使用get()来检索不存在的数据时,它会返回null,因为它会在调用数据后立即加载数据。
例如:
在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的引用。
答案 1 :(得分:1)
回答这个问题:
是否包含为延迟加载配置的选择查询中的关联,或者为返回对象中的此类关联设置空值?
1)session.get()
NOT 会启动懒惰的内容。决不。实际上,这是设计的核心思想。否则 - 我们可以在一个SHOT中加载整个数据库(在一个JAVA调用session.get()
中)
2)并且还有不会为空。每个参考或集合将由代理表示。这就是我们如何避免一次性加载强制数据库的方式(所有用一个方法get初始化的东西)。因为每个代理实际上都是一个承诺 - 一旦我们触摸它......它将加载真实数据。
等等。因此,如何获得与配置数据相同的数据是非常安全的方式....
答案 2 :(得分:0)
简单地
调用get()
方法时,它将直接命中数据库,获取结果并返回。如果找不到匹配的字段,它将很乐意返回null。
根据引用的注释 Lazy或Eager ,将返回数据。如果Lazy
,将返回代理而不是null,如果Eager
,将返回完全初始化的对象。
最好监控后端的查询,以便更好地理解。
答案 3 :(得分:0)
1)映射T_CUSTOMER数据库表的客户实体类:
@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)映射T_ADDRESS数据库表的地址实体类:
@Entity
@Table(name= “T_ADDRESS”)
public class Address {
// Fields and Properties
}
请考虑此Customers表:
----------------------------------------------------------------------------
| Cust_id | Cust_firstname | Cust_lastname | Cust_email | Cust_mobile |
----------------------------------------------------------------------------
| 101 | XXXX | YYYYY |xxx@xyz.com | 8282263131 |
----------------------------------------------------------------------------
Above customers表有一条记录,cust_id为101。
现在考虑一下这个地址表:
----------------------------------------------------------------------------
| 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表及其关联表相关的所有数据,在这种情况下为T_ADDRESS表。
2)。我的情况懒洋洋地加载:
SELECT * FROM T_CUSTOMER WHERE cust_id=101;
因此,它只获取对应于T_CUSTOMER表的数据,并使用Proxy作为T_ADDRESS表,如上所述@RadimKöhler。只有在您调用时才会从T_ADDRESS TABLE中获取数据:
cust.getAddresses();