[转]Hibernate3如何解决n+1 selects
Hibernate3中取得多层数据的所产生的n+1 selects问题的解决:
其实这个问题在Hibernate in Action中已经有很多种解决办法了。但我觉得其中最好的办法是用Criteria
的FetchMode来解决,但是Hibernate in Action中写的很不详细。我昨晚试了好长时间来的到答案。下
面总结一下。
需求这样的,我有四张表(one,two,three,four)从one一直外键关联到four。结构如下
现在在Session中得到One,并从One里一直取到Four里的内容。如果简单的用Session.get来实现是这
样的。
Java代码
这样我在Session关闭后返回的One里是从One到Four的信息都有的。
然而这样做所导致的结果是生成大量的SQL查询,这是一个典型的n+1 Selects问题。如果系统结构层次多,符合条件的记录多,那么Hibernate为你生成的SQL查询将是难以接受的。
对于这个例子生成的SQL是这样的
SQL代码
对于这样的问题,在没有Hibernate以前我们一般都用jdbc来做,那样的话我们其实用一个进行3次join
的sql语句就可以实现,但 是这样解决也有问题,就是返回的ResultSet中的数据非常多,而且杂乱,其
实是从one到four平行排列的。对于这样的结果集我们要把它手动影射 曾对象结构也是一个很复杂的操
作。
幸好Hibernate3可以为我们做这些事情(我再一次被Hibernate的强大所震撼)。
上面的实现可以用Criteria来实现: Java代码
这里的重点是这句话
criteria.setFetchMode("twos",FetchMode.JOIN).
setFetchMode("twos.threes",FetchMode.JOIN).
setFetchMode("twos.threes.fours",FetchMode.JOIN).uniqueResult();
在用Criteria之前先设置FetchMode,应为Criteria是动态生成sql语句的,所以生成的sql就是一层层Join
下去的。
setFetchMode(String,Mode)第一个参数是association path,用"."来表示路径。这一点具体的例子
很少,文档也没有写清楚。我也是试了很久才试出来的。
就这个例子来所把因为取道第四层,所以要进行三次setFetchMode
第一次的路径是twos,一位one中有two的Set。这个具体要更具hbm.xml的配置来定。
第二个路径就是twos.threes
第三个就是twos.threes.fours
一次类推,一层层增加的。
这样做法最终生成的SQL是这样的:
SQL代码
虽然很长但是只有一条SQL语句。性能要好很多。Hibernate的强大之处是它会把返回的ResultSet自动
影射到你的对象模型里面去。这就为我们省了很多事。
看来Hibernate真是一个耐人寻味的Framework啊。
最新文章
- 上传文件fileupload
- java 内存模型
- ylbtech-数据库设计与优化-对作为复选框/单选列表的集合表的设计
- 【Pure】
- SystemParametersInfo
- jqPlot,一个 jQuery这个 JavaScript 框架的绘图插件
- 删除左右两边的空格trim
- ajax 传值 中文乱码问题
- ubuntu配置jdk脚本以及导致开不了机的解决方案
- Vi编辑器入门
- Android makefile 组织结构
- 数据库文件导入导出操作,以及赋予权限SQL语句
- ios小型服务器环境配置
- 关于CTO角色的认知
- vue(2)—— vue简单语法运用,常用指令集
- Visual Studio 2015的安装及单元测试练习
- php 历史版本下载地址
- hung task机制
- mybatis的快速入门
- 第十九课 golang中的下划线
热门文章
- 暴力枚举——Help Me with the Game
- mybatis和model关联
- Openstack学习历程_1_视频
- javascript 中 typeof 的使用
- bootStrap-1
- C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常
- windows7下python3.4.3 添加库路径(转)
- error_log() 范例
- scala言语基础学习三
- URAL 1291 Gear-wheels(BFS)