本文共 2232 字,大约阅读时间需要 7 分钟。
上次我们说到Hibernate对象的几种状态,今天我们来看看Hibernate中的缓存机制。hibernate中的缓存有两种,分为一级缓存和二级缓存,
缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域。
缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。
Hibernate是一个持久层框架,经常访问物理数据库。为了减少应用程序对物理数据源访问的次数,提高应用程序的运行性能,我们可以采用缓存机制。
使用缓存,肯定是长时间不改变的数据,如果经常变化的数据放到缓存里就没有太大意义了。因为经常变化,还是需要经常到数据库里查询,那就没有必要用缓存了。
Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到的时候 就会从物理数据源中检索,所以,把频繁使用的数据加载到缓存区后,就可以大大减少应 用程序对物理数据源的访问,使得程序的运行性能明显的提升。在使用缓存机制需要注意数据缓存和物理内存数据统一性,在使用过程中缓存的过期清理和手工清理影响也要考虑。
hibernate是一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。
hibernate一级缓存生命周期很短,和session生命周期一样,一级缓存也称session级的缓存或事务级缓存。 由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。 第一级缓存是必须的,不允许而且事实上也无法被卸除。在第一级缓存中,持久化类的每个实例都具有惟一的OID。
evit(Object obj) 将指定的持久化对象从一级缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。
clear() 将一级缓存中的所有持久化对象清除,释放其占用的内存资源。
contains(Object obj) 判断指定的对象是否存在于一级缓存中。
flush() 刷新一级缓存区的内容,使之与数据库数据保持同步。
save()。当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。
get()和load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓存中。
二级缓存是一个可插拔的缓存插件,它由SessionFactory负责管理。因此它可被所有的Session对象所共享。
由于SessionFactory对象的生命周期和应用程序的整个进程对应,因此第二级缓存是进程范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。 这个缓存中存放的是对象的散装数据。 第二级缓存是可选的,是一个可配置的插件,可以在每个类或每个集合的粒度上配置第二级缓存,默认下SessionFactory不会启用这个插件。 Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。
evict(Class arg0, Serializable arg1)将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源。
evict(Class arg0) 将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源。
evictCollection(String arg0) 将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源。
1) 很少被修改的数据
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 常量数据
1) 经常被修改的数据
2) 绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发
3) 与其他应用共享的数据。
一级缓存采用的是Key-Value的MAP方式来实现的。在缓存实体对象时,对象的主关键字ID是MAP的Key,实体对象就是对象的值。所以说一级缓存是以实体对象为单位进行存储的。访问的时候使用的是主键关键字ID。
二级缓存的实现原理与一级缓存是一样的。也是通过Key-Value的Map来实现对对象的缓存。
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;
查不到时,如果配置了二级缓存,那么从二级缓存中查; 如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。
我们从开始介绍Hibernate概念到Hibernate映射关系,最后写了Hibernate的对象状态和缓存机制,这些都只是冰山一角。以后的知识还需要我们继续深挖。希望这一系列的文章能让Hibernate的初学者有第一定的收获。以后我们再继续分享其他知识。