|
我们的系统经常涉及到多表查询。例如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中。
是否除了上面的方法,就没其他的更好的办法了?希望讨论一下,大家在项目中都是怎样处理这些问题的?
|
|