在spring boot + spring data查询数据库的过程中,有时候总会出现一些复杂的查询,我们希望数据库返回的字段能随意改变。这个需求在mybatis里很好解决,只需要用map接收就可以,但在用spring data的时候有些麻烦。今天来讨论一下可选的方案。基于spring boot 1.5.15.RELEASE 和 2.2.1.RELEASE。

spring boot 版本 1.5.15.release

一、官方推荐的做法interface-based Projections 和 class-based Projections

  interface-based Projections

  1、根据数据库要返回的字段,建立一个interface,实现各个字段的get方法  

interface SomeDto{
Long getId();
String getName();
Date getCreateTime();
}

  2、在repository中,写nativeQuery查询,并以上面新建的interface作为返回对象

@Query(nativeQuery=true,value="SELECT id,name,create_time FROM table")
List<SomeDto> find();

  3、spring boot会把查询的结果集的每一条记录,对应到SomeDto中,并为其创建一个代理对象(proxy instance)。然后你可以将其当作一般对象,从里面获取数据。

List<SomeDto> dtoList = repository.find();
String name1 = dtoList.get(0).getName();
System.out.println(name1);

  class-based Projections

  上述查询方式,根据官方文档,也可以基于普通的class。但是我在尝试的过程中,总是报错,放弃。

参考

1、https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.dtos(5.3.11.Projections)

2、https://stackoverflow.com/questions/29082749/spring-data-jpa-map-the-native-query-result-to-non-entity-pojo?r=SearchResults

其他方式,可行但不推荐的方式

二、在repository中写sql,返回Object[]

@Query(nativeQuery=true, value = "SELECT id,name,create_time FROM table")
List<Object[]> find();

   返回的结果集的每一条记录,都是一个Object[],数组的0、1、2。。。等位置分别顺序对应查询的字段。

三、在repository中写hql,返回Map  

@Query(nativeQuery=false, value = "SELECT new map(id,name,create_time) FROM table")
List<Map> findSome();

  查询用了hql,如果是简单查询还好。如果涉及多表联查或是聚合函数,还需要查hql的对应语法,很麻烦。

  而且,表面上,返回的是Map,其实它还是一个Object[],因为map的key不是数据库字段,而是数组下标。

四、使用EntityManager,  

String sql = "SELECT id,name,create_time FROM table";
Query query = entityManager.createNativeQuery(sql);
query.unwrap(SQLQuery.class).setResultTransformer(Transformer.ALIAS_TO_ENTITY_MAP);
List<Map> list = query.getResultList();

  这个方法,可以正常的将sql查询结果转换成map,并且map的key就是数据库查询的字段的名字。然而需要使用entityManager,不能直接在repository中写sql,写法非常啰嗦。

spring boot 版本 2.2.1.RELEASE

1、此版本的spring data,在repository中进行nativeQuery sql查询,可以直接将,查询字段映射到map,并且map的key就是数据库的字段。

@Query(nativeQuery=true, value = "SELECT id,name,create_time FROM table")
List<Map<String,Object>> find();
List<Map<String,Object>> list = repository.find();
String name1 = list.get(0).get("name");
System.out.println(name1);

最新文章

  1. android中的回调请求的个人理解
  2. css3的背景颜色渐变@线性渐变
  3. sql性能优化小技巧(一)
  4. UVALive 4682 XOR Sum (trie)
  5. OpenStack(0) - Table of Contents
  6. Spring与Hibernate整合
  7. 无法显示TabHost的setIndicator设置的图片的问题解决办法
  8. BizTalk开发小技巧
  9. 计算机程序的思维逻辑 (74) - 并发容器 - ConcurrentHashMap
  10. svn服务器的搭建与使用二
  11. for循环&amp;len函数和range函数的运用
  12. Java编写的接口测试工具
  13. Android下NDK开发环境搭建
  14. synchronized学习
  15. CentOS6.5升级GCC4.8
  16. GUI界面修饰
  17. ENVI数据格式
  18. hibernate的一级缓存问题
  19. 更换SSL证书
  20. Cannot complete request to Marketplace不能打开eclipse marketplace

热门文章

  1. HDU 5113 Black And White ( 2014 北京区预赛 B 、搜索 + 剪枝 )
  2. codevs 1013 求先序排列 2001年NOIP全国联赛普及组 x
  3. noi.ac #531 神树和物品
  4. Redis Java连接池调研
  5. C语言中的位域[转]
  6. css基础(浮动 清除f浮动)
  7. $\LaTeX$数学公式大全13
  8. finally应用
  9. python中的定时器threading.Timer
  10. redux异步