您的位置:首页 > 博客中心 > 数据库 >

Hibernate对原生sql处理及结果集和VO的映射

时间:2022-03-14 03:24

昨天解决一个看似很简单的需求,

我有一个类似下面的table(info_table),是收集产品使用的机型信息:

@Override publicList<CountVO> getAllHandleCount(){ Sessionsession =sessionFactory.getCurrentSession(); Stringhql ="selecttype,count(*) as countType from info_table group by Type order bycountType desc"; Queryquery = session.createQuery(hql); @SuppressWarnings("unchecked") List<CountVO>list = query.list(); returnlist; }

再次server层...

最后action层;

@Autowired
privateHandleCountServicehandleCountService;
privateIntegercurrentPage= 1;
privateIntegerpageSize= 10;
privateIntegertotalCount;
privateIntegertotalPage;

privateList<CountVO>handleCountVO;
/*
* handle count at 2014-12-04
*
*/
publicString HandleCountQueryAll() throwsIOException{
handleCountVO=handleCountService.getAllPage(currentPage,pageSize);
totalCount=handleCountService.getAllHandleCount().size();
totalPage= (totalCount+pageSize- 1) /pageSize;
returnSUCCESS;
}
……
get/set方法

由于返回的结果不是Hibernate管理的bean,所以理所当然的想到写个VO去接纳返回结果集。

CountVO.java

publicclassCountVO {
privateString type;
privateIntegercountUser;
publicString getType(){
returntype;
}
publicvoidsetType(Stringtype){
this.type=type;
}
publicInteger getCountUser() {
returncountUser;
}
publicvoidsetCountUser(Integer countUser) {
this.countUser= countUser;
}
}

前台直接通过传递ListBean通过struts标签来实现:

xxxx.jsp

…
<s:iteratorvalue="handleCountVO">
<tr>
<td><s:propertyvalue="type"/></td>
<td><s:propertyvalue="countUser"/></td>
</tr>
</s:iterator>
…

整个流程配置完成。对我来说看似没问题,但是实际不是这样的...…


问题1:

在action层明明看到有list值,传到jsp层就是不显示,后debug跟到jsp,发现<s:iterator></s:iterator>也是可以循环的,可“奇怪”的就是不显示。

经过一番折腾,才发现经过sql获得的List不是“理所当然“的List<CountVO>而是List<Object>,其里面的值不是我想的CountVO中的type和countUser,而是[0],[1]。


需要找方法解决这个问题,很简单的一个解决方法-----转换一下就可以了,我不想这样做,想弄清楚这个问题。


由于没开vpn,暂时baidu查查。

发现:

1)有个createSQLQuery和一直用的createQuery不同,因为CountVO不属于Hibernate管理的bean,不对应实体表,这个语句可能使用,最主要的还在后面;

createQuery用的hql语句进行查询,createSQLQuery用sql语句查询;
前者以hibernate生成的Bean为对象装入list返回;
后者则是以对象数组进行存储;

所以使用createSQLQuery以hibernate生成的Bean为对象装入list返回,可以直接转换对象 

Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class); 
XXXXXXX 代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。

(以上方法,只是介绍使用原生sql查询结果映射为hibernate中bean方法,不能解决此问题)

2)createSQLQuery后可以有这样的方法:setResultTransformer(...)


org.hibernate.transform 
ClassAliasToBeanResultTransformer
org.hibernate.transform.AliasToBeanResultTransformer


中构造函数:
( resultClass) 

也可以满足需求。

那就开始做吧-------可以完美解决

问题2:

sql转换的一个小问题,也列到这吧,不让问题1孤单的存在着:

前面"selecttype,count(*) as countType from info_table group by Type order bycountType desc";

中count和countVO中countType类型问题。

IllegalArgumentExceptionin class: com.xxx.bean.CountVO, setter method of property: countUser

2014-12-0511:39:51,708 ERROR HHH000091: Expected type:java.lang.Integer,actual value: java.math.BigInteger

2014-12-0511:39:52,337 ERROR Exception occurred during processing request:IllegalArgumentExceptionoccurred while calling setter of com.xxx.bean.CountVO.countUser

org.hibernate.PropertyAccessException:IllegalArgumentExceptionoccurred while calling setter of com.xxx.bean.CountVO.countUser

类型不匹配,sql中count(*)需要对应类型为java.math.BigInteger,那就把CountVO.javacountUser转为其类型。

解决此问题。


参考:

https://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/transform/ResultTransformer.html

https://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/transform/AliasToBeanResultTransformer.html

http://blog.163.com/charm_888/blog/static/608350020107254126654/

http://langgufu.iteye.com/blog/1565397


热门排行

今日推荐

热门手游