Hibernate优化问题

来源:互联网 发布:无法连接windows系统 编辑:程序博客网 时间:2024/06/01 09:49

 Hibernate优化问题
 合理使用延迟加载
 选择session.load() 使用代理机制(cglib动态代理,cglib存在bug,hibernate3.3以上使用了jboss公司的javassist)
 选择session.get()
 抓取策略(一次全部取出,避免N+1)
 在HQL语句中使用抓取连接查询,通过写一条left join fetch 语句把相关联的两个实体的数据一次性从数据库中加载上来。这样可以在特定情况下(同时需要使用到这两个实体的数据)减少SQL的数量来提高查询效率
 Query.iterate()和Query.list()的选择
Query.iterate{
1:select id from Student s
N:select s from Stuent where s.id=?
}
支持从一级缓存和二级缓存中取数据,但是可能导致N+1问题,假如缓存中没有数据,iterate方法会发送一条SQL将所有数据的id查询出来放到缓存中,当迭代使用对象的时候会再发送N条SQL语句根据id查询对象。不过已查询出的对象会被放入一级缓存和二级缓存中,当第二次再访问该对象的时候会直接从缓存中取。
Query.list {
select s from Student s;
}
不支持从一级缓存和二级缓存中取数据,但是查询结果会被放入一级缓存和二级缓存中,每一次查询都会从数据库中,除非使用了查询缓存,使用了查询缓存,list方法会从查询缓存中取数据。
 缓存管理
 一级缓存(Session cache)生命周期和Session相同,存储对象
 Session级别的缓存由hibernate自动管理。当应用程序调用Session的CRUD方法及调用查询接口的list(),iterate()等方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把改对象加入到Session缓存中。如果在Session缓存中已经存在这个对象,就不需要再去数据库加载而是直接使用缓存中的这个对象,可以减少访问数据库的频率,提高程序的运行效率。当Hibernate清理缓存时(默认是提交事务的时候),Hibernate会根据缓存中对象的状态来同步数据库中的数据状态,在关闭Session时,会清空Session缓存中的所有对象。一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict(Object obj):从缓存中清除指定的持久化对象。clear():清空缓存中所有持久化对象。flush(): 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务。commit():先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。当做批量插入或批量更新时,必须通过经常调用Session的flush()以及稍后调用clear()来控制一级缓存的大小,这样内存才能保证足够的空间。
 二级缓存(SessionFactory cache)生命周期和SessionFactory相同,存储对象
 执行条件查询的时候,发出“select * from table_name where …”这样的SQL语句查询数据库,一次获得所有的数据对象。把获得的所有数据对象根据ID放入到二级缓存中。当Hibernate根据ID访问数据对象时,首先从Session缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;还没查到,再查询数据库,把结果按照ID放入到二级缓存。删除、更新和增加数据的时候,同时会更新到二级缓存中。Hibernate的二级缓存策略是针对ID查询的缓存策略,对于调节查询则毫无作用。为此,hibernate提高了单独针对条件查询的查询缓存。适合存放到二级缓存中的数据有:很少被修改的数据。不是很重要的数据,允许出现偶尔的并发的数据。很多系统模块都要用到不是私有的数据,是共享的什么样的数据不适合放在二级缓存中???财务数据 安全性的数据 也就是不想让别人看到的数据和特别重要的数据
 查询缓存(Query cache)存储对象的普通属性、对象id,当查询缓存关联的表中数据发生变动时查询缓存消失,当使用查询缓存之后,query.list()会从query cache中取数据,减少SQL语句的发送。
 控制SQL语句的发出粒度(i/o)(查询数据,数据量庞大最好分页查询,调整每页显示的数量)
 拼装HQL最好使用问号方式
 配置inservse/mappedBy

0 0
原创粉丝点击