职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 723|回复: 14

hibernate多表查询后映射到非持久化值对象的探讨

  [复制链接]
broken 发表于 2011-6-20 10:00 | 显示全部楼层 |阅读模式
我们的系统经常涉及到多表查询。例如tableA,tableB,从这两个表中分别select出一些列。这些列的值组成一个新的值对象VO
Sql代码  
select tableA.a,tableB.b from tableA, talbeB  

select tableA.a,tableB.b from tableA, talbeB
如果直接返回list<Object[]>,需要遍历list,把objec数组内的元用setA(Object[0])这样的形式再次set进VO,而且代码不易阅读。

所以想有没有方法让hibernate在查询出数据的时间自动set数据到VO中。在网上搜了很久,大概有以下一些办法,但是都有缺点。
1. 在VO中写一个构造函数,然后在hql中这样写:
Sql代码  
select new VO(tableA.a, tableB.b) from tableA,tableB  

select new VO(tableA.a, tableB.b) from tableA,tableB
但是这个方法要求要先写一个VO的hibernate hbm的映射文件,把VO映射到一个虚的表上。
我们的系统中涉及到很多不用的多表查询,每次返回的列都不相同。这样需要对每个VO都去建立映射文件,太繁琐了。
2.采用
List list = getSession().createSQLQuery("select tableA.a \"a\",tableB.b \"b\", from tableA,tableB") 
   .addScalar("a",Hibernate.Long).addScalar("b",Hibernate.Long) 
   .setResultTransformer(Transformers.aliasToBean(VO.class)));

且不说这样的代码量很大,而且在我所用的hibernate3.2的版本中,没有addScalar这个方法。
3. Java代码  
List list = getSession().createSQLQuery("select * from tableA,tableB")   
          .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);  

List list = getSession().createSQLQuery("select * from tableA,tableB")
          .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
这样会把所有查询的列放到一个元素为Map的list中。
4.我也试验了直接用.setResultTransformer(Transformers.aliasToBean(VO.class)));也不行。

现在采用的是第三种方法,转换为map,在遍历list,从map中get出value,再set到VO相应值中。这样代码的易读性好多了,但是仍然需要遍历,很繁琐。以前用iBatis的时候,iBATIS可以把select出的任意列映射到自己的resultMap中,在把resultMap指向一个VO。不用自己每次都遍历一遍去set值。

我所需要的1.不用遍历list去set VO的值2
2.不要去写hbm映射文件
3.select出来的值自动填充到VO中。
是否除了上面的方法,就没其他的更好的办法了?希望讨论一下,大家在项目中都是怎样处理这些问题的?

江南枫 发表于 2011-6-20 10:00 | 显示全部楼层
<!-- 获取入库计划批次的列表 -->
<statement id="getJhrkPc" parameterClass="java.util.HashMap" resultClass="com.longtop.istat3.jhgl.vo.JhYearPcVO">
select j.pc_bm as ypValue, j.pc_mc as ypStr
          from  jh_pcxx j
         where j.ywlx ='1'  
         order by j.scsx
</statement>
ibtas是可以直接封装到VO中的不需要任何的配置!! hibenate没找到!!寻找中!

叫我小乖 发表于 2011-6-20 10:00 | 显示全部楼层
等答案。。。。。。。。。

曾经的小孩 发表于 2011-6-20 10:00 | 显示全部楼层
引用
4.我也试验了直接用.setResultTransformer(Transformers.aliasToBean(VO.class)));也不行。

你有没有调试过为什么不行?

芷馨 发表于 2011-6-20 10:00 | 显示全部楼层
我没记错的话,hibernate支持两种方式

1、获取的数据封装到map中的键值对
2、使用dynamic bean

这两种都可以直接用apache commons beanutils
来直接丢到vo的属性中去的。
其中dynamic bean甚至可以直接用的。

yoyo 发表于 2011-6-20 10:01 | 显示全部楼层
这个问题还涉及到数据库表字段名到VO属性名的映射问题,自己写个扩展可能会更加灵活一点

紫衿 发表于 2011-6-20 10:01 | 显示全部楼层
先返回map,然后反射set Vo的值。

愚人 发表于 2011-6-20 10:01 | 显示全部楼层
这不是解决这个问题的王道

fl 发表于 2011-6-20 10:01 | 显示全部楼层
为什么一定要用对象呢?

yoyo 发表于 2011-6-20 10:01 | 显示全部楼层
ricoyu 写道
引用
4.我也试验了直接用.setResultTransformer(Transformers.aliasToBean(VO.class)));也不行。

你有没有调试过为什么不行?

应该是没有配置hbm文件的原因
Jethro 发表于 2011-7-22 10:42 | 显示全部楼层
先看看怎么样!
yoyo 发表于 2011-7-24 10:46 | 显示全部楼层
真它媽的夠狠
木已 发表于 2011-7-29 10:15 | 显示全部楼层
额~哦........偶无语
北大青鸟 发表于 2011-8-9 11:06 | 显示全部楼层
oh!magat!!!
fossil 发表于 2011-8-18 14:00 | 显示全部楼层
最近比较倒霉
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-27 23:52 , Processed in 0.138392 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表