`
sungang_1120
  • 浏览: 321650 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类

Hibernate 缓存机制

阅读更多

1数据缓存:(date caching) 是一种将数据暂时存于内存缓存区中的技术,缓存通常是影响系统性能的关键因素 

2.ORM的数据缓存策略有3种 
  1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡. 

  2.应用级缓存:有多个事务共享,在SessionFactory层实现,由SessionFactory创建的session都共享次缓存 

  3.分布式应用缓存:有多个应用实例,由多个JVM共享的缓存模式,通过远程机制实现数据的同步.解决了多实例运行过程中数据的同步问题. 

Hibernate 的缓存  只从下面两个方面发生作用 
1.通过主键值加载对象 
2.延迟加载 

一级缓存 
释义:是一个session缓存,就是一个Map,一个 id为key Object 为value 的Map,Hibernate对一级缓存使用自动维护,没有提供任何配置功能,但是可以通过session提供方法来进行一些手动的干预, 
必须的 不能卸载的 

1.evict(); 用于将对象从Session的一级缓存中清除 
2.clear(); 将一级缓存中的对象全部清除. 

从上面可以看出 session缓存中不可能存在两个id 相同的key 对应的object 
所以 使用 session保存或者 udpate 的时候 需要使用 evict()清除指定的重复对象. 
  
1.evict()的使用

    public void testEvict(){  
            Configuration config=new Configuration().configure();  
            SessionFactory factory=config.buildSessionFactory();  
            Session session=factory.openSession();  
            Transaction tr=session.beginTransaction();  
            //一级缓存: session缓存 中 通过 id 获取对象  
            Integer deptId=new Integer(21);  
            Dept deptOne=(Dept)session.get(Dept.class, deptId);  
              
            Dept deptTwo =new Dept();  
            deptTwo.setDeptId(deptId);  
            deptTwo.setDeptName("采购部");  
            deptTwo.setCreateDate("2000-03-10");  
              
            session.evict(deptOne); //如果不先清除 相同id的 deptOne   下面的 saveOrUpdate 就会报错  
            session.saveOrUpdate(deptTwo);  
              
            tr.commit();  
        }  

 2.clear的使用 (如果执行批量修改的时候 需要使用大量的缓存这时就定时清空缓存)

    public void testClear(){  
            Configuration config=new Configuration().configure();  
            SessionFactory factory=config.buildSessionFactory();  
            Session session=factory.openSession();  
            Transaction tr=session.beginTransaction();  
            for(int i=0;i<10000;i++){  
                Dept deptTwo=new Dept();  
                deptTwo.setDeptName("才购物");  
                deptTwo.setCreateDate("2002-01-02");  
                session.save(deptTwo);  
                if(i%20==0){  
                    session.flush();  
                    session.clear();  
                }  
            }  
            tr.commit();  
            session.close();  
        }  

 二级缓存 
释义:1实现原理 和一级缓存一样 同样是一个 Id 为key Object 为value的一个Map集合 
2只是作用范围 扩大到 sessionFactory ,能够被所有的session共享 
3.非必须 可选的 ,可插拔缓存插件,能够在每个类或者集合的粒度上配置. 

功能分类: 
    内置缓存: 只读用于存放映射文件的数据及预定的sql语句, 
              映射元数据是映射文件中数据的副本 
              预定的sql语句:由Hibernate在初始化阶根据元数据推导生成. 
    外置缓存: 为配置插件,一般不启用. 

二级缓存的工作过程: 
1.执行各种查询时,如果获取的结果集为实体对象的集合,则将所有的实体对象根据id 存放 Map集合  即 二级缓存. 

2.根据id 获取对象的时候,首先会在一级缓存中查找,如果无法找到,而此时这个类又配置了二级缓存,则将在二级缓存中继续查找,若仍然无法找到,则会从数据库中查找,然后将结果通过id放入缓存中, 

3.删除 ,更新及 增加的时候  更新缓存 

二级缓存的使用 
1.作为一个可插入主键,一般在使用的时候进行配置,只有具备以下特征的对象才可以放入二级缓存中. 
  1 较少被修改的数据 
  2.非重要,能偶尔出现并发的数据 
  3.不会被并发访问的数据 
  4.参数数据 

相对而言, 以下特征数据不适合放入二级缓存 
  1.常被修改 
  2.财务数据, 绝不容许出现并发 
  3.与其他应用共享 


Hibernate 缓存在查询中的应用 

1.session.load:先从 一级缓存中查找 ,如果配置了二级缓存 会在二级缓存中查找,然后在数据库中查找,然后会填充到 一级缓存 二级缓存中 

2.session.get:不会在二级缓存中查找对象,会如果在一级缓存中找不到 会直接在数据库中查找 

3.query.list: 会首先检查是否配置了查询缓存,如果配置了则在查询缓存中查找,如果找不到,则直接在数据中查询,,获取后会填充一级缓存,和二级缓存及 查询缓存. 数据发生任何变化时,查询缓存都会清空. 

4.iterator:会首先通过查询语句获取id值的列表,然后使用session的load的方法获取需要对象的值. 

Hibernate的检索策略 
1.类级别检索   : 立即检索, 延迟检索 
2.关联级别检索 : 立即检索, 延迟检索, 迫切左外连接检索 

1.类级别 立即检索: 
释 义:指的是 在 配置文件中的class 中加入 lazy=false| true 的配置 .(默认为延迟检索:lazy=true,立即检索为 lazy=false);立即检索,只会影响 session.load 的方法 即 在加载的时候就会执行sql查询,而不是在使用对象属性的时候才执行sql查询 
session.get  是不会有 sql语句的

    //立即检索: 此时不会返回 代理对象 而是立刻执行 sql语句 查询对象  
        public void testQueryLoad1(){  
            Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
                    //执行上面这句 就会打印 sql语句  
        }  

 2.类级别 延迟检索: 
释义:在class 上配置 lazy=true (可以省略,默认延迟) .返回代理对象,即 只有id有值 ,其他的属性全是 null. 在hibernate运行时动态生成的扩展类,它继承了目标类,并且  在第一访问的时候才会初始化 这个代理对象

//延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象  
    public void testQueryLoad1(){  
        Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
          
        System.out.println("部门名称:"+dept.getDeptName());  
        //在执行上面这句时 才执行 sql语句 去查询,也就是第一次 (因为返回的代理对象,除id 外 其他的值都为空,所以才去查询)  
    }

 


延迟检索下 出现的一些不同的情况

     //检索的对象不存在  
public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(-2));  
               //执行上面不会报错  
    System.out.println("部门名称:"+dept.getDeptName());  
    //下面出现异常 ,因为 id为-2 的Dept不存在   
}  
      //session范围内 没有访问实体对象.(Hibernate会在第一访问代理对象的时候才会初始化代理对象)  
     public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
    session.close();  
               //执行上面不会报错  
    System.out.println("部门名称:"+dept.getDeptName());  
    //下面出现异常 ,session关闭了 代理对象没有初始化  
}  
  
  
      //延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象  
public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
      
    System.out.println("部门ID:"+dept.getDeptId());  
    //此时 根本就没有执行sql语句 因为 代理类 中的id 的默认值就是 我们设置的2,此时还是不会触发hibernate初始化代理实例  
              session.close();  
              System.out.println("部门名称:"+dept.getDeptName());  
               //报错,因为 代理没有被初始化过.  
                 
}  
  
     //显示的初始化代理对象  
      public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
    //显示的初始化代理对象      
    Hibernate.initialize(dept.getDeptName());  
      
    System.out.println("部门名称:"+dept.getDeptName());  
      
}  
  
       //显示初始化后  不会报错了.  
      public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
    //显示的初始化代理对象      
    Hibernate.initialize(dept.getDeptName());  
    session.close();  
    System.out.println("部门名称:"+dept.getDeptName());  
      
}  
  
       //隐式 的触发hibernate的初始化代理对象  
       public void testQueryLoad1(){  
    Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
     //隐式 的触发hibernate的初始化代理对象(就是在session范围 第一次访问代理对象,此时就会触发hibernate的初始化)   
    System.out.println("部门名称:"+dept.getDeptName());  
    session.close();  
    System.out.println("部门名称:"+dept.getDeptName());  
      
}  

 1.关联级别 立即检索: 
释义:就是设置有关联的类是否立即检索(查询),在set 配置节点中 添加 lazy=false.就表示立即检索, true 就表示 延迟检索,怎么判断呢? 
就从sql语句的打印中可以看出 
  立即检索: 在没有利用关联对象的时候,就执行了sql到数据库中将关联类给查询了一把.(是不是有点耗性能啊?) 
  延迟检索: 只有在你利用到关联对象的时候,才执行sql到数据库中 查询

//类级别关联 立即检索 Dept.hbm.xml: <set name="employees" lazy=false inverse=false> ...   
    public void testQueryRaload1(){  
        Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
        //这行这句话的时候  就 执行了两个sql 一个是 查询 Dept 一个是查询 Employee  (立即关联执行sql)  
        System.out.println("部门名称:"+dept.getDeptName());  
        System.out.println("开始检索关联的员工信息");  
        System.out.println("部门员工数量"+dept.getEmployees().size());  
    }

 1.关联级别 延迟检索: 
释义:默认就是 延迟检索 lazy=true 可以省略,只有在你利用到关联对象的时候,才执行sql到数据库中 查询

    //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
        public void testQueryRaload1(){  
            Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
            //执行这句话的时候  就 只执行一个sql 查询 dept  
            System.out.println("部门名称:"+dept.getDeptName());  
            System.out.println("开始检索关联的员工信息");  
            System.out.println("部门员工数量"+dept.getEmployees().size());  
            //执行上面的那句话之前  才执行 sql 去查询 employee   
        }  

 既然是延迟 是不是 又会出现 和 类级别中的延迟检索出现的一些类似特殊情况呢? 答案:是肯定的

    //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
            //session 关闭后 关联对象没有被初始化   
        public void testQueryRaload1(){  
            Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
            //执行这句话的时候  就 只执行一个sql 查询 dept  
            System.out.println("部门名称:"+dept.getDeptName());  
            System.out.println("开始检索关联的员工信息");  
            session.close(); //session 范围内没有访问对象  
            System.out.println("部门员工数量"+dept.getEmployees().size());  
                      
            //报错了,关联对象没有被初始化  
        }  
      
    //这个不会报错  
    //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
        //sesssion 关闭前 初始化关联对象  
        public void testQueryRaload1(){  
            Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
            //执行这句话的时候  就 只执行一个sql 查询 dept  
            System.out.println("部门名称:"+dept.getDeptName());  
            System.out.println("部门员工数量"+dept.getEmployees().size());  
            System.out.println("开始检索关联的员工信息");  
            session.close(); //session 范围内没有访问对象  
            System.out.println("部门员工数量"+dept.getEmployees().size());  
            //执行上面的那句话之前  才执行 sql 去查询 employee   
        }  

 3.关联级别 迫切左外连接检索: 
释义:将 set 节点的 out-join=true  就可以了,这个好像和 立即检索类似,只是将 原本的两个sql 变成 一个 left join 的查询   只查询了一次 只有一个sql语句

        //类关联级别  迫切左外连接查询. <set out-join="true" invers="true"  
        public void testQueryOutJoin(){  
            Dept dept =(Dept)session.load(Dept.class,new Integer(2));  
            //执行上面代码时 ,就会执行一条  left join 的sql 查询数据库   
            System.out.println("员工名称:"+dept.getDeptName());  
              
        }  

 转载:http://www.cnblogs.com/jifeng/archive/2013/03/03/2941189.html

分享到:
评论

相关推荐

    hibernate缓存机制

    Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...

    Hibernate缓存机制

    h​i​b​e​r​n​a​t​e​缓​存​机​制​,​你​必​须​学​的​持​久​层​技​术​。

    hibernate缓存机制分析共17页.pdf.zip

    《Hibernate缓存机制详解》 Hibernate,作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。其缓存机制是优化性能的关键组成部分,它减少了对数据库的直接访问,提高了数据处理效率。本文...

    Hibernate缓存机制,转载

    **标题:“Hibernate缓存机制,转载”** **描述:**这篇博客主要探讨了Hibernate框架中的缓存机制,包括一级缓存和二级缓存的概念、工作原理以及如何在实际开发中应用。 **标签:“源码 工具”** **知识点详解:*...

    Hibernate缓存机制.txt

    Hibernate缓存机制.txt

    Hibernate缓存机制探讨.doc

    ### Hibernate缓存机制详解 #### 一、概述 Hibernate 是一款流行的 Java 持久层框架,它简化了 Java 应用程序与数据库交互的过程。然而,直接使用 JDBC 访问数据库存在一定的性能开销。为了提升性能,Hibernate ...

    Hibernate缓存机制解说

    ## Hibernate缓存机制详解 ### 一、缓存分类与管理 Hibernate提供了两种主要的缓存类型:一级缓存和二级缓存。 #### 1. 一级缓存 一级缓存也称为Session缓存,它在同一个Session中对数据的多次读取操作只需要一...

    HIBERNATE的缓存机制

    Hibernate缓存机制是提高应用程序性能的关键特性,尤其是在频繁与数据库交互的应用中。缓存通过减少对物理数据库的直接访问次数,显著提升了数据读取和写入的速度。这主要是因为从缓存中读取数据比从数据库中获取更...

    Hibernate缓存机制探讨

    在配置Hibernate缓存时,需要明确哪些实体或查询结果应该缓存,并设置相应的缓存策略。例如,我们可以使用`@Cacheable`注解标记实体类,使用`@Cache`注解来定义缓存区域和策略。同时,对于查询结果的缓存,可以使用`...

    Hibernate缓存机制深入浅出

    Hibernate缓存介于Hibernate应用和数据库之间,缓存中存放了数据库数据的拷贝。 其作用是减少访问数据库的频率,从而提高应用的运行性能

    hibernate 缓存机制

    Hibernate的缓存机制是优化应用程序性能的关键组成部分,它通过存储数据副本减少对数据库的直接访问,从而提升系统响应速度。缓存主要分为两类:一级缓存(Session缓存)和二级缓存。 一级缓存是Hibernate的核心...

    hibernate缓存

    ### Hibernate缓存机制及优化策略 #### 一、概述 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域被广泛应用于数据库操作。它提供了丰富的缓存机制来提高应用性能并降低数据库访问压力。本文将...

    Hibernate缓存,性能优化

    综上所述,Hibernate缓存机制是提升应用性能的重要手段,通过合理配置缓存策略、优化查询方式、管理数据库连接以及实施有效的监控和调优措施,可以显著提高Hibernate应用的运行效率和用户体验。然而,缓存的使用并非...

    Hibernate缓存深入详解

    Hibernate缓存机制是其性能优化的核心组成部分,对于提高应用程序的运行效率至关重要。它位于Hibernate应用和数据库之间,减少了对数据库的直接访问,通过存储数据库数据的副本来加速数据检索。 **1. Hibernate缓存...

    Hibernate缓存

    2. Hibernate缓存机制.doc:这个文档应该详细解释了Hibernate的一级和二级缓存机制,包括缓存的生命周期、更新策略(如脏检查和锁机制)以及缓存失效策略。 3. osCache.doc:可能深入介绍了Oscache的高级特性和最佳...

Global site tag (gtag.js) - Google Analytics