Hibernate中的缓存

来源:互联网 发布:淘宝引擎优化 编辑:程序博客网 时间:2024/05/16 09:29


Hibernate中提供了两个级别的缓存

Session级别的缓存:

它是属于事务范围的缓存,这一级别的缓存由hibernate管理,一般情况下无需进行干预

SessionFactory级别的缓存:

它是属于进程范围的缓存

启用二级缓存的条件:

1、  很少被修改

2、  很多系统得模块都是要用到的

3、  不是私有的数据,是共享的

配置二级缓存的方法【每种方法操作之前都要把commons-logging-1.1.1.jar】:

1、  在类的映射文件中配置

2、  在配置文件中配置

3、  在ehcache.xml文件中配置【此文件可以指定缓存存储到硬盘的哪个位置】

Ehcache.xml文件中的属性:

1、<diskStore>:指定一个目录,当ehcache把数据写到硬盘上时,将吧数据写到这个文件目录下,默认是:C:\WINDOWS\Temp

2、<defaultCache>:设置缓存的默认数据过去策略

3、<cache>:设定具体的命名缓存的数据过期策略

4、每个命名缓存代表一个缓存区域,每个缓存区域有各自的数据过期策略。命名缓存机制使得用户能够在每个类以及类的每个集合的粒度上设置数据过期策略

Cache元素的属性:

1、  name:设置缓存的名字,它的取值为类的全限定名或类的集合的名字

2、  maxElementsInMeory:设置基于内存的缓存中可存放的对象的最大数目

3、  eternal:设置对象是否永久的,true表示永不过期

4、  timeToIdleSeconds和timeToLiveSeconds属性:默认值为false

5、  timeToIdleSeconds:设置对象空闲最长时间,以秒为单位,超过这个时间对象过期。当对象过期时,ehcache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态

6、  timeToLiveSeconds:设置对象生存的最长时间,超过这个时间,对象过期。如果此值为0,表示对象可以无限期的存在于缓存中,该属性值必须大于或者等于timeToIdleSeconds属性值

7、  overflowToDisk:设置基于内在的缓存中的对象数目达到上线后,是否把溢出的对象写到基于硬盘的缓存中

8、  diskPersistent:当jvm结束时是否持久化对象true  false 默认为false

9、  diskExpiryIntervalSeconds:指定专门用于清除过期对象的监听线程的轮询时间

 

例子:

1、从二级缓存中取数据

    //测试二级缓存

    /*

     * 当session关闭以后hibernate的一级缓存也就关闭了,这个时候再查询相同的数据,

     * 肯定会发出sql但是如果当前对象被缓存到二级缓存中的时候,session关闭,但是

     * 二级缓存并没有消失,所有这个时候再查询相同的数据,也不会发出sql语句

     * */

    @Test

    public void testCache(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Customers customer=(Customers) session.load(Customers.class, 2);

       System.out.println(customer.getEmail());

       tx.commit();

       session.close();

      

       session=HibernateUtil.getSession();

       tx=session.beginTransaction();

       customer=(Customers) session.load(Customers.class, 2);

       System.out.println(customer.getPetName());

       tx.commit();

       session.close();

      

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

aa@aa.com

bbb

注:当二级缓存关闭以后,运行结果中会有两条sql语句

 

2、把数据同步到二级缓存

    //测试对对象的操作,会同步到二级缓存

    @Test

    public void testUpdate(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Customers customer=(Customers) session.load(Customers.class, 2);

       System.out.println(customer.getEmail());

       customer.setEmail("aaa123@qq.com");

       tx.commit();

       session.close();

      

       session=HibernateUtil.getSession();

       tx=session.beginTransaction();

       customer=(Customers) session.load(Customers.class, 2);

       System.out.println(customer.getEmail());

       tx.commit();

       session.close();

      

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

aa@aa.com

Hibernate: updatepros.customers set realName=?, pass=?, sex=?, petName=?, email=?, rdate=? whereid=?

aaa123@qq.com

 

4、 改变值的时候同步到二级缓存:

    //当改变值的时候二级缓存会重新加载数据,已保证数据的一致性

    @Test

    public void testUpdateTimeStampCache(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Customers customer=(Customers) session.load(Customers.class, 1);

       System.out.println(customer.getPetName());

       Query query=session.createQuery("update Customers c set c.petName='wang' where c.id=1");

       query.executeUpdate();

       tx.commit();

       session.close();

      

       session=HibernateUtil.getSession();

       tx=session.beginTransaction();

       //重新查询数据库,因为缓存中的数据和数据库的数据已经不一致,利用时间截的方式

       customer=(Customers) session.load(Customers.class, 1);

       System.out.println(customer.getPetName());

       tx.commit();

       session.close();

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

34

Hibernate: updatepros.customers set petName='wang' where id=1

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_, customers0_.passas pass0_0_, customers0_.sex as sex0_0_, customers0_.petName as petName0_0_,customers0_.email as email0_0_, customers0_.rdate as rdate0_0_ frompros.customers customers0_ where customers0_.id=?

Wang

当查询语句为update Customers c set c.petName=wang where c.id=1时会抛异常,所有一定要看好要修改的元素的类型呀

5、  缓存到临时目录

//测试缓存溢出存放到临时目录

    @Test

    public void testowerFlow(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Query query=session.createQuery("from Customers c");

       query.list().size();

       tx.commit();

       session.close();

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_, customers0_.realName as realName0_, customers0_.pass aspass0_, customers0_.sex as sex0_, customers0_.petName as petName0_,customers0_.email as email0_, customers0_.rdate as rdate0_ from pros.customerscustomers0_

6、  Session.iterate方法

//iterator先到数据库中检索符合条件的id,然后根据id分别到一级和二级缓存中查找对象

    //(没有在查询数据库,每次只能查一个,可能导致n+1次查询)

    /*

     * 因为第一次关闭了session,所有一级缓存里的数据已经不存在了,而二级缓存中的数据并没有消失

     * 所有小于2的数据应该存在二级缓存中,而大于2的数据应该在查询数据库的时候才能查询到

     * */

    @Test

    public void testIterator(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Query query=session.createQuery("from Customers c where c.id<2");

       query.list().size();

       tx.commit();

       session.close();

      

       session=HibernateUtil.getSession();

       tx=session.beginTransaction();

        query=session.createQuery("from Customers c");

        Iterator<Customers> it=query.iterate();

        while(it.hasNext()){

            System.out.println(it.next().getEmail());

        }

        tx.commit();

           session.close();

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_, customers0_.realName as realName0_, customers0_.pass aspass0_, customers0_.sex as sex0_, customers0_.petName as petName0_,customers0_.email as email0_, customers0_.rdate as rdate0_ from pros.customerscustomers0_ where customers0_.id<2

Hibernate: selectcustomers0_.id as col_0_0_ from pros.customers customers0_

ewr

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

aaa123@qq.com

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

aa@aa.com

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

32432@ww.con

Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from pros.customers customers0_ where customers0_.id=?

rty

7、 查询缓存

/*

     * 测试查询缓存

     * 查询缓存依赖二级缓存,所有必须开启二级缓存,查询缓存才能起作用

     * */

    @Test

    public void testQueryCache(){

       Session session=HibernateUtil.getSession();

       Transaction tx=session.beginTransaction();

       Query query=session.createQuery("select c from Customers c where c.id=2");

       /*

        * 设置查询缓存

        *      如果查询缓存存在,直接返回

        *      如果查询不存在,查询数据库,将查询结果放置到缓存中

        * */

       query.setCacheable(true);

       query.list();

       tx.commit();

       session.close();

      

       session=HibernateUtil.getSession();

       tx=session.beginTransaction();

       query=session.createQuery("select c from Customers c where c.id=2");

       query.setCacheable(true);

       query.list();

       tx.commit();

       session.close();

    }

运行结果:

Hibernate: selectcustomers0_.id as id0_, customers0_.realName as realName0_, customers0_.pass aspass0_, customers0_.sex as sex0_, customers0_.petName as petName0_, customers0_.emailas email0_, customers0_.rdate as rdate0_ from pros.customers customers0_ wherecustomers0_.id=2

Hibernate: selectcustomers0_.id as id0_, customers0_.realName as realName0_, customers0_.pass aspass0_, customers0_.sex as sex0_, customers0_.petName as petName0_,customers0_.email as email0_, customers0_.rdate as rdate0_ from pros.customerscustomers0_ where customers0_.id=2