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语句,从而同步更新数据库。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java成神之路

Java微信开发_03_使用测试号进行开发

今天进行自定义菜单的开发时,发现公众号没有自定义菜单的权限。于是想到用测试号,但微信服务器如何区分你要请求的是公众号还是测试号呢。

8930
来自专栏河湾欢儿的专栏

常用的dos命令

11720
来自专栏我的博客

CI页面乱码

今天项目页面乱码 我确认了数据库读取时utf8,页面也添加 <meta http-equiv=”content-type” content=”text/html...

31660
来自专栏闵开慧

centos中tree插件的使用与注意事项

1 tree的安装 yum -y install tree 使用时直接输入tree 目录名,即可显示该目录的树形结构,示例如下: ? 这样查看目录结构一目了然,...

29280
来自专栏Java后端技术

解决jetty7.0.pre5启动时报ClassNotFoundException: javax.interceptor.InvocationContext异常的问题

一.背景介绍:最近项目在使用maven命令行运行jetty服务器时出现ClassNotFoundException: javax.interceptor.Inv...

8210
来自专栏不想当开发的产品不是好测试

查看jar包的jdk版本并降级

用解压工具打开jar包(例子都是用7zip) ? 进入到META-INF目录,查看MANIFEST.MF文件,查看Bulid-Jdk,下图就为1.7.0_55版...

31170
来自专栏orientlu

python 模块与包

每个文件夹对应一个包,包里面可以包含多个包,对应的每个 .py 文件是一个具体模块。 封装成包,在文件上组织好代码后,确保每个目录都要一个 __init__....

17530
来自专栏栗霖积跬步之旅

git中的merge与rebase

29960
来自专栏赵俊的Java专栏

Python 文件操作

32730
来自专栏zhangdd.com

tomcat8 启动报错: ignoring option PermSize=256m处理方法

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; suppor...

21510

扫码关注云+社区

领取腾讯云代金券