文档章节

Hibernate 优化策略

Zero零_度
 Zero零_度
发布于 2015/07/23 16:08
字数 1286
阅读 26
收藏 0
最近需要对项目的持久层进行优化,阅读了《深入浅出Hibernate》其中提出的提高性能方案总结如下:
  1. DAO层与业务层独立;

  2. 使用最新版Hibernate;

  3. 设定合理的批处理参数(batch_size);

  4. 尽量使用延迟加载特性;

  5. 采用合理的Session管理机制;

  6. 制定合理的缓存策略;

Session控制

为了避免session创建的开销,需要对session的创建进行控制。 控制方法1)使用ThreadLocal的方式控制session的创建。2)并且使用filter的方式创建和关闭session,这样一个用户操作只需要使用一个Session。但需要对Session的开关进行良好的管理。 

延迟加载

lazy_load,所有有关数据关联(一对多,多对多等)的映射都需要指定延迟加载。因为当前系统的session关闭是在filter里面做的,所以不需要控制关联对象的加载。在特殊的情况下,比如session关闭后获取关联对象,可以在session关闭前调用Hibernate.initialize()API获取关联对象。 

事务控制

针对hibernate由三种dao操作 find save flush, find即查询不需要开事务,所以可以考虑针对查询不使用事务控制。针对saveOrUpdate使用事务, 现在事务提交是在filter结束的时候去做,但有一些action中是不需要事务的,频繁开关事务可能会带来一定的系统开销。 

事务的开关最好限定在方法内部,可以考虑在service方法中开关事务,可以避免这个问题。session关闭和事务提交的时候,hibernate会主动调用flush方法进行数据库同步。所以在当前项目中不需要关心flush方法。

事务实现选用和配置。使用jdbc事务控制. 不选用jta作为事务的实现。放弃理由, 当前测试服务器tomcat本身仅仅是个web server,并不支持jta。配置hibernate属性信息hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory           net.sf.hibernate.transaction.JDBCTransactionFactory

jta的好处:JTA提供了跨Session的事务管理能力,为以后扩展留下了选择空间。

实现单一的增删改操作不需要调用session.beginTransaction()等方法,针对多条记录的修改使用下面的方式调用api   UserTransaction ut = (UserTransaction)(new InitialContext(). lookup("java:comp/UserTransaction")); ut.begin();   //....     ut.commit();     

分页控制

 通过criteria. setFirstResult/setMaxResults方法可以限制一次查询返回的记录范围。 
缓存选用及配置管理
当前选用EHCache作为第二层的缓存(第一层为数据库缓存)。由于EHCache不支持分布式,所以将来可以考虑使用jgroup实现分布式。针对系统内大部分的dao操作使用只读(read)方式进行缓存。 需要写入的部署在不同的机器上解决多个jvm上数据不一致的问题。
 EHCache配置:首先配置hibernate缓存provider class属性hibernate.cache.provider_class net.sf.ehcache.hibernate.Provide。 配置ehcahe配置文件
<ehcache> 
       <diskStore path="java.io.tmpdir"/> 
       <defaultCache  maxElementsInMemory="10000"   //Cache中最大允许保存的数据数量 
           eternal="false"     //Cache中数据是否为常量 

           timeToIdleSeconds="120"   //缓存数据钝化时间 

           timeToLiveSeconds="120"   //缓存数据的生存时间 
          overflowToDisk="true"   //内存不足时,是否启用磁盘缓存 /> 
</ehcache> 
在hibernate映射文件中指定各个映射实体的Cache策略
   <cache usage="read-write"/>
   <cache usage="read-only"/>
 配置好Cache之后,Hibernate在运行期会自动应用Cache机制 

对于查询方法的选用策略

Query.list();  通过一条sql语句返回所有对象
Query.iterate(); 而iterate方法,则是首先通过一条Select SQL获取所有符合查询条件的记录的id。再对这个id集合进行循环操作,通过单独的Select SQL取出每个id所对应的记录,之后填入POJO中返回。

list方法不会从缓存中读取数据,而iterator方法在返回id集合后,针对每一条记录会先到缓存中读取数据。综合以上,当前系统使用原则:1)少量的数据和不频繁访问的数据使用list方法。2)频繁访问的数据使用iterator方法。 

数据库连接池配置和管理

 出于通用的原则选用dbcp,hibernate中的配置

  #hibernate.dbcp.maxActive 100

  #hibernate.dbcp.whenExhaustedAction 1

  #hibernate.dbcp.maxWait 120000

  #hibernate.dbcp.maxIdle 10

  ## prepared statement cache

  #hibernate.dbcp.ps.maxActive 100

  #hibernate.dbcp.ps.whenExhaustedAction 1

  #hibernate.dbcp.ps.maxWait 120000

  #hibernate.dbcp.ps.maxIdle 10

 其他配置

  hibernate.cache.use_query_cache

  cache.use_minimal_puts false

其他问题

1)  当获取大量关联数据的时候,需要指定关联集合属性 (解决N+1 Select问题)。

2)  batch-size (可选,默认是1) 指定一个用于根据标识符抓取实例时使用的"batch size"(批次抓取数量)可设置为10。

3)  对于一些统计查询,尽可能使用hql,而不要依赖于映射进行获取。

4)  对于代码级别的特殊查询,通过设置FetchMode提高效率。

5)  使用绑定变量,在查询中,使用占位符号: 替换非常量值,在查询中使用命名参数。因为query是可以缓存的,所以使用命名参数的方式可以提升查询效率。

本文转载自:http://my.oschina.net/jiyayun/blog/87623

Zero零_度
粉丝 69
博文 1267
码字总数 263854
作品 0
程序员
私信 提问
Java面试题之Hibernate

1.简书一下Hibernated的开发流程 第一步:加载Hibernate的配置文件,读取配置文件的参数, 第二步:创建SessionFactory会话工厂(内部有连接池) 第三步:打开Session 连接 第四步:开启事务...

年轻诠释我们的梦想_705b
2018/06/05
0
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

park
2017/11/28
0
0
MyBatis和Hibernate优劣势对比

1、开发对比 开发速度 Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernat...

黎嘉诚
2016/08/05
106
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

vshcxl
2016/03/28
54
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

qq5923dd411b8fa
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
6
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
昨天
7
0
轻量级 HTTP(s) 代理 TinyProxy

CentOS 下安装 TinyProxy yum install -y tinyproxy 启动、停止、重启 # 启动service tinyproxy start# 停止service tinyproxy stop# 重启service tinyproxy restart 相关配置 默认...

Anoyi
昨天
2
0
Linux创建yum仓库

第一步、搞定自己的光盘 #创建文件夹 mkdir -p /media/cdrom #挂载光盘 mount /dev/cdrom /media/cdrom #编辑配置文件使其永久生效 vim /etc/fstab 第二步,编辑yun源 vim /ect yum.repos.d...

究极小怪兽zzz
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部