hibernate中的缓存机制
什么是缓存
缓存是介于应用程序与物理数据源之间的空间,也就是我们常说的内存。是为了减少程序对物理数据源的访问,因为对物理数据源的访问比较的消耗资源而且访问速度比较慢。而内存是告诉缓冲区,处于缓冲区中的数据,基本上都是用户需要的数据,这样可以提高程序执行的性能
hibernate中的一级缓存
一级缓存又称session缓存,一个回话一个缓存,默认开启不可关闭,多个session之间数据不共享,单会话关闭或者session关闭时,缓存丢失
原理
当用户发送查询请求的时候,orm会从缓存中查找数据,如果有直接拿使用该数据;如果没有,那么orm会发送一条sql语句从数据库中查询,同时将查询得到的结果放在session缓存中。
缓存处理相关的问题
但对数据执行了增删改动作是,程序会自动的删除缓存中的数据,目的是为了降低数据并发的可能性,已经处于session缓存中的数据不允许执行删除动作
测试一级缓存
Student stu=(Student) session.get(Student.class, "4");
System.out.println(stu.getStu_name());
System.out.println("===============1=================");
Student stu1=(Student) session.get(Student.class, "4");
System.out.println(stu1.getStu_name());
此时只会发送一条sql语句,第一次查询的时候会将得到的对象放在session缓存中,当第二次查询的时候会直接从session缓存获取该对象,从而不用发送sql语句来查询数据库
hibernate二级缓存
hibernate中二级缓存是一个可插拔式的缓存插件,需要手动开启,同时可以选择不同的供应商,有sessionFactory管理,所有的回话都是通过sessionFactory创建,多个session之间共享sessionFactory中的缓存数据,实现了跨事务共享数据。带来了更高的访问性能,同时也会产生严重的数据并发
使用场合
- 很少被修改的数据
- 允许出现并发数据的场合
- 不会出现数据并发的场合
二级缓存的使用
1.下载二级缓存依赖的包
<!- 并发处理端口的工具包->
<dependency>
<groupId>backport-util-concurrent</groupId>
<artifactId>backport-util-concurrent</artifactId>
<version>2.2</version>
</dependency>
<!-- 日志文件包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!- 进程内缓存的框架->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.1.4</version>
</dependency>
2.开启二级缓存和配置二级缓存供应商
hibernate.cfg.xml
<!-- 配置二级缓存 -->
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> -->
<!--二级缓存提供商• -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- 制定需要二级缓存的对象 -->
<class-cache usage="read-write" class="com.it.bean.Student"/>
3.配置ehcache.xml配置文件
ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
其中的配置参数
<!--
defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
eternal:代表对象是否永不过期
timeToIdleSeconds:最大的发呆时间
timeToLiveSeconds:最大的存活时间
overflowToDisk:是否允许对象被写入到磁盘
-->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />
<!--
cache:为指定名称的对象进行缓存的特殊配置
name:指定对象的完整名
-->
<cache name="com.zbaccp.entity.Person" maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" />
测试二级缓存
public class TestSecondCache {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
@Before
public void createSessionFactory(){
try {
//创建SessionFactory工厂
sessionFactory =new Configuration().configure().buildSessionFactory();
}catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testSecontCache(){
try {
Session session1=sessionFactory.getCurrentSession();
Transaction tx1=session1.beginTransaction();
Session session2=sessionFactory.getCurrentSession();
Transaction tx2=session2.beginTransaction();
Student stu1=(Student)session1.get(Student.class, "1003");
System.out.println(stu1.getStu_name()+"===1====");
tx1.commit();
Student stu2=(Student)session2.get(Student.class, "1003");
System.out.println(stu2.getStu_name()+"===2===");
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试二级缓存可能出现的问题
延迟加载
延迟加载(lazy load)是(也称为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
懒加载的特殊情况:
代理对象的创建需要依赖session,代理对象依赖的session已经被关闭了。
- Load:延迟加载
当访问该对象的非主属性的时候,才会通过orm发送sql语句,进行查询。
当查找的对象不存在的时候,报错ObjectNotFoundException
体现的是资源调度
lazy=“false”:去除延迟加载
- Get:即刻加载
当查找的对象不存在的时候,报错NullpointException
hibernate中对象的三种状态
- 临时态(瞬时态)
Student stu=new Student(“”,””);
不和 Session 实例关联
在数据库中没有和瞬时对象关联的记录
当执行new动作的时候,对象会转化成临时态
-
持久态:
(1) 和 Session 实例关联(2) 在数据库中有和持久对象关联的记录
【注意点】
Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save() 或 update() 方法是没有意义的 -
游离态(托管态):
(1) 本质上和瞬时对象相同(2) 只是比瞬时对象多了一个数据库记录标识值 id.
三种对象之间如何相互转化
上一篇: 解决使用startup.bat批处理文件启动Tomcat一闪而过
下一篇: 第十二周作业