Hibernate对原生sql处理及结果集和VO的映射
来源:互联网 发布:知乎复制破解 编辑:程序博客网 时间:2024/05/21 00:49
昨天解决一个看似很简单的需求,
我有一个类似下面的table(info_table),是收集产品使用的机型信息:
id
type
model
1
nokia
xxx1
2
nokia
xxx2
3
Motorola
yyyy1
4
Motorola
yyyy2
5
Motorola
yyyy3
要实现一个前台展示的页面:
type
countType
nokia
2
Motorola
3
就这么简单的功能。相信稍微熟悉sql的人,马上就可以写出此实现。很惭愧的说,我的心里感觉很简单,由于很久没怎么深入接触sql了,也费了一番周折...
selecttype,count(*) as countType from info_table group by Type order bycountType desc
实现上面的功能。
如何放到功能(struts2.3.x,spring3.1.x,hibernate4.x)集成的环境中处理?一步一步看:
首先从dao层:
@OverridepublicList<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层;
@AutowiredprivateHandleCountServicehandleCountService;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(...)
Query
setResultTransformer
(
ResultTransformer
transformer)
Seta strategy for handling the query results.
(只能google一下了)
Query setResultTransformer(ResultTransformer transformer)
- Seta strategy for handling the query results. This can be used tochange "shape" of the query result.
- Parameters:
transformer
-The transformer to apply- Returns:
- this(for method chaining)
这个函数功能:设置处理查询结果集的策略。
参数ResultTransformer定义:
public interface ResultTransformerextends Serializable
Implementorsdefine a strategy for transforming query results into the actualapplication-visible query result list.
setResultTransformer的执行者,转换查询结果到实际应用的结果列表。ResultTransformer是个接口,通过hibernate3.3.x中doc文档可以看到其有多种实现类。在一些博客中看到最多的是:Transformers.aliasToBean()
static
ResultTransformer
aliasToBean
(
Class
target)
Createsa result transformer that will inject aliased values intoinstances of Class via property methods or fields.
hibernate3.3.x中doc文档也看到:
org.hibernate.transform
ClassAliasToBeanResultTransformer
java.lang.Object org.hibernate.transform.AliasToBeanResultTransformer
中构造函数:AliasToBeanResultTransformer
(
Class
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.java中countUser转为其类型。
解决此问题。
参考:
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
- Hibernate对原生sql处理及结果集和VO的映射
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理
- hibernate使用原生SQL查询返回结果集的处理
- HIBERNATE对原生SQL的处理
- Hibernate执行原生sql将查询结果直接转为VO
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-2
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-2
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-2
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1
- 解决Hibernate原生SQL映射问题 - SQL查询出来的结果映射为值对象
- hibernate纯sql查询结果集映射为DTO(VO,DO)
- hibernate纯sql查询结果集映射为DTO(VO,DO)
- 经典趣味编程问题
- 关于windows操作系统之消息和消息队列
- java生成文件并向文件写入内容
- 解决eclipse中overlaps the location of another project: 'xxxx'
- 2014年苹果ios开发者证书申请及xcode5应用上线发布---完整流程
- Hibernate对原生sql处理及结果集和VO的映射
- 用js验证身份证号,真的很准
- 正则表达式基础知识
- Java中的时间格式化和时间计算的方法
- shell基础知识-2
- 无线遥控小车android客户端图展
- 营销者必读:哪些情绪导致图片病毒传播?
- Linux文件(夹)权限含义
- powershell 学习地址