`

hibernate 缓存相关知识点

阅读更多

Hibernate延迟加载实现原理

http://www.iteye.com/topic/296845

 

通过将class的lazy属性设置为true,来开启实体的延迟加载特性。如果我们运行下面的代码:
  User user=(User)session.load(User.class,"1");(1)
  System.out.println(user.getName());(2)


   当运行到(1)处时,Hibernate并没有发起对数据的查询,如果我们此时通过一些调试工具(比如Eclipse的Debug工具),观察此时user对象的内存快照,我们会惊奇的发现,此时返回的可能是User$EnhancerByCGLIB$$bede8986类型的对象,而且其属性为null,这是怎么回事?session.load()方法会返回实体对象的代理类对象,这里所返回的对象类型就是User对象的代理类对象。在Hibernate中通过使用CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显示的内存快照,我们可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当代码运行到(2)处时,此时调用user.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用CGLIB$CALBACK_0.getName()方法,当调用该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select * from user where id=’1’;来查询数据,并构造目标对象,并且将它赋值到CGLIB$CALBACK_0.target属性中。

 

    这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。

 

Hibernate 缓存及其原理

 

Hibernate 中Java对象的状态

临时态:session中无,数据库中也无。

持久态:session中有,数据库中也有

游离态:session中无,数据库中可能有。

 

  1.临时状态 (transient)

  特征:

  1】不处于Session 缓存中

  2】数据库中没有对象记录

  Java如何进入临时状态

  1】通过new语句刚创建一个对象时

  2】当调用Session 的delete()方法,从Session 缓存中删除一个对象时。

  2.持久化状态(persisted)

  特征:

  1】处于Session 缓存中

  2】持久化对象数据库中设有对象记录

  3】Session 在特定时刻会保持二者同步

  Java如何进入持久化状态

  1】Session 的save()把临时-》持久化状态

  2】Session 的load(),get()方法返回的对象

  3】Session 的find()返回的list集合中存放的对象

  4】Session 的update(),saveOrupdate()使游离-》持久化

  3.游离状态(detached)

  特征:

  1】不再位于Session 缓存中

  2】游离对象由持久化状态转变而来,数据库中可能还有对应记录。

  Java如何进入持久化状态-》游离状态

  1】Session 的close()方法

  2】Session 的evict()方法,从缓存中删除一个对象。提高性能。少用。

 

缓存原理:

 

     1 hibernate 只对实体对象缓存,不对属性级别缓存;

     2 如果启用了二级缓存,则所有通过hibernate查询到的实体对象都将被缓存到二级缓存;二级缓存的形式为 {key:value,...}形式的hash结构,其中key是实体的主键,value是实体对象。发生查询时,首先获取目标数据的所有id,然后拿这些id去二级缓存中找,找不到就通过id查数据库,所以有可能会出现查询实体对象*N+1问题;

     3 如果启用了查询缓存,则所有通过hibernate查询到的实体对象都将被缓存到二级缓存和查询缓存,查询缓存的形式为 {key:value,...}形式的hash结构,其中key是hql查询语句,value是实体的主键集合。发生查询时,如果查询字符串与缓存的查询串完全匹配,则用缓存的id去二级缓存中找,找不到就 通过id查数据库,所以有可能会出现查询实体对象*N+1问题;

     4 查询缓存的失效控制是以数据表为粒度的,只要数据表中任何一条记录发生改变,整个表相关的所有查询缓存就都无效了;(题外话:这和数据库的查询缓存失效策略是一致的)

     5 二级缓存和查询缓存的是否失效都由hibernate维护,如果不通过hibernate改变了缓存涉及到的数据库数据,则缓存不可能正确;

     6 对于写操作频繁的系统,必须设置严格的缓存并发策略,在这种情况下,二级缓存和查询缓存对提升数据访问性能的贡献有限,并且仍然存在数据藏读的可能。

     7 默认情况下,hibernate不缓存子对象,可以通过配置开启;

 

分享到:
评论

相关推荐

    Hibernate 培训.pdf

    Hibernate 培训.pdf,大体介绍hibernate的关键知识点,供大家交流。 1、什么是Hibernate? 2、ORM是什么? 3、Hibernate核心接口 4、对象关联 5、对象状态 6、Hibernate查询 7、Hibernate events and ...

    Hibernate实战(第2版 中文高清版)

     13.3.2 Hibernate高速缓存架构   13.4 高速缓存实践   13.4.1 选择并发控制策略   13.4.2 理解高速缓存区域   13.4.3 设置本地的高速缓存提供程序   13.4.4 设置重复的高速缓存   13.4.5 控制二级高速...

    Java求职面试宝典各大公司常考知识点

    1.9. hibernate如何管理缓存 4 1.10. 使用Hibernate的优点: 6 1.11. Hibernate是如何延迟加载? 6 1.12. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 6 1.13. Hibernate的查询方式 7 1.14. 如何...

    从J2SE到J2EE知识点介绍

    (八) 复合自然主键实例(源代码hibernate_0500) 218 (九) Hibernate的类型 224 1. Java基本值类型的Hibernate映射 224 2. Java时间和日期类型的Hibernate映射类型 224 3. Java大对象类型的Hibernate映射类型 225 4....

    2021年最新java面试题--视频讲解(内部培训84个知识点超详细).rar

    Java面试题58:hibernate的缓存 Java面试题59.webservice的使用场景 Java面试题60.activiti的简单介绍 Java面试题61.linux的使用场景 Java面试题62.linux常用命令 Java面试题63:怎么操作linux服务器 Java面试题64:...

    JessMA Java Web 应用开发框架 (v3.2.2-20130815).pdf

    6) 平缓的学习曲线:学习使用JessMA只需掌握一定的Core Java与JSP/Servlet知识,本开发手册会循序渐进阐述每个知识点,每个知识点都会结合完整的示例进行讲述,知识点之间前后呼应,确保学习者在学习时温故知新,...

    Java-Interview-Tutorial:建议star持续更新ing!!!BAT华为工程师四年磨一剑精心编排【Java高级工程师及架构师技能&面试宝典】:数据库、缓存、大数据、机器学习、设计模式、Docker、K8s、RPC、分布式微服务架构相关框架中间件原理及电商互联网下的业务实践

    按照现有计划,主要研究如下方面知识点: Java SE重难点、包含但不限于集合、多线程、泛型、反射、I/O; Java Web重难点,包含但不限于Servlet、JSP、Tomcat、Jetty ; Java EE开发流行框架,包含但不限于Spring、...

    iBATIS实战

    书的最后给出了一个设计优雅、层次清晰的示例程序JGameStore,该示例涵盖全书的大部分知识点,可以作为iBATIS学习和Web开发的经典案例,非常值得深入研究。 本书既可为广大的开发人员(不仅仅是Web应用程序开发人员)...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    而越来越多专业知识的 Blog 的出现,让我们看到了 Blog 更多所蕴涵的巨大的信息价值:不同的 Blog 选择不同的内容,收集和整理成为很多人关注的专业 Blog ——目前越来越多的人获取信息的来源是一些固定的 Blog 。...

    java开源包1

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包11

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包2

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包3

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包6

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包5

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包10

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包4

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包8

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包7

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

    java开源包9

    该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存...

Global site tag (gtag.js) - Google Analytics