我知道当我们调用get或load方法时,hibernate使用反射调用默认构造函数创建一个对象。但是我无法理解hibernate如何在会话期间监视该对象。
假设我有一个POJO类代表数据库中的Entity。
public class User {
private int userId;
private String userName
// getters and setters.
}
假设在DB中。 现在的记录
userId - 1
userName - john
Session session = sessionfactory.openSession(); // Line 1
Transaction tx = session.beginTransaction(); //Line 2
User user = (User) session.load(User.class,1); //Line 3
user.getUserName(); //Line 4
tx.commit(); //Line 5
session.close(); //Line 6
但是在控制台选择查询发生在第4行,当我们调用getUserName()不在第3行时。我知道使用load我们只获得代理对象。但是在第4行我们只调用POJO getter,但它是如何以简单的java方式访问数据库选择查询的,这是不可理解的。有什么样的反思吗?任何机构都可以向我解释它是如何运作的。
再次,如果我使用get()方法得到对象。
Session session = sessionfactory.openSession(); // Line 1
Transaction tx = session.beginTransaction(); //Line 2
User user = (User) session.get(User.class,1); //Line 3
user.setUserName("mark"); //Line 4
tx.commit(); //Line 5
session.close(); //Line 6
选择查询发生在第3行。确定get()命中DB.but再次在第4行我们只调用setter但它如何在第5行的事务结束时命中数据库更新查询。
我通过来源但不明白。 在我的想法中,它看起来像反射和事件处理类的东西。对象或代理对象创建 通过get()或load()使用反射然后监视对象状态更改,如事件处理。有观察者设计模式或其他东西。
如果我正在思考正确的方向,那么有些人可以给我示例或链接进行练习,因为我对反思知之甚少。我也想做类似的事情监控对象状态。
答案 0 :(得分:0)
get()和load()方法之间的关键区别之一
load()
方法将首先检查会话级缓存中的实体。如果找到,则实体将从缓存中返回,否则它将查询数据库并将其返回给客户端。但get()
方法将直接从数据库中获取。
我的假设(如果我错了,请善意纠正):
User user = (User) session.load(User.class,1); //Line 3
user.getUserName(); //Line 4
第3行说你需要一个特定的对象。但是并不能保证你会使用它。因此他们可能已经实现了懒惰的fetch类型的内存管理。如果你没有使用它,那么你就是在浪费一个实例。但从整体上看,这可能是一种理性的设计。
User user = (User) session.load(User.class,1); //Line 3
//do some other operations…
但就get()
方法而言,情况有所不同。它每次都直接从数据库中获取。在这种情况下,它应该首先加载数据(这里没有想到),因为在调用getter方法(它可能属于连接的体系结构)时加载数据之前它不能保存一些指针。基本上这是我个人认为的昂贵。
Hibernate根据对象值而不是对象引用来观察对象状态。但是在收集的情况下,hibernate使用身份。