`
myreligion
  • 浏览: 205385 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

想设计一种实用的有效的hibernate查询缓存设计,欢迎讨论

    博客分类:
  • Java
阅读更多
  1. hibernate 自带缓存的情况介绍

hibernate 提供了两种缓存,一个是基于对象主ID 的一级缓存和一个为缓存查询结果而设计的二级缓存(姑且叫作查询缓存),一级缓存是默认开启的, 而且似乎也是很难关闭的;查询缓存默认是关闭的,而在我的印象中则一直觉得这个东西是 没有价值的 ,至今没有看到典型的使用案例和使用模式。<o:p></o:p>

hibernate 提供的查询缓存,默认会去cache 所有的查询请求,而这对于常用的系统而言是完全没有必要的。大多数真正需要缓存的应用场景,往往是 数据量庞大,交互操作较多的系统,而一般真正需要缓存的数据只有少量的查询,如果所有的查询都缓存,缓存的效率会大大降低而且会浪费很多内存,可能效率还 不如不用缓存。例如javaeye 论坛的版面帖子列表,我们希望缓存的往往也就是每一个版的第12 页帖子,如果用户翻老帖子,则不去缓存。这种场景应该 是经常用到的缓存场景,而hibernate 查询缓存恰恰不能自动做到,这个就是我们将要讨论解决的问题。

  1. 我们会用多少的查询缓存?

一级缓存HibernateTemplate 只有load()get() 方法才会使用,如果您用的是list(..;) 或者其他的方法都是不缓存的。如果您的系统有内容审核这么一说(如只有审核通过的才能对外显示,删除的不对外显示等等),即使是提取一个帖子(可以用get() 的情形),你们组程序员提取数据的语句一般也会写成list(from XXXX where id = … and 状态 = 审核通过的) ,以图方便或者为了数据库连接可以为readonly 事务,这样hibernate 仅有的一级缓存也会被跳过,您的查询语句都是没有缓存的!这时候一个有效的查询缓存将会给你的系统带来巨大的性能提升。<o:p></o:p>

  1. 一般的应用场景与通用的查询缓存应该具备的功能

缓存的使用目的是为了提供性能,缓存的使用后果是数据将会有延迟。如果我们决心使用缓存,一般的应用场景应该具有如下特点:事务要求低,数据实时性要求低,并发量要求高,系统可扩展性要求高,机器硬件成本要求低,总之非常适合大面积的空间换时间设计方法并且对数据的完整/ 准确度要求不高。<o:p></o:p>

缓存还应该是通用的,应用系统只要配置下即可使用;不能每个系统都单独开发,这样也就没有讨论的意义了。<o:p></o:p>

对于要缓存的东西,往往应用本身而且只有应用本身了解什么情况下需要缓存,所以查询缓存应该提供接口,由应用提供解释,来描述哪些查询是需要缓存的,哪些是不需要缓存的。如对于论坛的版面帖子列表,应用可以告诉缓存模块:Java 版缓存第12 页的帖子,回收站不做缓存,其他版面缓存第1 页帖子列表,如果用户是登录用户则所有版面的帖子列表都不做缓存;只有这样才能真正的提高缓存的效率,降低缓存成本。<o:p></o:p>

  1. 一种基于域对象的缓存实现方式

针对前面的描述,偶做了一个实现,基于annotation 的定义(当然可以基于xml 配置或者基于数据库,然后可以在线的调试配置参数达到最优)。定义如下:

java 代码
  1. @SuppressWarnings ( "serial" )
  2. @Entity
  3. @Cachable (interval=5)
  4. @UniqueCondition (combine = "id=?::limit=2000;word=?::limit=2000" )
  5. @QueryCondition (combine = "categoryId=?::limit=30::orderBy=id desc, parentCategoryId=?&&status=10" )
  6. public class SomeObject {
  7. private int id ;
  8. /**状态*/
  9. private int status ;
  10. private double symbolLength ;
  11. private String word ;
  12. private String symbol ;
  13. private int categoryId ;
  14. private int clickCount ;
  15. private int parentCategoryId ;
  16. @Id
  17. @GeneratedValue (strategy=GenerationType.AUTO)
  18. public int getId() {
  19. return id;
  20. }
  21. public void setId( int id) {
  22. this .id = id;
  23. }
  24. public String getSymbol() {
  25. return symbol;
  26. }
  27. public void setSymbol(String ipa) {
  28. this .symbol = ipa;
  29. }
  30. @QueryConditionIgnoreParseField
  31. public double getSymbolLength() {
  32. return symbolLength;
  33. }
  34. public void setSymbolLength( double length) {
  35. this .symbolLength = length;
  36. }
  37. public String getWord() {
  38. return word;
  39. }
  40. public void setWord(String word) {
  41. this .word = word;
  42. }
  43. public String authSignature() {
  44. return null ;
  45. }
  46. public int getCategoryId() {
  47. return categoryId;
  48. }
  49. public void setCategoryId( int categoryId) {
  50. this .categoryId = categoryId;
  51. }
  52. @CacheIngoreUpdateField
  53. public int getClickCount() {
  54. return clickCount;
  55. }
  56. public void setClickCount( int clickCount) {
  57. this .clickCount = clickCount;
  58. }
  59. public int getParentCategoryId() {
  60. return parentCategoryId;
  61. }
  62. public void setParentCategoryId( int parentCategoryId) {
  63. this .parentCategoryId = parentCategoryId;
  64. }
  65. public int getStatus() {
  66. return status;
  67. }
  68. public void setStatus( int status) {
  69. this .status = status;
  70. }
  71. }

 

 

各项定义解释:

  • <!----> <!---->Cachable ,指定这个实体是要进行缓存的。interval=5 ,表示对象cache 5 秒失效。
  • <!----> <!---->QueryCondition 为一般的查询缓存,指定那些条件下进行结果集cache ,如此处就是说当条件为cateogory= 某一个值,并且按照id desc 进行排序时cache 查询记录的前30 条(如果一页显示15 条,则缓存第12 页,第345 。。。不做缓存)。或者当条件为parentCategoryId=? 并且status=10 进行缓存,缓存不考虑排序字段,并且缓存所有结果。
  • <!----> <!---->UnqiueConditon ,指定对象的唯一性条件,当满足这个条件时可以保证数据库只有一个对象,常见情形如用户表的username, nickNameid 等。此处按照id 查询时进行缓存,最多缓存2000 条记录;如果按照word 字段进行查询,也进行缓存,最多缓存2000 条记录。如对于查询条件 id = 134343 and status = 10 ;cache 分析出含有记录唯一保证的字段idstatus 就可以暂时忽略,先通过id=134343cache 中读取记录,然后在利用好比反射的方 法查看对象的status 是否为10 ,如果是,就直接对象,不是返回null ;保证同一个对象尽量占用同样的cache 位置。
  • <!---->CacheIngoreUpdateField 这个表示忽略的更新字段。因为clickCount 用户每次打开都会更新+1 ,如果此时刷新cachecache 也就可以撤消了。所以我们通过定义 这个标记,如果某一个update 操作只是更新了clickCount 字段,只更新数据库,cache 依然有效不做更新。等到Cachable 标记的 interval 让对象失效以后再更新,保证cache 的低刷新频率。
  • <!----> <!---->QueryConditionIgnoreParseField 表示此字段不参与是否需要cache 的匹配,如此处的symbolLength ,只要标记了@ QueryConditionIgnoreParseField ,无论查询条件中有没有symbolLength 条件,都不影响查询缓存决定当前查询是否需要做缓存。
  • <!----> <!---->Entity hibernate 的标记。


----编辑器看到的效果好像和显示的不一样,一直排不对版面:(

分享到:
评论
2 楼 bulargy 2008-03-21  
很好很强大。。。学习了~~~
1 楼 ydw9527 2008-01-05  
楼主,第4点中的如何使用呢?难道在POJO里加上annotation就行了? 初学中,请指教

相关推荐

    hibernate3.5.0官方手册

    ORM,即对象关系映射,是Java开发中用来解决数据库操作与面向对象编程之间差异的一种技术。Hibernate作为Java领域最流行的ORM框架之一,它简化了数据库操作,让开发者可以更加专注于业务逻辑而不是底层的SQL查询。 ...

    hibernate5.0中文文档

    查询语言方面,文档会详细讲解HQL(Hibernate Query Language),这是一种面向对象的查询语言,类似于SQL,但更贴近Java编程。同时,还会涉及Criteria API,它是另一种动态构建查询的方式,提供了更强大的查询构造...

    一个好的hibernate源代码有server2008数据库

    6. **开发实践**:使用Hibernate进行开发时,需要注意实体类的设计,属性与数据库字段对应,还要编写HQL(Hibernate查询语言)或使用Criteria API来执行查询操作。 7. **性能优化**:Hibernate提供了缓存机制、...

    深入浅出Hibernate

    7.缓存机制:讲解Hibernate的缓存策略,包括一级缓存、二级缓存以及查询缓存,以及如何优化缓存性能。 8. 继承映射:探讨如何处理类继承关系在数据库中的映射,包括单表继承、联合继承和表-per-hierarchy等策略。 ...

    Hibernate In Action中文版

    6. Criteria API和CriteriaBuilder:提供了一种动态构建查询的方式,避免硬编码HQL,使得代码更具有可读性和可维护性。 7. Criteria API的高级用法:包括限制查询结果、分页、投影、关联查询、子查询等。 8. ...

    Hibernate in action 中文版 完整版 pdf

    4. 高级特性:深入讨论了懒加载、级联操作、缓存机制(一级缓存和二级缓存)、延迟加载和代理对象等高级特性,帮助读者理解Hibernate的内部工作原理。 5. 查询优化:分析了HQL和SQL的性能差异,介绍了如何使用...

    孙卫琴.精通Hibernate.zip

    除此之外,作者还详细讨论了Hibernate的缓存机制,包括第一级缓存和第二级缓存,以及查询缓存。缓存的合理使用能够大大提高应用程序的性能,减少数据库的负载。 在性能优化方面,书中提到了批处理操作、延迟加载、...

    Hibernate学习笔记

    6. **查询语言HQL**:介绍Hibernate查询语言(HQL),一种面向对象的查询语言,与SQL类似但更适应面向对象的编程。讲解基本查询、条件查询、聚合函数、子查询等。 7. ** Criteria API**:探讨Criteria API,它是另...

    2017黑马程序员第一天Hibernate讲义,笔记,源码

    6. **缓存机制**:Hibernate提供了一级缓存(Session级别的)和二级缓存(SessionFactory级别的),提高了数据读取效率。 7. **对象状态**:Hibernate区分了瞬时、持久化、托管和脱管四种对象状态,理解这些状态...

    HIBERNATE参考手册

    7. **第二级缓存**:讨论Hibernate的缓存策略,包括查询缓存和更新缓存,以及如何配置和使用第三方缓存提供商(如Ehcache)。 8. **性能优化**:提供各种性能优化技巧,如批处理操作、延迟加载、懒加载、集合的优化...

    Hibernate电子书

    6. **HQL与SQL**:介绍Hibernate Query Language(HQL),一种面向对象的查询语言,以及如何与原生SQL配合使用,进行复杂查询。 7. **关联映射**:讨论一对一、一对多、多对一、多对多等不同类型的关联映射,以及懒...

    Hibernate开发指南___夏昕

    “Hibernate高级特性”章节则进一步探讨了XDoclet与Hibernate映射、数据检索(包括CriteriaQuery和HQL)、数据关联(如一对一、一对多、多对多关系处理)、数据访问(PO和VO的使用)、事务管理、锁机制、分页、缓存...

    hibernate或nhibernate文档

    2. 工作原理:Hibernate通过XML或注解配置来定义对象和表之间的映射关系,提供了一种透明的对象存储机制。 3. 主要组件:包括SessionFactory、Session、Query等核心接口,以及Criteria、HQL(Hibernate查询语言)等...

    Hibernate3.6中文文档

    文档会介绍HQL(Hibernate Query Language),这是一种面向对象的查询语言,类似于SQL但更适应于对象模型。此外,它还会讲解Criteria API和Detached Criteria,提供更加灵活的查询方式。同时,不要忘记,文档还会...

    Hibernate3.2官方中文参考手册

    此外,还会有Criteria API的使用方法,这是一种更强大的、类型安全的查询方式。同时,手册也会涵盖 Criteria、DetachedCriteria 和 QueryOver 等高级查询技术。 事务处理和缓存策略是Hibernate的另一个关键领域。...

    hibernate3.2最少依赖的包

    4. **dom4j.jar**:DOM4J是一个Java的XML API,提供了一种灵活的处理XML文档的方式,用于解析和构建XML文档,Hibernate的XML配置文件处理就依赖它。 5. **slf4j-api.jar** 和 **slf4j-log4j12.jar**:Simple ...

    夏昕-Hibernate 开发指南.pdf

    1. **Hibernate简介**:Hibernate是一种开源的ORM框架,通过将Java类与数据库表进行映射,使得开发者可以使用面向对象的方式来操作数据库,降低了数据库编程的复杂性。它支持多种数据库,如MySQL、Oracle等,并提供...

    使用Hibernate开发租房系统7-11

    Hibernate提供了一种直观的方式来执行这些基本操作,如`save()`, `update()`, `delete()`以及各种查询方法。此外,HQL(Hibernate查询语言)和Criteria API也是进行复杂查询的重要工具。 `Chapter11`可能涉及了事务...

    Hibernate资料包

    4. **查询语言(HQL)**:介绍Hibernate查询语言,一种面向对象的查询方式,与SQL类似但更灵活。 5. ** Criteria API**:提供一种更面向对象的查询方式,避免硬编码SQL,支持动态构建查询。 6. **Criteria API与...

    西安野马计算机培训学校HIBERNATE讲义

    在学习过程中,可以结合【JPA.ppt】这个文件,它是关于Java Persistence API的补充资料,JPA是另一种ORM规范,与Hibernate有密切联系。通过对比学习,可以更深入理解两者之间的异同,以及在实际项目中如何选择和使用...

Global site tag (gtag.js) - Google Analytics