在spring boot + spring data查询数据库的过程当中,有时候总会出现一些复杂的查询,咱们但愿数据库返回的字段能随意改变。这个需求在mybatis里很好解决,只须要用map接收就能够,但在用spring data的时候有些麻烦。今天来讨论一下可选的方案。基于spring boot 1.5.15.RELEASE 和 2.2.1.RELEASE。spring
1、官方推荐的作法interface-based Projections 和 class-based Projectionssql
interface-based Projections数据库
一、根据数据库要返回的字段,创建一个interface,实现各个字段的get方法数组
interface SomeDto{ Long getId(); String getName(); Date getCreateTime(); }
二、在repository中,写nativeQuery查询,并以上面新建的interface做为返回对象mybatis
@Query(nativeQuery=true,value="SELECT id,name,create_time FROM table") List<SomeDto> find();
三、spring boot会把查询的结果集的每一条记录,对应到SomeDto中,并为其建立一个代理代理对象(proxy instance)。而后你能够将其看成通常对象,从里面获取数据。函数
List<SomeDto> dtoList = repository.find();
String name1 = dtoList.get(0).getName();
System.out.println(name1);
class-based Projectionsspa
上述基于接口的返回结果,根据官方文档,也能够基于普通的class。可是我在尝试的过程当中,老是报错,放弃。代理
其余方式,可行但不推荐code
1、在repository中写sql,返回Object[]orm
@Query(nativeQuery=true, value = "SELECT id,name,create_time FROM table") List<Object[]> find();
返回的结果集的每一条记录,都是一个Object[],数组的0、一、2。。。等位置分别顺序对应查询的字段。
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不是数据库字段,而是数组下标。
3、使用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 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);