Hibernate的持久化环境
很久没有使用Hibernate了,现在要复习一下, 面试的话这个是必不可少的.
1.Hibernate Session.
session的概念大概是这样:
(1). Session是一块内存,里面存放了Persistent状态的对象, 也就是Persistent Context(持久化环境)
(2). Session里面有一组排着队等着执行的Sql,这些sql的目的本质上都是为了确保缓冲区(session级别的缓存,一级缓存)的内容和数据库保持一致.
关于Persistent Context,注意几点:
(1). 就是存放对象的一块缓存
(2). 你不能通过相关的API来访问它(它就是隐藏在背后的一个神秘人物)
(3). 很明显,一个Hibernate Session对应一个Persistent Context
(4). 对应的是一级缓存,不是可选的,是必须的,而且不能disable.
除了效率的提高(缓存), 缓存还可以给我们带来另外的好处:
(1) 自动脏数据检查.
来个例子:
package com.yxy.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.stat.Statistics;
import com.yxy.bean.Student;
public class HibernateStatTest {
public static void main(String[] args){
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Statistics stat = sessionFactory.getStatistics();
Session session = sessionFactory.openSession();
session.getTransaction().begin();
stat.setStatisticsEnabled(true);
stat.clear();
Student student = (Student)session.load(Student.class, 1);
student.setName("Hello Hibernate !");
System.out.println(stat.getEntityLoadCount());
stat.setStatisticsEnabled(false);
session.getTransaction().commit();
session.close();
}
}
并没有调用update方法去更新,但是在事务提交之后是可以自动的将更新同步到数据库中的,控制台中也发出了相关的update语句
Hibernate:
/* update
com.yxy.bean.Student */ update
student
set
name=?,
sex=?,
register_date=?
where
id=?
原理很简单:
Hibernate会在session中保存一份对象最近从数据库中加载上来的快照(snapshot), 所以在写回到数据库中的时候(比如事务提交),会将当前的对象同快照进行对比,如果有变化,则将变化部分同步到数据库,要注意一点,自动脏数据检查只是针对persistent状态的对象,因为如果是detached状态的话,很明显sesson已经关闭,所以快照都不存在了,还对比什么啊.
得益于自动脏数据检查,Hibernate还有一个延迟写入策略(透明的交易层延迟写入) - Transparent transaction-level write-behind
例子如下:
package com.yxy.test;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.stat.Statistics;
import com.yxy.bean.Student;
public class HibernateWriteBehindTest {
public static void main(String[] args){
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Statistics stat = sessionFactory.getStatistics();
/*
* --------------------- Session 1 ---------------------------
*/
Session session = sessionFactory.openSession();
session.getTransaction().begin();
stat.setStatisticsEnabled(true);
stat.clear();
Student student = (Student)session.load(Student.class, 1);
student.setName("Hello Hibernate !");
System.out.println(stat.getEntityLoadCount());
stat.setStatisticsEnabled(false);
session.getTransaction().commit();
session.close();
/*
* 开启另外一个session, 这里的student是一个detached状态对象
*/
/*
* --------------------- Session 2 ---------------------------
*/
student.setName("Another Hibernate Session");
Session anotherSession = sessionFactory.openSession();
anotherSession.getTransaction().begin();
stat.setStatisticsEnabled(true);
stat.clear();
/*
* update student
*/
anotherSession.update(student);
/*
* 打印出flush的次数和修改对象的次数
*/
System.out.println("--------------- call update ----------------");
System.out.println(stat.getEntityUpdateCount());
System.out.println(stat.getFlushCount());
Student student2 = new Student();
student2.setName("Another Student");
student2.setRegisterDate(new Date(System.currentTimeMillis()));
student2.setSex("Man");
/*
* save student2
*/
anotherSession.save(student2);
/*
* 打印出新增对象个数等信息
*/
System.out.println("--------------- call save ----------------");
System.out.println(stat.getEntityInsertCount());
System.out.println(stat.getEntityUpdateCount());
System.out.println(stat.getFlushCount());
anotherSession.getTransaction().commit();
System.out.println("--------------- after commit ----------------");
System.out.println(stat.getEntityInsertCount());
System.out.println(stat.getEntityUpdateCount());
System.out.println(stat.getFlushCount());
stat.setStatisticsEnabled(false);
anotherSession.close();
}
}
通过console打印出来的部分信息可以看到:
--------------- call update ----------------
0
0
Hibernate:
select
hibernate_sequence.nextval
from
dual
--------------- call save ----------------
0
0
0
Hibernate:
/* insert com.yxy.bean.Student
*/ insert
into
student
(name, sex, register_date, id)
values
(?, ?, ?, ?)
Hibernate:
/* update
com.yxy.bean.Student */ update
student
set
name=?,
sex=?,
register_date=?
where
id=?
--------------- after commit ----------------
1
1
1
当调用update的时候,并不会马上同步到数据库中,同样的调用save方法时也不会马上生成insert并同步到数据库,而是等到事务commit,才会一次性flush. 其实这些没有马上执行的sql会保存在之前提高过的排着队的sql那个队列里面
延迟写入的好处:
(1) 可以减少数据库的负担,不会造成频繁的写数据库,当然也可以间接的提高并发性.
(2) 可以减少数据在网络上传输的开销.
但是也不是什么情况下都等到commit才会一股脑的将所有sql送给数据库去执行.比如说在中途要执行查询操作,这时Hibernate就会把之前的SQL送给数据库去执行了.因为要保证查询到的数据时最新的.
(关于这个问题,我不能试验出来啊,奇怪,看来书上说的还是有点不对,我使用的版本是Hibernate 3.2.0.ga)
在上述例子save student2之后调用:
List students = anotherSession.createSQLQuery("select * from student").list();
但是产生的统计信息没有变化. 这表示在发出查询操作后并没有把之前的sql交给数据库去处理.
关于Persistent Context的基本概念,就先到这啦.
分享到:
相关推荐
java-hibernate持久化
《冬眠的力量-Hibernate 持久化技术详解》这本书是本人多年基于Hibernate的系统架构设计以及系统开发经验总结和对Hibernate原理的研究成果。 本书成书于2007年8月,一直作为本人目前就职公司的内部技术手册参考,...
达梦数据DmDialect-for-hibernate所有jar包,DmDialect-for-hibernate2.0、DmDialect-for-hibernate2.1、DmDialect-for-hibernate3.0、DmDialect-for-hibernate3.1、DmDialect-for-hibernate3.6、DmDialect-for-...
spring-hibernate.jar
国产达梦数据库hibernate方言包
JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-...
Middlegen-Hibernate-r5.zip
dao-hibernate.jardao-hibernate.jardao-hibernate.jardao-hibernate.jardao-hibernate.jar
此文件中包了SpringBoot集成达梦7中所需要的驱动及方言jar包
JPA-Hibernate包, JPA-Hibernate包, JPA-Hibernate包, JPA-Hibernate包, JPA-Hibernate包, JPA-Hibernate包
包括 Middlegen-Hibernate-r5 hibernate-extensions-2.1.3
1. DmDialect-for-hibernate2.0.jar 对应 Jdk1.4及以上, hibernate2.0 环境 2. DmDialect-for-hibernate2.1.jar 对应 Jdk1.4及以上, hibernate2.1 -- 2.X 环境 3. DmDialect-for-hibernate3.0.jar 对应 Jdk1.4及以上...
hibernate的知识:持久化类(Persistent Classes)、对象关系数据库映射基础(Basic OR Mapping)、集合类(Collections)映射、关联关系映射、拦截器与事件(Interceptors and events)等。
xjar-agent-hibernate-v1.0.0.jar下载
Middlegen-Hibernate配合apache-ant-1.7.0-bin.tar来完成hibernate培植文件的生成。
Spring-hibernate结合使用全xml配置方式
DmDialect-for-hibernate2.0、DmDialect-for-hibernate2.1、DmDialect-for-hibernate3.0、DmDialect-for-hibernate3.1、DmDialect-for-hibernate3.6、DmDialect-for-hibernate4.0、DmDialect-for-hibernate5.0、...
Hibernate操作持久化对象Hibernate操作持久化对象Hibernate操作持久化对象Hibernate操作持久化对象Hibernate操作持久化对象
spring-hibernate3.jar 非常好用,请多支持!
maven-hibernate3-jdk14-2.0.jar