Session.get方法如何在hibernate中工作

时间:2015-01-12 07:13:35

标签: java hibernate get

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

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

4 个答案:

答案 0 :(得分:2)

Hibernate Session提供了从数据库中获取数据的不同方法。其中两个是 - get()和load()。 get()通过从数据库或从hibernate缓存中获取对象来返回对象。 当我们使用get()来检索不存在的数据时,它会返回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的引用。

答案 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();