Hibernate 正确的查询及优化方法
执行数据查询功能的基本方法有两种:一种是得到单个持久化对象的get()方法和load()方法,另一种是Query对象的list()方法和iterator()方法。
get()方法和load()方法的区别在于对二级缓存的使用上。load()方法会使用二级缓存,而get()方法在一级缓存没有找到的情况下会直接查询数据库,不会去二级缓存中查找。在使用中,对使用二级缓存的对象进行查询时最好使用load()方法,以充分利用二级缓存来提高检索的效率。
load()如果没有匹配的数据库记录,会抛出unrecoverable exception,如果类的映射使用了代理,load()方法返回一个未初始化的代理。
如果不确定匹配的数据是否存在于数据库,应该使用get()方法,它会立即访问数据库,如果没有结果返回null。
list()方法和iterator()方法之间的区别可以从以下几个方法来进行比较。
执行的查询不同
list()方法在执行时,是直接运行查询结果所需要的查询语句,而iterator()方法则是先执行得到对象ID的查询,然后再根据每个ID值去取得所要查询的对象。因此,对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句
缓存的使用
list()方法只能使用二级缓存中的查询缓存,而无法使用二级缓存对单个对象的缓存(但是会把查询出的对象放入二级缓存中)。所以,除非重执行相同的查询操作,否则无法利用缓存的机制来提高查询的效率。
iterator()方法则可以充分利用二级缓存,在根据ID检索对象的时候会首先到缓存中查找,只有在找不到的情况下才会执行相应的查询语句。所以,缓存中对象的存在与否会影响到SQL语句的执行数量。
对于结果集的处理方法不同
list()方法会一次获得所有的结果集对象,而且它会依据查询的结果初始化所有的结果集对象。这在结果集非常大的时候必须会占据非常多的内存,甚至会造成内存溢出的情况发生。
iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。因此在访问中可以控制缓存中对象的数量,以避免占用过多缓存,导致内存溢出情况的发生。使用iterator()方法的另外一个好处是,如果只需要结果集中的部分记录,那么没有被用到的结果对象根本不会被初始化。所以,对结果集的访问情况也是调用iterator()方法时执行数据库SQL语句多少的一个因素。
所以,在使用Query对象执行数据查询时应该从以上几个方面去考虑使用何种方法来执行数据库的查询操作。
抓取策略的选取
对于抓取策略的选取将影响到抓取关系对象的方式,也就是抓取关联对象时所执行的SQL语句。这就要根据实际的业务需求、数据的数量以及数据库的结构来进行选择了。
在这里需要注意的是,通常情况下都会在执行查询的时候针对每个查询来指定对其合适的抓取策略。制定抓取策略的方法如下所示:
User user = (User)session.createCriteria(User.class)
.setFetchMode("permissions",FetchMode.JOIN)
.add(Restrictions.idEq(userId))
.uniqueResult();
查询性能小结
在本小节中介绍了查询性能提升的方法,关键是如何通过优化SQL语句来提升系统的查询性能。查询方法和抓取策略的影响也是通过执行查询方式和SQL语句的多少来改变系统的性能的。这些都属于开发人员所应该掌握的基本技能,避免由于开发不当而导致系统性能的低下。
在性能调整中,除了前面介绍的执行SQL语句的因素外,对于缓存的使用也会影响系统的性能。通常来说,缓存的使用会增加系统查询的性能,而降低系统增加、修改和删除操作的性能(因为要进行缓存的同步处理)。所以,开发人员应该能够正确的使用有效的缓存来提高数据查询的性能,而要避免滥用缓存而导致的系统性能变低。在采用缓存的时候也应该注意调整自己的检索策略和查询方法,这三者配合起来才可以达到最优的性能。
另外,事务的使用策略也会影响到系统的性能。选取正确的事务隔离级别以及使用正确的锁机制来控制数据的并发访问都会影响到系统的性能。
如果想使用Hibernate API?
对于HibernateTemplate没有提供的功能,开发人员也可以直接调用HibernateDaoSupport对象的getSession()方法来得到Session对象的实例直接利用Hibernate所提供的原生API进行数据库的访问操作。
Hibernate 处理并发
自动版本化—Hibernate能够自动进行乐观并发控制,如果在用户思考的过程中发生并发修改冲突,Hibernate能够自动检测到。
托管对象—如果你决定采用前面已经讨论过的session-per-request模式所有载入的实例在用户思考的过程中都处于与Session脱离的状态。Hibernate允许你把与Session脱离的对象重新关联到Session上,并且对修改进行持久化,这种模式被称为自动版本化被用来隔离并发修改。
长生命周期的Session—Hibernate的Session可以在数据库事务提交之后和底层的JDBC连接断开,当一个新的客户端请求到来的时候,它又重新连接上底层的JDBC连接。这种模式,这种情况可能会造成不必要的Session和JDBC连接的重新关联。自动版本化被用来隔离并发修改。
大批量数据库操作的话,最好考虑使用存储过程。
Spring AOP支持的通知类型:
前置通知(Before advice)
前置通知是指在某个连接点方法之前执行的通知。如果通知不抛出异常那么该连接点就一定会被执行。
返回后通知(After returning advice)
返回后通知是指在某个连接点方法正常完成(没有抛出异常)后执行的通知。
抛出异常后通知(After throwing advice)
抛出异常后通知是指在连接点方法抛出异常退出时执行的通知
后置通知(After advice)
后置通知是指无论在任何情况下连接点方法退出时执行的通知,也就是说无论连接点方法正常退出还是抛出异常退出都会执行此通知。
环绕通知(Around advice)
环绕通知是指包围连接点方法的通知。这种通知的功能非常强大,可以替代前面任意一种通知的功能
分享到:
相关推荐
linux 对于性能优化随笔所记整理,程序性能优化是开发产品稳定阶段追求的一个方便,对于产品提升的一个重要内容,有别于应届开发的一个方便
2020年托班教师教育随笔让幼儿学会整理图书.pdf
很抱歉,但根据您给出的信息,标题和描述中提到的是"网恋随笔散文随笔散文.rar",这明显与IT行业知识不相符,而更倾向于文学或个人创作。标签虽为"教育",但没有具体的IT教育相关知识点。压缩包子文件的文件名称列表...
工程数学软件实用入门资料,可视很好,不需要专门的语言。
"散文随笔【黄牛散文随笔】.rar" 是一个压缩文件,其中包含了由作者“黄牛”创作的散文随笔集合。这个标题指示我们,这是一份文学作品,主要涵盖了散文和随笔这两种文体,可能包含作者对生活、社会、自然等各方面的...
关于描写夏天的散文随笔.doc
根据给定文件的信息,我们可以提炼出以下几个主要的知识点: ### 1. 幼儿教育的重要性 - **基础知识**:从婴幼儿出生到成长的过程是不断进步发展的。幼儿园阶段是这一过程中的重要环节,它不仅关系到孩子们的身体...
一年级数学第一学期教学随笔.pdf
关于小学一年级数学下册教学随笔.docx
"Java完整随笔(学习)"可能包含了一系列关于Java编程的基础到高级概念的笔记,是学习Java的好资源。以下是一些可能涵盖的重要知识点: 1. **Java基础**:这部分可能包括了Java的基本语法,如变量、数据类型、...
信息技术教学随笔主要探讨了如何在信息技术教学中应对教材陈旧和激发学生兴趣的问题。作者指出,信息技术学科因其快速发展,教学内容应及时更新,以适应不断变化的信息环境。针对使用过时教材的情况,教师采取了以下...
【小忆故乡随笔】是一本以回忆故乡为主题的随笔集,主要涵盖了作者对家乡的点滴记忆、情感体验以及对乡土文化的深刻洞察。这不仅是一部文学作品,也是一份珍贵的文化记录,对于读者来说,它既能够带来阅读的愉悦,也...
有关家风的经典散文随笔.doc
散文随笔【黄牛散文随笔】.pdf
"散文随笔【人间五月散文随笔】.rar" 这个标题表明这是一款压缩文件,格式为RAR,其中包含了名为“人间五月散文随笔”的散文集。"人间五月"可能指的是散文的主题或者创作的时间背景,与春天、生机、生活等元素相关。...
二年级数学上册的教学随笔.docx
"心情日记随笔参考" 本文是关于心情日记随笔的参考文献,包含四篇随笔,每篇都是作者对生活中的感悟和思考。通过这些随笔,我们可以看到作者对生活的热爱和感恩,对梦想的追求和信念。 第一篇:心情日记随笔 这篇...
最新小学二年级道德与法治教学随笔.pdf
这篇教学随笔主要探讨了以下几个方面: 首先,教师需要认识到一年级学生的特点,他们活泼好动,注意力维持时间较短。因此,创设有趣、富有吸引力的教学情境至关重要。例如,通过设立小奖励,如小红旗、小红花等,...
由于提供的文件信息【标题】、【描述】、【标签】和【部分内容】内容都是一些特殊符号和乱码,而非实际有效文字信息。这样的信息无法用来生成具体的IT知识点。IT知识需要有明确的、有意义的上下文内容作为基础,例如...