zoukankan      html  css  js  c++  java
  • hibernate中的二级缓存

    二级缓存使用场景:不经常修改的数据,但是经常的访问的数据会放到缓存中去

    一级缓存仅仅是session内部的缓存,用来存取sql语句,比如说连续调用两次相同参数的get方法,就是session缓存

    二级缓存是sessiionFactory层面的缓存,即不同线程,不同程序之间的缓存

    1.在hibernate.hbm.xml中加载配置

    <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

    <!-- 配置缓存项 可以在hibernate.hbm.xml下配置 也可以在各自类下的映射文件下配 -->
    <class-cache usage="read-write" class="cache.Employee"/>
    <class-cache usage="read-write" class="cache.Department"/>

    类缓存

    public void testCahce()
    {
    Session session=sessionFactory.openSession();

    Transaction tx=session.beginTransaction();
    Employee employee=(Employee) session.get(Employee.class, 1);
    // System.out.println(employee);

    Session session2=sessionFactory.openSession();
    Employee employee1=(Employee) session.get(Employee.class,1);

    //sessionFactory 二级缓存 当两个session用get查询相同的数据就会调用使用


    tx.commit();
    session.close();
    }

    2.集合缓存

    <collection-cache usage="read-write" collection="cache.Department.employees"/> 

    /**
    * 二级缓存中的集合缓存
    */
    @Test
    public void testCahce2()
    {
    Session session=sessionFactory.openSession();

    Transaction tx=session.beginTransaction();
    Department department=(Department) session.get(Department.class, 1);
    System.out.println(department.getEmployees());//懒加载
    // System.out.println(employee);
    Session session2=sessionFactory.openSession();
    department=(Department) session2.get(Department.class, 1);
    System.out.println(department.getEmployees()); //由于集合为设置二级缓存 所以相同数据也会加载两次
    //sessionFactory 二级缓存 当两个session用get查询相同的数据就会调用使用

    tx.commit();
    session.close();

    不是用集合缓存


    }

    使用集合缓存

    3.查询语句缓存(只针对相同sql语句的缓存)

    (1)iterator实现

    /**
    * 查询缓存 n+1次查询 按一模一样的查询语句来缓存
    */
    @Test
    public void testQueryCache()
    {
    Session session=sessionFactory.openSession();

    Transaction tx=session.beginTransaction();
    Iterator<Employee> iterator=session.createQuery("from Employee where id<5").iterate();
    while(iterator.hasNext())
    {
    System.out.println(iterator.next());
    }

    Iterator<Employee> iterator1=session.createQuery("from Employee where id<5").iterate();
    while(iterator1.hasNext())
    {
    System.out.println(iterator1.next());
    }
    tx.commit();
    session.close();
    }

    (2)使用setCacheable实现

    需加载额外配置

    <property name="cache.use_query_cache">true</property>

    @Test
    public void testQueryCachetrue()
    {
    Session session=sessionFactory.openSession();

    Transaction tx=session.beginTransaction();
    List list=session.createQuery("from Employee where id<5").setCacheable(true).list();
    System.out.println(list);
    tx.commit();
    session.close();
    Session session1=sessionFactory.openSession();
    Transaction tx1=session1.beginTransaction();
    List list1=session1.createQuery("from Employee where id<5").setCacheable(true).list();
    System.out.println(list1);
    tx1.commit();
    session1.close();

    }

    但是sql语句有一点不一样 ,都不能使用缓存

     

  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/lt123/p/7241812.html
Copyright © 2011-2022 走看看