Hibernate中的一级缓存、二级缓存和懒加载

1.为何使用缓存

  hibernate使用缓存减小对数据库的访问次数,从而提高hibernate的执行效率。hibernate中有两种类型的缓存:一级缓存和二级缓存。html

2.一级缓存

  Hibenate中一级缓存,也叫作session的缓存,当调用session的save/saveOrUpdate/get/load/list/iterator方法的时候,都会把对象放入session的缓存中。sql

  一级缓存能够在session范围内减小数据库的访问次数,只在session范围有效,session关闭,一级缓存失效。数据库

  session的缓存由hibernate维护, 用户不能操做缓存内容; 若是想操做缓存内容,必须经过hibernate提供的evit/clear方法操做。缓存

特色:session

         只在当前session范围有效,做用时间短,效果不是特别明显!框架

         在短期内屡次操做数据库,效果比较明显!ide

list和iterator的区别spa

list:hibernate

一次把全部的记录都查询出来code

会放入缓存,但不会从缓存中获取数据

Iterator:

N+1查询; N表示全部的记录总数,即会先发送一条语句查询全部记录的主键(1),再根据每个主键再去数据库查询(N)

会放入缓存,也会从缓存中取数据

复制代码
    public void test5()throws Exception{
        Session session = sf.openSession();
        session.beginTransaction();

        User user = new User();
        user.setUserName("林黛玉");
        session.save(user);
        user.setUserName("嘉宝");
        session.save(user);
        session.getTransaction().commit();
        session.close();
    }
复制代码

  因为一级缓存的做用,user对象只会被保存一次。

3.二级缓存

Hibernate提供了基于应用程序级别的缓存, 能够跨多个session,即不一样的session均可以访问缓存数据。 这个缓存也叫二级缓存。

Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!若是用户想用二级缓存,只须要在hibernate.cfg.xml中配置便可; 不想用,直接移除,不影响代码。若是用户以为hibernate提供的框架框架很差用,本身能够换其余的缓存框架或本身实现缓存框架。

开启二级缓存:

list() 默认状况只会放入缓存,不会从一级缓存中取,配置查询缓存,可让list()查询从二级缓存中取数据。

复制代码
        <!--开启二级缓存-->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!--指定使用的缓存框架-->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

        <!--开启查询缓存-->
        <property name="hibernate.cache.use_query_cache">true</property>
复制代码

  指定须要二级缓存的类:

  若是设置了集合缓存,集合所属的元素对象也要放入二级缓存,即Employee。

        <!--指定哪一些类须要加入二级缓存-->
        <class-cache class="com.juaner.department.Employee" usage="read-only"/>
        <class-cache class="com.juaner.department.Dept" usage="read-only"/>
        <!--集合缓存,集合所属的类型也要放入二级缓存-->
        <collection-cache collection="com.juaner.department.Dept.emps" usage="read-only"/>

  使用二级缓存:

  若是设置了查询缓存,须要手动设置setCacheable(true)。

复制代码
   @Test
    public void test1(){
        Session session = sf.openSession();
        session.beginTransaction();
        //setCacheable 指定从二级缓存中找,或放入二级缓存,针对list不从一级缓存中取数据的状况
        //从缓存中读数据,查询条件必须一致
        //缓存机制为Map<条件,结果>
        Query query = session.createQuery("from Dept").setCacheable(true);
        System.out.println(query.list());

        session.getTransaction().commit();
        session.close();

        Session session1 = sf.openSession();
        session1.beginTransaction();

        query = session1.createQuery("from Dept").setCacheable(true);
        System.out.println(query.list());

        session1.getTransaction().commit();
        session1.close();
    }
复制代码

4.get和load

get: 及时加载,只要调用get方法马上向数据库查询

load:默认使用懒加载,当用到数据的时候才向数据库查询

5.懒加载

  当用到数据的时候才向数据库查询,这就是hibernate的懒加载特性。

lazy 值

     true     使用懒加载

     false    关闭懒加载

     extra   在集合数据懒加载时候提高效率,在真正使用数据的时候才向数据库发送查询的sql,若是调用集合的size()/isEmpty()方法,只是统计,不真正查询数据!

 

来源于:https://www.cnblogs.com/juaner767/p/5575076.html

相关文章
相关标签/搜索