Hibernate之Session解析
1.Session概述
Session接口是Hibernate向应用程序提供的操纵数据库最主要的接口,它提供了基本的保存,更新,删除和加载java对象的方法
Session具有一个缓存,位于缓存中的对象成为持久化对象,它和数据库中的相关记录对应,Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被成为刷新缓存(flush)
站在持久化的角度,Hibernate把对象分为4种状态:持久化状态,临时状态,游离状态,删除状态。Session的特定方法能使对象从一个状态转换到另一个状态
2.Session缓存
@Testpublic void testGet() {
Session session = getSession();NewsEntity newsEntity = (NewsEntity) session.get(NewsEntity.class, 2);NewsEntity newsEntity1 = (NewsEntity) session.get(NewsEntity.class, 2);System.out.println(newsEntity);System.out.println(newsEntity1);session.close();}
该方法只会向数据库发送1条SQL语句。当进行第二次获取时,会从Session缓存中获取数据,而不是去向数据库查询
3.操作Session缓存
(1)flush缓存
Session按照缓存中对象的属性变化来同步更新数据库
默认情况下Session在以下时间点刷新缓存:
显示调用flush()方法
调用Transaction的commit()方法(该方法先flush,再提交事务)
当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会flush缓存
特殊情况:如果使用native生成器生成OID,那么当调用Session的save()方法保存对象,会立即执行插入操作
(2)设定刷新缓存的时间点
若希望改变flush的默认时间点,可以通过Session的setFlushMode()方法显式设定flush的时间点
/*调用Session的查询方法时,清理缓存,注意:这条规则必须保证显式开启的事务中调用Session.commit()时,清理缓存调用Session.flush()时,清理缓存
*/
session.setFlushMode(FlushMode.AUTO); //默认模式
/* 调用Session的查询方法时,不清理缓存调用Session.commit()时,不清理缓存调用Session.flush()时,清理缓存
*/
session.setFlushMode(FlushMode.MANUAL);
/*调用Session的查询方法时,不清理缓存调用Session.commit()时,清理缓存调用Session.flush()时,清理缓存
*/
session.setFlushMode(FlushMode.COMMIT);
/*
调用Session的查询方法时,清理缓存,注意:这条规则必须保证显式开启的事务中
调用Session.commit()时,清理缓存
调用Session.flush()时,清理缓存
*/
session.setFlushMode(FlushMode.ALWAYS);
4.持久化对象的状态
Hibernate把对象分为4种状态:
持久化状态,临时状态,游离状态,删除状态
临时对象(Transient)
在使用代理主键的情况下,OID通常为null
不处于Session的缓存中
在数据库中没有对应的记录
持久化对象(Persist)
OID不为null
位于Session缓存中
若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
Session在flush缓存时,会根据持久化对象的属性变化,来同步更新数据库
在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
删除对象(Removed)
在数据库中没有和其OID对应的记录
不再处于Session缓存中
一般情况下,应用程序不该再使用被删除的对象
游离对象(Detached)
OID不为null
不再处于Session缓存中
一般情况下,游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录
5.对象的状态转换图
6.save()方法
Session的save()方法使一个临时对象转变为持久化对象
当对象为持久化状态时,不允许程序随意修改它的ID
@Testpublic void testAdd() {
Session session = getSession();//3. 开启事务Transaction transaction = session.beginTransaction();//4. 执行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("java语句很强吗");newsEntity.setAuthor("hello123");newsEntity.setData(new Date());session.save(newsEntity);newsEntity.setId(5);//5. 提交事务transaction.commit();//6. 关闭 Sessionsession.close();}
save()之后,又修改了NewsEntity,程序会抛出异常
persist()和save()的区别:
/*** persist(): 也会执行 INSERT 操作* * 和 save() 的区别 : * 在调用 persist 方法之前, 若对象已经有 id 了, 则不会执行 INSERT, 而抛出异常*/@Testpublic void testPersist(){Session session = getSession();//3. 开启事务Transaction transaction = session.beginTransaction();//4. 执行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("测试");newsEntity.setAuthor("java555");newsEntity.setData(new Date());newsEntity.setId(333);session.persist(newsEntity);//5. 提交事务transaction.commit();//6. 关闭 Sessionsession.close();}/*** 1. save() 方法* 1). 使一个临时对象变为持久化对象* 2). 为对象分配 ID.* 3). 在 flush 缓存时会发送一条 INSERT 语句.* 4). 在 save 方法之前的 id 是无效的* 5). 持久化对象的 ID 是不能被修改的!*/@Testpublic void testSave(){Session session = getSession();//3. 开启事务Transaction transaction = session.beginTransaction();//4. 执行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("测试");newsEntity.setAuthor("java555");newsEntity.setData(new Date());newsEntity.setId(333);session.save(newsEntity);//5. 提交事务transaction.commit();//6. 关闭 Sessionsession.close();
// news.setId(101); }
7.get()和load()方法
/*** get VS load:* * 1. 执行 get 方法: 会立即加载对象. * 执行 load 方法, 若不适用该对象, 则不会立即执行查询操作, 而返回一个代理对象* * get 是 立即检索, load 是延迟检索. * * 2. load 方法可能会抛出 LazyInitializationException 异常: 在需要初始化* 代理对象之前已经关闭了 Session* * 3. 若数据表中没有对应的记录, Session 也没有被关闭. * get 返回 null* load 若不使用该对象的任何属性, 没问题; 若需要初始化了, 抛出异常. */
@Testpublic void testLoad(){Session session = getSession();NewsEntity news = (NewsEntity) session.load(NewsEntity.class, 1);System.out.println(news.getClass().getName());
// session.close();
// System.out.println(news); }
@Testpublic void testGet1(){Session session = getSession();NewsEntity news = (NewsEntity) session.get(NewsEntity.class, 1);
// session.close();System.out.println(news);}
8.update()方法
Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句.
若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设为 true. 该属性的默认值为 false
当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常
当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常
9.saveOrUpdate()方法
/*** 注意:* 1. 若 OID 不为 null, 但数据表中还没有和其对应的记录. 会抛出一个异常.* 2. 了解: OID 值等于 id 的 unsaved-value 属性值的对象, 也被认为是一个游离对象*/@Testpublic void testSaveOrUpdate(){Session session = getSession();//3. 开启事务Transaction transaction = session.beginTransaction();NewsEntity news = new NewsEntity("FFF", "fff", new Date());news.setId(11);session.saveOrUpdate(news);//5. 提交事务transaction.commit();//6. 关闭 Sessionsession.close();}
10.delete()方法
/*** delete: 执行删除操作. 只要 OID 和数据表中一条记录对应, 就会准备执行 delete 操作* 若 OID 在数据表中没有对应的记录, 则抛出异常** 可以通过设置 hibernate 配置文件 hibernate.use_identifier_rollback 为 true,* 使删除对象后, 把其 OID 置为 null*/@Testpublic void testDelete(){Session session = getSession();NewsEntity news = (NewsEntity) session.get(NewsEntity.class, 23);session.delete(news);
System.out.println(news);}
Hibernate之Session解析相关推荐
- Hibernate 3 深度解析
Hibernate 3 深度解析 Hibernate 的重要性,我想各位一定很清楚.那么 Hibernate 的一些重要功能项大家是否真的很了解呢,是否明白它的执行逻辑呢?本文章将会带领大家深入到 H ...
- hibernate 管理 Session(单独使用session,非spring)
hibernate 管理 Session(单独使用session,非spring) Hibernate 自身提供了三种管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 S ...
- 在Hibernate的session中同时有两个相同id的同类型对象,修改失败
若在Hibernate的session中同时有两个相同id的同类型对象,修改会失败,报错:a different object with the same identifier value was a ...
- Spring boot 解决 hibernate no session异常
Spring boot 解决 hibernate no session异常 参考文章: (1)Spring boot 解决 hibernate no session异常 (2)https://www. ...
- (继续搬)struts日期格式的转换以及hibernate中session的关闭在xml中的配置
1.struts日期格式的转换package cn.sxx.utils;import java.text.ParseException; import java.text.SimpleDateForm ...
- 一口一口吃掉Hibernate(二)——别被世俗蒙蔽了双眼:Hibernate中Session之get和load方法的真正区别
最近在学习SHH框架中的Hibernate,对Session的get和load方法,有点混不清楚,不知道区别在哪,或者对它们的区别感触不深.所以百度了一下,结果问题来了.百度的结果和实际测试的结果出入 ...
- Hibernate学习笔记 | 解析二级缓存
缓存 计算机领域非常通用的概念,它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能,缓存中的数据是数据存储源中 ...
- Hibernate的Session介绍[转 adoocoke]
Session Session是Hibernate向应用程序提供操作数据的主要接口, 他提供了保存.更新.删除.加载Java对象的方法. Session的缓存 Session有一个缓存,用来缓存Jav ...
- hibernate中session接口方法总结
Session的save()和persist()方法 Session的save()方法使一个临时对象转变为持久化对象.它完成以下操作: (1)将临时对象加入到Session缓存中,使其进入持久化状态. ...
最新文章
- 干货丨一份机器学习的初学者指南
- 使用SQL_TRACE进行数据库诊断
- html绘图环境,HTML_HTML5 在canvas中绘制文本附效果图,一、绘制文本 在绘图环境中提 - phpStudy...
- 跨站脚本攻击(selfxss)笔记(三)
- uva 10710——Chinese Shuffle
- Bootstrap创建进度条
- 关于layui中lay-verify=required无效的解决办法
- SQL:postgresql中为查询结果增加一个自增序列之ROW_NUMBER 	() OVER ()的使用
- 表格求和和计算机不一致6,(电子行业企业管理)计算机电子表格公式应用常见错误及处理(6页)-原创力文档...
- 数据结构实验1-线性表的顺序实现
- 免费分享一套狂雨小说cms采集规则
- 游戏植入广告获取收益
- linux找不到fastboot驱动下载,fastboot 刷机傻瓜教程
- Win10 打开MSDTC
- 大学物理(Ⅱ)公式整理
- 安卓Alarm闹钟唤醒耗电问题的排查
- java中cbrt_Java Math类静态double cbrt(double d)示例
- Oracle递归查询的使用
- 手动测量变量溢出长度
- HTML基础-笔记1标签