hibernate 中对象的状态

load() 和 get()

User user = session.get(User.class, "1");

如上调用get方法后,会向数据库查询id为1的user。

User user = session.load(User.class, "1");

如上调用load方法后,会返回一个代理对象,id为1,但其他属性都为null,并未向数据库查询。若继续执行String name = user.getName();,则才会执行数据库的查询。而在此时,很有可能数据库中根本没有id为1的user,就会报空指针异常。

session中对象的状态

1. 临时态

存在于jvm中,却不存在于数据库中的对象,适合以下情况:

1. 使用new关键字实例化出来的对象,还未保存到数据库中;

2. 从数据库中已经删除了的对象,还存在于jvm中时。(delete方法调用后)

2. 持久态

存在于jvm中,也存在于数据库记录中,session未关闭,保持着对象与记录的同步,适合以下情况:

1. 将jvm中存在的对象保存或同步到数据库中记录后对象的状态。(save、update方法调用后)

注: session中有一个map存放着被托管的对象,也就是hibernate以及缓存对象的来源。

3. 游离态

存在于jvm中,也存在于数据库记录中,session已关闭,对象与记录未保持同步,适合以下情况:

1. 对象已经持久化,session已关闭后的状态,不能保持对象与数据库记录的同步。(session的close、evict、clear方法被调用后)

脏检查和缓存清理

1. 缓存清理

当Session缓存中对象的属性每次发生了变化,Session并不会立即清理缓存和执行相关的SQL update语句,而是在特定的时间点才清理缓存,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,一遍减少访问数据库的次数,从而提高应用程序的数据访问性能。

在默认情况下,Session会在以下时间点清理缓存

  1. 当应用程序调用org.hibernate.Transaction的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。Hibernate之所以把清理缓存的时间点安排在事务快结束时,一方面是因为可以减少访问数据库的频率,还有一方面是因为可以尽可能缩短当前事务对数据库中相关资源的锁定时间。
  2. 当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,就会清理缓存,使得Session缓存与数据库已经进行了同步,从而保证查询结果返回的是正确的数据。
  3. 当应用程序显示调用Session的flush()方法的时候。

2. 脏检查

 Transaction tx=session.beginTransaction();
 User user=(User)session.load(User.class,”1”);//从数据库中加载符合条件的数据
 user.setName(“zx”);//改变了user对象的姓名属性,此时user对象成为了所谓的“脏数据”
 tx.commit();// 此时进行脏检查,将改变后的对象同步到数据库记录

当一个user对象被加入到Session缓存中时,Session会为user对象的值类型的属性复制一份快照。当Session清理缓存之前,会进行脏检查,即比较user对象的当前属性与它的快照,来判断user对象的属性是否发生了变化,如果发生了变化,就称这个对象是“脏对象”,Session会根据脏对象的最新属性来执行相关的update SQL语句,从而同步更新数据库。

发布了67 篇原创文章 · 获赞 1 · 访问量 1825

猜你喜欢

转载自blog.csdn.net/qq_15060345/article/details/100526357
今日推荐