[英]How Session.get method works in hibernate
我試圖通過Session Get方法了解對象初始化如何為返回的對象工作。請驗證我的理解。 執行時,它會檢查第一級緩存中具有給定標識符的對象,然后檢查第二級緩存(如果已配置),如果未找到,則觸發select查詢以從數據庫中檢索數據。 我的問題是,它是否包含為延遲加載配置的select查詢中的關聯,或者為返回對象中的此類關聯設置空值?
如果是這種情況,那么session.get不會對返回的對象進行完整的初始化,這與Web上可用的大多數hibernate教程所寫的內容相矛盾。
Hibernate Session提供了從數據庫中獲取數據的不同方法。 其中兩個是 - get()和load()。 get()通過從數據庫或從hibernate緩存中獲取對象來返回對象。 當我們使用get()來檢索不存在的數據時,它返回null,因為它會在調用時盡快加載數據。
例如 :
在股票應用程序中,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的引用。
回答這個問題:
是否包含為延遲加載配置的select查詢中的關聯,或者為返回對象中的此類關聯設置空值?
1) session.get()
不會啟動懶惰的東西。 決不。 實際上,這是設計的核心思想。 否則 - 我們將能夠在一個SHOT中加載整個DB(在一個JAVA調用session.get()
)
2)而且也不會為空。 每個參考或集合將由代理表示。 這就是我們如何避免一次性加載強制數據庫的方式(所有用一個方法get初始化的東西)。 因為每個代理實際上都是一個承諾 - 一旦我們觸摸它......它將加載真實數據。
等等。 因此獲得非常安全的方式如何收集盡可能少的數據....
只是
當調用get()
方法時,它將直接命中數據庫,獲取結果並返回。 如果找不到匹配的字段,它將很樂意返回null。
根據引用的注釋, Lazy或Eager ,將返回數據。 如果是Lazy
,則返回代理而不是null,如果Eager
,將返回完全初始化的對象。
最好監控后端的查詢,以便更好地理解。
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 DB表的地址實體類:
@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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.