zoukankan      html  css  js  c++  java
  • 【转】让EntityManager的Query返回Map对象

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

      常见的用法是这样的:

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

      这样用会使代码非常不容易让人理解,究竟下标为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)我们可以退而求其次,牺牲跨实现的特性来满足我们的需求:

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

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

      转载自《createNativeQuery


      补充记录:

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

     1 import lombok.Data;
     2 import javax.persistence.Entity;
     3 import javax.persistence.Id;
     4 import javax.persistence.Transient;
     5 import java.io.Serializable;
     6 import java.math.BigDecimal;
     7 import java.util.Date;
     8 
     9 @Data //lombok
    10 @Entity //这个注解必备 
    11 public class StatCardOpen implements Serializable {
    12     @Transient
    13     private static final long serialVersionUID = 1L;
    14     @Id //这个注解必备,必须有个id
    15     private Integer id;
    16     private String realName;
    17     private String identity;
    18     private String departTitle;
    19     private BigDecimal changeBalance;
    20     private BigDecimal changeDonation;
    21     private BigDecimal changeDeposit;
    22     private String managerName;
    23     private Date createTime;
    24 
    25 }

      则调用的格式如下:

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

      

     

  • 相关阅读:
    Ubuntu14.04手动安装配置jdk sdk ndk ant
    Ubuntu中(桌面或者文件夹)右键鼠标打开终端设置
    C语言中固定长度和不定长度的数组初始化示例
    Algorithm Design——最大公约数、最小公倍数
    Algorithm Design——凸包
    Algorithm Design——判断线段是否相交
    Algorithm Design Everyday——2.查找学生信息
    Algorithm Design——查找
    Algorithm Design——高精度整数四则运算
    Algorithm Design——并查集
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/10758222.html
Copyright © 2011-2022 走看看