在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. 使用栈实现队列(1)(Java)

    class MyQueue { private Stack s1; private Stack s2; public MyQueue(int size) { this.s1 = new Stack(s ...

  2. Scrapy:配置日志

    Scrapy logger 在每个spider实例中提供了一个可以访问和使用的实例,方法如下: import scrapy class MySpider(scrapy.Spider): name = ...

  3. Flutter获取屏幕宽高和Widget大小

    我们平时在开发中的过程中通常都会获取屏幕或者 widget 的宽高用来做一些事情,在 Flutter 中,我们可以使用如下方法来获取屏幕或者 widget 的宽高. MediaQuery 一般情况下, ...

  4. SpringBoot配置mybatis

    一直都说SpringBoot是零配置,当然,真正实现零配置是不可能的,但是在配置mybatis这里真的是太简单了,哈哈,下面我们一起看一下. 1.先导入基于SpringBoot的mybatis依赖包 ...

  5. 加载hive-jdbc driver时报错:java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration

    这是因为缺少一个hadoop-common包,引入即可: <dependency> <groupId>org.apache.hadoop</groupId> < ...

  6. kubernetes调度pod运行于master节点上

    应用背景: 使用kubeadm部署的kubernetes集群,其master节点默认拒绝将pod调度运行于其上的,加点官方的术语就是:master默认被赋予了一个或者多个“污点(taints)”,“污 ...

  7. 给dataframe添加一列索引

    测试数据自己瞎编的 需求:给现在df数据添加一列sid,要求这一列是和stock一一对应的整数 代码如下: import pandas as pd test_data = {'stock': ['AA ...

  8. MongoDB集群管理常用命令

    1.以admin身份登录yqtrack_gather01库: mongo 127.0.0.1:27017/yqtrack_gather01 -u username -p password --auth ...

  9. anacodna/python 安装 tensorflow

    study from : https://www.cnblogs.com/HongjianChen/p/8385547.html 执行1-6 7 安装jupyter 每次使用tensorflow,都要 ...

  10. Spring Security 访问控制 源码解析

    上篇 Spring Security 登录校验 源码解析  分析了使用Spring Security时用户登录时验证并返回token过程,本篇分析下用户带token访问时,如何验证用户登录状态及权限问 ...