在JPA 2.0中我们可以使用entityManager.createNativeQuery()来执行原生的SQL语句。但当我们查询结果没有对应实体类时,需使用entityManager.createNativeQuery(String sqlString)来执行查询时,query.getResultList()返回的是一个List<Object[]>。也就是说每行的数据被作为一个对象数组返回。

  常见的用法是这样的:

 public void testNativeQuery(){  
    Query query = entityManager.createNativeQuery("select id, name, age from t_user");  
    List rows = query.getResultList();  
    for (Object row : rows) {  
        Object[] cells = (Object[]) row;  
        System.out.println("id = " + cells[0]);  
        System.out.println("name = " + cells[1]);  
        System.out.println("age = " + cells[2]);  
    }  

  这样用会使代码非常不容易让人理解,究竟下标为0的元素到底是什么,不去数查询语句是不知道的,而且一旦查询语句被调整,Java代码也要一起调整。这时我们想如果返回的是Map的话,用起来会清晰得多。

  可惜的是JPA的API中并没有提供这样的设置。其实很多JPA的底层实现都是支持返回Map对象的。例如:

  EclipseLink的query.setHint(QueryHints.RESULT_TYPE,ResultType.Map);

  Hibernate的.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

  所以,如果我们想要返回Map并且确定底层用的是某一种JPA的实现时(如Hibernate)我们可以退而求其次,牺牲跨实现的特性来满足我们的需求:

 public void testNativeQuery(){  
    Query query = entityManager.createNativeQuery("select id, name, age from t_user");  
    query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);  
    List rows = query.getResultList();  
    for (Object obj : rows) {  
        Map row = (Map) obj;  
        System.out.println("id = " + row.get("ID"));  
        System.out.println("name = " + row.get("NAME"));  
        System.out.println("age = " + row.get("AGE"));  
    }  

  这里需要注意的是,用Map肯定要比用Object数组来的效率低。所以你要看性能下降是否在可接受范围内。再就是在我的Hibernate 4.2.x的环境下,无论你原生SQL中写的是大写字母还是小写字母,返回的字段名都是大写的。

  转载自《createNativeQuery


  补充记录:

  若调用entityManager.createNativeQuery(String sqlString,Class resultClass)来执行查询时,需传入查询结果对应的实体类,假设实体类的定义如下:

 import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date; @Data //lombok
@Entity //这个注解必备
public class StatCardOpen implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
@Id //这个注解必备,必须有个id
private Integer id;
private String realName;
private String identity;
private String departTitle;
private BigDecimal changeBalance;
private BigDecimal changeDonation;
private BigDecimal changeDeposit;
private String managerName;
private Date createTime; }

  则调用的格式如下:

 Query query = em.createNativeQuery(sqlstart + sqlend + sqlorder, StatCardOpen.class);
List<StatCardOpen> resultList = query.getResultList();

  

 

【转】让EntityManager的Query返回Map对象的更多相关文章

  1. 设置JPA的Query返回Map对象

    说明正常执行jpa查询的时候需要传一个对应实体进行映射返回的数据,这样有时候如果一个sql是复合sql关联很多表,就需要新建实体有点麻烦,通过下面方式就能将返回结果映射成map.这样就能随意获取返回结 ...

  2. 让JPA的Query查询接口返回Map对象

    在JPA 2.0 中我们可以使用entityManager.createNativeQuery()来执行原生的SQL语句. 但当我们查询结果没有对应实体类时,query.getResultList() ...

  3. Spring data jpa中Query和@Query分别返回map结果集

    引用: http://blog.csdn.net/yingxiake/article/details/51016234 http://blog.csdn.net/yingxiake/article/d ...

  4. JPA EntityManager 在没有实体类的情况下返回Map

    JPA entityManager.createNativeQuery()执行原生的SQL,当我们查询结果没有对应的实体类时,query.getResultList()返回的是一个List<Ob ...

  5. css字符串转换为类map对象及反转

    存储对象为啥是类map(即:{key:val,...}格式),因为Map对象的val为字符时,无法存储 '('.')' 左右括号,我也很无奈╮(╯▽╰)╭ 解析脚本: <!DOCTYPE htm ...

  6. python3中的map对象返回的是迭代器,该迭代器用list()转列表之后,再次用list()转化时会返回空

    练习代码的时候,发现python3中的map()函数返回的可迭代对象,在用list()转成列表之后,再次用list()转列表的时候,获取的是空值(如下所示),所以查了一下python3的map()对象 ...

  7. 使用Criteria 实现两表的左外连接,返回根对象

    (转) 引用 两个实体 Parent(P) 和 Child(C)之间是1:N的关系,现要求符合指定条件的P及所包 含的C 采用hibernate中的Criteria来实现此功能的代码如下: Java代 ...

  8. js 操作map对象

    转自:http://smallvq123.javaeye.com/blog/823923 /* * Map对象,实现Map功能 * * * size() 获取Map元素个数 * isEmpty() 判 ...

  9. JavaScript创建Map对象(转)

    JavaScript 里面本身没有map对象,用JavaScript的Array来实现Map的数据结构. /* * MAP对象,实现MAP功能 * * 接口: * size()     获取MAP元素 ...

随机推荐

  1. Python3中如何解决中文乱码与编码的问题

    1.解决乱码问题: pyhton中内部所有编码是Unicode,中文是gbk:正常情况下,我们输出的是utf-8: 我们可以采用sys.getdefaultencoding()查看系统默认的编码: 解 ...

  2. 《为大量出现的KPI流快速部署异常检测模型》 笔记

    以下我为这篇<Rapid Deployment of Anomaly Detection Models for Large Number of Emerging KPI Streams>做 ...

  3. Reflections 介绍

    Reflections 介绍 研究Spring扫包原理的时候,在网上查阅相关资料的时候,发现使用Reflections库可以实现扫包. Reflections 通过扫描 classpath,索引元数据 ...

  4. styled-components解决全局样式'injectGlobal' 废除的问题

    最新版的 styled-components v4 已经将原有的 injectGlobal() 方法替换成了 createGlobalStyle() ,而且用法也和之前的 injectGlobal 方 ...

  5. swiftmailer时没有设置https的选项,才可以发送成功。在linux下面

    <?php $su = 'register'; $ge = '1362836763@qq.com'; $co = 'Please register!'; send_mail($su,$ge,$c ...

  6. git几个必知托管平台

      程序员必须知道的几个Git代码托管平台 说到Git代码托管平台,首先推荐的是GitHub,好多好的开源项目都来自GitHub,但是GitHub只能新建公开的Git仓库,私有 仓库要收费,如果你做的 ...

  7. IFE第二天

    HTML是超文本标记语言,HTML5是下一代的HTML标准. HTML元素是组成HTML文档的部分,HTML属性为HTML元素提供附加信息. 文档类型<!DOCTYPE>声明帮助浏览器正确 ...

  8. BZOJ 2594 水管局长数据加强版

    LCT维护最小生成树 要求两点路径最大的最小,首先想到的肯定是最小生成树,再加上有删边操作,那就得用LCT维护了. 可是对于cut一条边,我们要时刻维护图中的最小生成树,需要把之前被我们淘汰的边找回, ...

  9. 第六届SD省赛 Circle of Friends

    Circle of Friends Time Limit: 2000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

  10. Python--基础二

    Python基础:字符串str & 列表list & 元组tuple & 字典dict & 集合set Python 基础 2 字符串 str 字符串是以单引号或双引号 ...