spring data 返回任意字段

在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);

 

 

 

posted @ 2019-11-29 14:30  leondryu  阅读(806)  评论(0编辑  收藏  举报