J2EE最佳实践.ppt

  1. 1、本文档共123页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
* 1.一对多关系是最常见的关联关系,也是优化的重点.因为缓存只缓存普通字段和集合的实例OID,所以当要用到集合的实例的时候,还要一条一条的去数据库载入,相当于load()方法,而执行的SQL语句就是这样的: ??? select id,... from table where id=? ??? select id,... from table where id=? ??? ... ??? 如果这个对象关联的多个对象有成百上千个,那就要执行成百上千这样的查询,数据库服务器估计会很吃力,应用服务器的内存估计也用的差不多了. ??? 解决办法: ??? a.手动清除Session级别的缓存,调用Session.evict()来将该持久对象从一级缓存清除,节约内存,这时候持久对象成为脱管状态,或者叫游离状态,应用层和视图层可以照常使用该对象,最后保存的时候,Hibernate会自动处理好与数据库同步的问题; ??? b.使用set的batch-size属性,这个属性可以明显的减少执行SQL语句数目,因为它执行的是这样的语句: ??? 如果batch-size=10,而集合有13个关联对象,那么它会执行如下语句: ??? select id,... from table where id in (?,?,?,?,?,?,?,?,?,?) ??? select id,... from table where id in (?,?,?) ??? 总共2条语句,如果不设置batch-size,就要执行13条SQL语句,虽然in语句也不是很高效的语句,但还是比执行N条语句快很多,我做了个初步的测试,用Oracle 10g测试,相同的数据,用两种不同的查询方式,每个运行10次,算出平均查询时间,batch-size方式查询时间少一半,也就是快一倍,虽然是很粗糙的测试,但足以说明性能上的差距.如果你的集合很大,那么你的batch-size也不能设的太大,如果有1000条数据,那么你的batch-size最好不要超过50,否则性能也不会好到哪里去. ??? 以上两条结合,能够较好的解决执行过多SQL语句的问题和内存不足的问题. * fatch方式的设置.在one-to-many和mangy-to-one关系中fetch=select和fetch=join,两者产生的SQL语句不同.select表示将关联对象用另外一句SQL语句查询出来,而且第二条SQL语句默认是延迟加载的,也就是如果不用到关联对象,这句SQL语句就不会执行了;join是采用左外连接语句来查询的,将两个表通过外键产生一个连接查询,如果两个表总字段数很多,那么这句SQL语句会很长,而且对它设置的lazy=true也会失效,也就变成了立即加载,在某些情况下会造成很多不必要的查询和持久对象load到内存. ??? 虽然select方式多执行了一条SQL语句,但对性能影响不大,因为这条语句很简单,只有一个where条件:外键=?,所以解决方案是:采用select配置 * 数据量很大的表(一般是上百万或千万数据),查询一次很费时间,而如果一次把所有查询结果都转成持久化类,那么内存肯定会罢工的.根据我以往的经验,对于这样的表,都是要分页查询的,除非哪个项目非常变态的要在一页内显示所有数据(也可以解决,但麻烦一点,就是分多次查,每查到一定量数据就清空一级缓存,然后将数据加入到List或Set),但基本上不会有必须这样做的理由. ??? 做分页也有意思的,其实分页功能抽象出来,最简单的就只有3个int属性:总记录数total(数据库count出来),每页记录数page_size(通过常量或参数设置得到),游标偏移量offset(通过页参数传递得到).其他数据都可以由这3个推导出来,况且它们这些整数之间的乘除加减速度都是很快的,比如: ??? 总页数=[(total-1)/page_size]+1 ??? 当前页数=(offset/page_size)+1 ??? 其中偏移量offset主要是控制查询区间的开始位置,而offset+page_size就是查询区间的结束位置,适用于Oracle的rownum和Mysql的limit.其他数据库也可以将offset换成当前页curr_page,方便查询. ??? 而且分页功能可以单独抽象出来做成一个与具体业务数据无关的类,我取名叫PageBean,这是一个SimpleBean,只有3个属性和对应的set,get方法.而如果需要分页,只要将这3个属性设置好,传递在各层之间,查数据的时候,将offset和offset+page_size设置到查询即可. ??? 那么total怎么办?每次翻页都去查?不需要.我的做法是,将查询条件封装成一个bean对象(Sea

文档评论(0)

yan666888 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档