随笔 以后整理

[size=x-large][color=red][b]Hibernate 正确的查询及优化方法[/b][/color][/size]
执行数据查询功能的基本方法有两种:一种是得到单个持久化对象的get()方法和load()方法,另一种是Query对象的list()方法和iterator()方法。
get()方法和load()方法的区别在于对二级缓存的使用上。load()方法会使用二级缓存,而get()方法在一级缓存没有找到的情况下会直接查询数据库,不会去二级缓存中查找。在使用中,对使用二级缓存的对象进行查询时最好使用load()方法,以充分利用二级缓存来提高检索的效率。
load()如果没有匹配的数据库记录,会抛出unrecoverable exception,如果类的映射使用了代理,load()方法返回一个未初始化的代理。
如果不确定匹配的数据是否存在于数据库,应该使用get()方法,它会立即访问数据库,如果没有结果返回null。
list()方法和iterator()方法之间的区别可以从以下几个方法来进行比较。
[b]执行的查询不同[/b]
list()方法在执行时,是直接运行查询结果所需要的查询语句,而iterator()方法则是先执行得到对象ID的查询,然后再根据每个ID值去取得所要查询的对象。因此,对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句
[b]缓存的使用[/b]
list()方法只能使用二级缓存中的查询缓存,而无法使用二级缓存对单个对象的缓存(但是会把查询出的对象放入二级缓存中)。所以,除非重执行相同的查询操作,否则无法利用缓存的机制来提高查询的效率。
iterator()方法则可以充分利用二级缓存,在根据ID检索对象的时候会首先到缓存中查找,只有在找不到的情况下才会执行相应的查询语句。所以,缓存中对象的存在与否会影响到SQL语句的执行数量。
[b]对于结果集的处理方法不同[/b]
list()方法会一次获得所有的结果集对象,而且它会依据查询的结果初始化所有的结果集对象。这在结果集非常大的时候必须会占据非常多的内存,甚至会造成内存溢出的情况发生。
iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。因此在访问中可以控制缓存中对象的数量,以避免占用过多缓存,导致内存溢出情况的发生。使用iterator()方法的另外一个好处是,如果只需要结果集中的部分记录,那么没有被用到的结果对象根本不会被初始化。所以,对结果集的访问情况也是调用iterator()方法时执行数据库SQL语句多少的一个因素。
所以,在使用Query对象执行数据查询时应该从以上几个方面去考虑使用何种方法来执行数据库的查询操作。
[b]抓取策略的选取[/b]
对于抓取策略的选取将影响到抓取关系对象的方式,也就是抓取关联对象时所执行的SQL语句。这就要根据实际的业务需求、数据的数量以及数据库的结构来进行选择了。
在这里需要注意的是,通常情况下都会在执行查询的时候针对每个查询来指定对其合适的抓取策略。制定抓取策略的方法如下所示:
User user = (User)session.createCriteria(User.class)
.setFetchMode("permissions",FetchMode.JOIN)
.add(Restrictions.idEq(userId))
.uniqueResult();
[b]查询性能小结[/b]
在本小节中介绍了查询性能提升的方法,关键是如何通过优化SQL语句来提升系统的查询性能。查询方法和抓取策略的影响也是通过执行查询方式和SQL语句的多少来改变系统的性能的。这些都属于开发人员所应该掌握的基本技能,避免由于开发不当而导致系统性能的低下。
在性能调整中,除了前面介绍的执行SQL语句的因素外,对于缓存的使用也会影响系统的性能。通常来说,缓存的使用会增加系统查询的性能,而降低系统增加、修改和删除操作的性能(因为要进行缓存的同步处理)。所以,开发人员应该能够正确的使用有效的缓存来提高数据查询的性能,而要避免滥用缓存而导致的系统性能变低。在采用缓存的时候也应该注意调整自己的检索策略和查询方法,这三者配合起来才可以达到最优的性能。
另外,事务的使用策略也会影响到系统的性能。选取正确的事务隔离级别以及使用正确的锁机制来控制数据的并发访问都会影响到系统的性能。

[size=x-large][color=red][b]如果想使用Hibernate API[/b][/color]?[/size]
对于HibernateTemplate没有提供的功能,开发人员也可以直接调用HibernateDaoSupport对象的getSession()方法来得到Session对象的实例直接利用Hibernate所提供的原生API进行数据库的访问操作。

[size=x-large][b][color=red]Hibernate 处理并发[/color][/b][/size]
自动版本化—Hibernate能够自动进行乐观并发控制,如果在用户思考的过程中发生并发修改冲突,Hibernate能够自动检测到。
托管对象—如果你决定采用前面已经讨论过的session-per-request模式所有载入的实例在用户思考的过程中都处于与Session脱离的状态。Hibernate允许你把与Session脱离的对象重新关联到Session上,并且对修改进行持久化,这种模式被称为自动版本化被用来隔离并发修改。
长生命周期的Session—Hibernate的Session可以在数据库事务提交之后和底层的JDBC连接断开,当一个新的客户端请求到来的时候,它又重新连接上底层的JDBC连接。这种模式,这种情况可能会造成不必要的Session和JDBC连接的重新关联。自动版本化被用来隔离并发修改。
大批量数据库操作的话,最好考虑使用存储过程。

[size=x-large][color=red][b]Spring AOP支持的通知类型[/b]:[/color][/size]

[b]前置通知(Before advice)[/b]
前置通知是指在某个连接点方法之前执行的通知。如果通知不抛出异常那么该连接点就一定会被执行。
[b]返回后通知(After returning advice)[/b]
返回后通知是指在某个连接点方法正常完成(没有抛出异常)后执行的通知。
[b]抛出异常后通知(After throwing advice)[/b]
抛出异常后通知是指在连接点方法抛出异常退出时执行的通知
[b]后置通知(After advice)[/b]
后置通知是指无论在任何情况下连接点方法退出时执行的通知,也就是说无论连接点方法正常退出还是抛出异常退出都会执行此通知。
[b]环绕通知(Around advice)[/b]
环绕通知是指包围连接点方法的通知。这种通知的功能非常强大,可以替代前面任意一种通知的功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值