本文实例讲述了Hibernate框架中的缓存技术。分享给大家供大家参考,具体如下:
Hibernate框架的缓存分为Session的缓存、SessionFactory的缓存,也称为一级缓存和二级缓存。
一级缓存:
一级缓存是Session级的缓存,其生命周期很短,与Session相互对应,由Hibernate进行管理,属于事务范围的缓存。当程序调用 Session的load()方法、get()方法、save()方法、saveOrUpdate()方法、update()方法或查询接口方法时,Hibernate会对实体对象进行缓存;当通过load()方法或get()方法查询实体对象时,Hibernate会首先到缓存中查询,在找不到实体对像的情况下,Hibernate才会发出SQL语句到数据库中查询,从而提高了Hibernate的使用效率。
举个例子来说吧:
- package com.xqh.util;
- import org.hibernate.Session;
- import com.xqh.model.User;
- public class Test {
- public static void main(String[] args) {
- Session session = null;
- try {
- session = HibernateUtil.getSession(); // 获取session
- session.beginTransaction(); //开启事务
- System.out.println("第一次查询:");
- User user = (User)session.get(User.class, new Integer(1));
- System.out.println("用户名:" + user.getName());
- System.out.println("第二次查询:");
- User user1 = (User)session.get(User.class, 1);
- System.out.println("用户名:" + user1.getName());
- session.getTransaction().commit();
- } catch (Exception e) {
- e.printStackTrace();
- // 出错将回滚事务
- session.getTransaction().rollback();
- } finally {
- // 关闭Session对象
- HibernateUtil.closeSession(session);
- }
- }
- }
复制代码
当程序通过get()方法第一次查用户对象时,Hibernate会发出一条SQL语句进行查询,此时Hibernate对其用户对象进行了一级缓存;当再次通过get()方法查询时,Hibernate就不会发出SQL语句了,因为用户名已经存在于一级缓存中。程序运行结果:
- 第一次查询:
- Hibernate:
- select
- user0_.id as id0_0_,
- user0_.name as name0_0_,
- user0_.sex as sex0_0_
- from
- tb_user_info user0_
- where
- user0_.id=?
- 用户名:xqh
- 第二次查询:
- 用户名:xqh
复制代码
注意:一级缓存的生命周期与Session相对应,它并不会在Session之间共享,在不同的Session中不能得到其他Session中缓存的实体对象
二级缓存:
二级缓存是SessionFactory级的缓存,其生命周期与SessionFactory一致。二级缓存可在多个Session间共享,属于进程范围或群集范围的缓存。
二级缓存是一个可插拔的缓存插件,它的使用需要第三方缓存产品的支持。在Hibernate框架中,通过Hibernate配置文件配置二级缓存的使用策略。
1.加入缓存配置文件ehcache.xml
- <ehcache>
- <!-- Sets the path to the directory where cache .data files are created.
- If the path is a Java System Property it is replaced by
- its value in the running VM.
- The following properties are translated:
- user.home - User's home directory
- user.dir - User's current working directory
- java.io.tmpdir - Default temp file path -->
- <diskStore path="java.io.tmpdir"/>
- <!--Default Cache configuration. These will applied to caches programmatically created through
- the CacheManager.
- The following attributes are required for defaultCache:
- maxInMemory - Sets the maximum number of objects that will be created in memory
- eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
- is never expired.
- timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
- if the element is not eternal. Idle time is now - last accessed time
- timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
- if the element is not eternal. TTL is now - creation time
- overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
- has reached the maxInMemory limit.
- -->
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="true"
- />
- <!--Predefined caches. Add your cache configuration settings here.
- If you do not have a configuration for your cache a WARNING will be issued when the
- CacheManager starts
- The following attributes are required for defaultCache:
- name - Sets the name of the cache. This is used to identify the cache. It must be unique.
- maxInMemory - Sets the maximum number of objects that will be created in memory
- eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
- is never expired.
- timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
- if the element is not eternal. Idle time is now - last accessed time
- timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
- if the element is not eternal. TTL is now - creation time
- overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
- has reached the maxInMemory limit.
- -->
- <!-- Sample cache named sampleCache1
- This cache contains a maximum in memory of 10000 elements, and will expire
- an element if it is idle for more than 5 minutes and lives for more than
- 10 minutes.
- If there are more than 10000 elements it will overflow to the
- disk cache, which in this configuration will go to wherever java.io.tmp is
- defined on your system. On a standard Linux system this will be /tmp"
- -->
- <cache name="sampleCache1"
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="300"
- timeToLiveSeconds="600"
- overflowToDisk="true"
- />
- <!-- Sample cache named sampleCache2
- This cache contains 1000 elements. Elements will always be held in memory.
- They are not expired. -->
- <cache name="sampleCache2"
- maxElementsInMemory="1000"
- eternal="true"
- timeToIdleSeconds="0"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- /> -->
- <!-- Place configuration for your caches following -->
- </ehcache>
复制代码
2.设置Hibernate配置文件。
- <!-- 开启二级缓存 -->
- <property name="hibernate.cache.use_second_level_cache">true</property>
- <!-- 指定缓存产品提供商 -->
- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
- <!-- 指定二级缓存应用到的实体对象 -->
- <class-cache class="com.xqh.model.User" usage="read-only"></class-cache>
复制代码
例:
- package com.xqh.util;
- import org.hibernate.Session;
- import com.xqh.model.User;
- public class Test {
- public static void main(String[] args) {
- Session session = null; // 第一个Session
- try {
- session = HibernateUtil.getSession();
- session.beginTransaction();
- System.out.println("第一次查询:");
- User user = (User)session.get(User.class, 1);
- System.out.println("用户名:" + user.getName());
- session.getTransaction().commit();
- } catch (Exception e) {
- e.printStackTrace();
- // 出错将回滚事务
- session.getTransaction().rollback();
- } finally {
- // 关闭Session对象
- HibernateUtil.closeSession(session);
- }
- try {
- session = HibernateUtil.getSession(); // 开启第二个缓存
- session.beginTransaction();
- System.out.println("第二次查询:");
- User user = (User)session.get(User.class, 1);
- System.out.println("用户名:" + user.getName());
- session.getTransaction().commit();
- } catch (Exception e) {
- e.printStackTrace();
- // 出错将回滚事务
- session.getTransaction().rollback();
- } finally {
- // 关闭Session对象
- HibernateUtil.closeSession(session);
- }
- }
- }
复制代码
二级缓存在Session之间是共享的,因此可在不同Session中加载同一个对象,Hibernate将只发出一条SQL语句,当第二次加载对象时,Hibernate将从缓存中获取此对象。
程序结果:
- 第一次查询:
- Hibernate:
- select
- user0_.id as id0_0_,
- user0_.name as name0_0_,
- user0_.sex as sex0_0_
- from
- tb_user_info user0_
- where
- user0_.id=?
- 用户名:xqh
- 第二次查询:
- 用户名:xqh
复制代码
对于二级缓存,可以使用一些不经常更新的数据或参考的数据,此时其性能会得到明显的提升。但如果经常变化的数据应用二级缓存,则性能方面会造成一定问题。
希望本文所述对大家基于Hibernate框架的java程序设计有所帮助。 |