在hibernate中查询使用List,Map和类对象定制返回类型

 

  在使用hibernate进行查询时,使用得最多的还是通过构建hql进行查询了。在查询的过程当中,除使用经常的查询对象方法之外,还会遇到查询一个属性,或一组聚集结果的情况。在这种情况下,我们通常就需要对返回的结构进行处理。
一般情况下,我们通过构建hql,并通过设置query的resultTransformer来定制返回结果的类型,一般设置为map属性,如下所示、来指定查询结果的每一项为一个map。:
Query query = session.createQuery("hql");
query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
 
    不过,随着hibernate的发展,可以在hql中直接使用集合查询语句,如list和map了。以下分别介绍使用List和Map时的查询语句以及查询结果。首先,数据库的数据如下所示:
mysql> select * from p_dictionary;
+-----------------+----+---------+------+--------+--------+
| dictionary_type | id | version | code | forbid | value |
+-----------------+----+---------+------+--------+--------+
| COUNTY | 1 | 0 | 001 | | 四川 |
| COUNTY | 2 | 0 | 002 | | 北京 |
| COUNTY | 3 | 0 | 001 | NULL | 四川 |
+-----------------+----+---------+------+--------+--------+
3 rows in set (0.00 sec)
以下分别介绍使用list和map的查询语句和查询结果:

A、使用List

String query = "select new List(p.code, p.value) from Dictionary p";
List list = session.createQuery(query).list();
System.out.println(list);
//结果: [[001, 四川],[002,北京],[001,四川]]

采用list方法查询的返回结果为一个List,该List中封装的对象分为以下三种情况:

  1.查询全部字段的情况下,如"from 实体类",list中封装的对象为实体类本身,各属性都将得到填充。

  2.只查询一个字段,默认情况下,list中封装的是Object对象。

  3.查询两个或两个以上的字段,默认情况下,list中封装的是Object[],长度与所查询的字段数一致。

 
B、使用Map,
  首先不指定alias(别名),则结果的键就按照查询出来的顺序结果,使用0,1来表示key:
String query = "select new Map(p.code, p.value) from Dictionary p";
//完全面向对象,使用java中的new Map
List list = session.createQuery(query).list();
//结果:[{1=四川, 0=001},{1=北京, 0=002},{1=四川, 0=001}
  使用Map,指定alias,则结果中的key则为alias,和实体类中字段对应着:
String query = "select new Map(p.code as code, p.value as value) from Dictionary p";
List list = session.createQuery(query).list();
//结果:[{value=四川, code=001},{value=北京, code=002},{value=四川, code=001}

  如果部分使用alias,部分不使用,则使用了alias的将使用alias作为key,没有使用的则仍然使用序号代替,其中序号则为在查询结果的序号

String query = "select new Map(p.code as code, p.value) from Dictionary p";
List list = session.createQuery(query).list();
//结果:[{1=四川, code=001},{1=北京, code=002},{1=四川, code=001}]

C、Others

--------------------------------------------------------------------------------------------------
select new List(p.name, p.address) from Person as p ;
//select将选择出来的属性存入一个List对象中 select new ClassTest(p.name, p.address) from Person as p;
//select将选择出来的属性封装成对象,前提是ClassTest支持ClassTest(p.name, p.address)的构造函数:) select new Map(p.name as personName) from Person as p ;
//select将选中的表达式命名为别名,这种用法与new Map()结合,选择出来的是Map结构,
//以personName为key,将实际选择出来的值作为value

--------------------------------------------------------------------------------------------------

D、One More Thing

  相信用过hibernate的兄弟们都会因为多表复杂查询后,为返回的结果如何组装到一个VO中而烦恼不已。我也不停的为此而烦恼,但是在看了hibernate的transform后,感觉这个方法还挺管用的。

  假设我们现在有一个DTO,其属性包括两张表的属性,我们现在需要将sql语句(不是Hql语句哦:)查询得到的内容转为一个DTO对象,其解决方法如下:

  

//sql语句
String sql = "select u.userName as userName, p.title as title, p.addTime as addTime from user as u,post as p where u.id=p.userId"
//PostVO类,里边放着了用户的信息和帖子的信息的属性,设置get\set方法,务必保证这个类里边有一个默认的构造函数。
Query q = getCurrentSession().createSQLQuery(sql).setResultTransformer(Transformers.aliasToBean(PostVO.class));

  可以看下hibernate这一部分的源码就会发现,主要是使用了AliasToBeanResultTransformer这个类,通过sql的 查询,会返回数组,然后hibernate根据数据表的映射,自动帮我们来set对应的字段属性,所以标红的部分务必要跟VO中的属性值一致,要不然会报错的。 如果需要的话,大家也可以重写这个类。例如VOResultTransformer。然后在dao中更改成

setResultTransformer(new VOResultTransformer(PostVO.class)); 

ps:

参考博客:) 关于hibernate纯sql查询返回结果集问题(hbm.xml中不写多表关联)

参考文章:) hibernate-hql-createquery-list-type-cast-to-model-directly

  

//add
//使用了包名 com.example.DTO
List<DTO> dtos = session.createQuery("SELECT NEW com.example.DTO( p.name, o.name) FROM Entity o").list();

hibernate总结一的更多相关文章

  1. hibernate多对多关联映射

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  2. 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用

    问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...

  3. hibernate多对一双向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  4. Hibernate中事务的隔离级别设置

    Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下

  5. Hibernate中事务声明

    Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...

  6. spring applicationContext.xml和hibernate.cfg.xml设置

    applicationContext.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans ...

  7. [原创]关于Hibernate中的级联操作以及懒加载

    Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...

  8. hibernate的基本xml文件配置

    需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...

  9. Maven搭建SpringMVC+Hibernate项目详解 【转】

    前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...

  10. 1.Hibernate简介

    1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发;           b.大大减少代码量;           c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...

随机推荐

  1. build opencv with python support

    cmake -DPYTHON_LIBRARY=/opt/anaconda/lib/libpython2.7.so -DPYTHON_INCLUDE_DIR=/opt/anaconda/include/ ...

  2. Linux命令查询手册--sort

    一.sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. 二.sort的参数选项 1. sort -u 在输出 ...

  3. 一台nginx服务器多域名配置 (转)

    Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了. 下面我就来说说server_name的使用吧: s ...

  4. 将String转化为Long,并将Long转化为Date

    package org.ljh.test.javaee; import java.text.SimpleDateFormat; import java.util.Date; public class ...

  5. jq插件处女座 图片轮播

    好久没写博客了,变得好懒呀,无地自容.最近一直在学sass和jq插件的写法,照猫画虎的谢了一个jq的插件,也算是第一次真正称得上插件的插件 ,废话不多说 上代码 (function($) { $.fn ...

  6. The FastCGI process exited unexpectedly

    ERROR:HTTP Error 500.0 - Internal Server Error D:\Program Files\php\php-cgi.exe - The FastCGI proces ...

  7. php ajax 同时验证 用户名 密码

    今天写了一个程序分享给大家,该程序是ajax密码和用户名验证问题 第一步 先在数据库里建立一张表 有3个字段 为 id name pass 第二步 写html页面,需要引入jq库 请到官网自行下载 & ...

  8. linux下mysql忘记root密码的解决方案

    1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ...

  9. C 宏定义

    C/C++中宏使用总结 .C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释 ...

  10. j2ee概览

    J2EE诞生的背景是什么?Java 2平台企业版,也就是J2EE,定义了开发多层企业应用程序的标准.它的诞生并不是偶然的,它是在各种条件积累成熟之下的产物.原因之一:java语言的巨大成功.1994年 ...