Java Session.get方法在hibernate中的工作原理
我试图通过会话Get方法了解返回对象的对象初始化工作原理。请验证我的理解。当它执行时,它在第一级缓存中检查具有给定标识符的对象,然后在第二级缓存中检查(如果已配置),如果未找到,则触发select查询以从数据库检索数据。 我的问题是,它是否在select查询中包含为延迟加载配置的关联,或者在返回的对象中为此类关联设置了null值 如果是这种情况,则session.get不会对返回的对象进行完全初始化,这与web上大多数hibernate教程中所写的内容相矛盾。 调用Java Session.get方法在hibernate中的工作原理,java,hibernate,get,Java,Hibernate,Get,我试图通过会话Get方法了解返回对象的对象初始化工作原理。请验证我的理解。当它执行时,它在第一级缓存中检查具有给定标识符的对象,然后在第二级缓存中检查(如果已配置),如果未找到,则触发select查询以从数据库检索数据。 我的问题是,它是否在select查询中包含为延迟加载配置的关联,或者在返回的对象中为此类关联设置了null值 如果是这种情况,则session.get不会对返回的对象进行完全初始化,这与web上大多数hibernate教程中所写的内容相矛盾。 调用get()方法时,它将直接命中
get()
方法时,它将直接命中数据库,获取结果并返回。如果没有找到匹配的字段,它将很乐意返回null。
根据引用上的注释,惰性或急切,将返回数据。如果Lazy
,将返回代理而不是null;如果Eager
,将返回完全初始化的对象
为了更好地理解,最好在后端监视查询。Hibernate会话提供了从数据库获取数据的不同方法。其中两个是–get()和load()。 get()通过从数据库或hibernate缓存获取对象来返回该对象。 当我们使用get()检索不存在的数据时,它返回null,因为它试图在调用数据时立即加载数据
- 当我们想确保数据库中存在数据时,应该使用get()
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的引用。要回答问题: 它是否在select query中包含配置为延迟加载的关联,或者在返回的对象中为此类关联设置了null值 1)
session.get()
将不启动懒惰的东西。从未。事实上,这是设计的中心思想。否则,我们将能够一次加载整个数据库(在对session.get()
的一次JAVA调用中)
2) 而且,也不会为空。每个引用或集合将由代理表示。这就是我们如何避免一次加载compelte DB的方法(所有东西都是用一个方法初始化的)。因为每一个代理事实上都是一个承诺——一旦我们触及它。。。它将加载真实数据
等等。因此,get是一种非常安全的方法,可以接收配置的尽可能少的数据….1)映射T_Customer DB表的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;
…
…
…
}
@Entity
@Table(name= “T_ADDRESS”)
public class Address {
// Fields and Properties
}
考虑这个客户表:
----------------------------------------------------------------------------
| Cust_id | Cust_firstname | Cust_lastname | Cust_email | Cust_mobile |
----------------------------------------------------------------------------
| 101 | XXXX | YYYYY |xxx@xyz.com | 8282263131 |
----------------------------------------------------------------------------
上面的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)。如果急加载:
SELECT * FROM T_CUSTOMER WHERE cust_id=101;
选择*FROM T_CUSTOMER cust JOIN T_add ON cust.cust_id=add.cid
i、 它将加载与T_CUSTOMERS表及其关联表相关的所有数据,在本例中为T_ADDRESS表
2.I延迟加载的情况:
SELECT * FROM T_CUSTOMER WHERE cust_id=101;
因此,它只获取对应于T_CUSTOMER表的数据,并使用@Radim Köhler上面所说的T_ADDRESS表的代理。仅当您调用以下命令时,它才会从T_地址表中获取数据:
cust.getAddresses();
它如何在实体内开发人员配置的关联上配置的获取模式(延迟或早期)的上下文中工作?如果是紧急加载,则需要显式配置获取策略=“JOIN”,默认值为“select”@Vinit89 yes,我想我在复制另一个答案的内容时忘了编辑这个。感谢您指出这一点。我认为cust.getAddresses()只返回代理对象。它不会触发选择查询,因为cust不是代理对象。请验证它。