这篇文章主要讲解了“springbootjpa如何实现返回结果自定义查询”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“springbootjpa如何实现返回结果自定义查询”吧!

jpa 返回结果自定义查询

这里自定义的实体是没有在数据映射的实体。可以返回聚合函数的值。

第一种方法

实体类。(这里本人使用的是idea)

@DatapublicclassNameOnlyDtoimplementsSerializable{privateStringfirstName;privateStringlastName;privateStringsex;}

repository类(这里不是 使用的继承jpa中的 的方式。而是使用的EntityManager)。代码中有详细的注释。

@RepositorypublicclassCustomEntity{//实体管理器EntityManager是负责管理Entity的对象。对Entity的操作包括添加、删除、修改和查询,都是通过实体管理器来实现的。@PersistenceContextprivateEntityManagerentityManager;//EntityManagerFactory@TransactionalpublicList<NameOnlyDto>listNameOnlyDto(){Stringsql="selectp.last_namelastName,p.first_namefirstNamefromPERSONp";//hibernate5.2之前//SQLQuerysqlQuery=entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class);//hibernate5.2之后的写法//unwrap让JPA的Query返回Map对象javax.persistence.Query.unwrap//hibernate或jpa中使用AliasToBeanResultTransformer自定义类型转换ResultTransformer下划线转驼峰SQLQuerysqlQuery=entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class);/*Queryquery=sqlQuery.setResultTransformer(Transformers.aliasToBean(NameOnlyDto.class));List<NameOnlyDto>list=query.getResultList();//.list();*/Queryquery=sqlQuery.setResultTransformer(Transformers.aliasToBean(NameOnlyDto.class));List<NameOnlyDto>list=query.getResultList();entityManager.clear();returnlist;}}

OK。就这样就可以了。个人测试似乎在oracle数据库 不行。可能是sql查询结果不太一样

第二种方法

可以在特定的场合使用。

自定义类

publicclassNameOnlyDtoTimplementsSerializable{privateStringfirstName;privateStringlastName;//privateStringaddress;privateStringsex;//构造函数特殊注意这里返回几个字段就要有几个字段的构造参数感觉不太合适的地方publicNameOnlyDtoT(StringfirstName,StringlastName){this.firstName=firstName;this.lastName=lastName;}/*publicNameOnlyDtoT(StringfirstName,StringlastName,Stringsex){this.firstName=firstName;this.lastName=lastName;this.sex=sex;}*/}

这里是repository中的写法

//切记不能使用@query.如果使用@query个人感觉和上面那种方法是一样的逻辑List<T>findByLastName(Stringlastname,Class<T>type);使用(这里注意的是NameOnlyDtoT中字段能赋值的只能是person中含有的字段。这是个人觉得鸡肋的存在)publicList<NameOnlyDtoT>testNameOnlyDtoTS(){List<NameOnlyDtoT>nameOnlyDtoTS=personRepository.findByLastName("哈哈",NameOnlyDtoT.class);returnnameOnlyDtoTS;}使用jpa两张表联查返回自定义实体

在java开发中,用Jpa框架做连表查询时(需要返回两张表的各自部分字段),在返回对象的过程中感觉比较棘手,一直没有一个好的解决方案,网上也有各种版本的方法,下面的方法本人感觉最方便使用

1、创建一个SpringBoot空白项目,引入pom依赖

先看项目结构,为了简化,没有引入service层,直接使用controller调用dao层

pom.xml配置

<!--web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version></dependency><!--jpa依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>2、application.yml配置文件

server:port:13333spring:datasource:url:jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNullusername:rootpassword:12345678driver-class-name:com.mysql.jdbc.Driverjpa:show-sql:truehibernate:ddl-auto:none3、数据库(有两张表user/address)

我们现在需要联查user和address表,address表中的user_id是和user表中id是做关联查询

4、User.java 和 Address.java

5、UserDaoRepository.java 和 AddressDaoRepository.java

附上UserDaoRepository.java的代码

packagecom.lss.jpa.dao;importcom.lss.jpa.entity.dto.UserAddressDto;importcom.lss.jpa.entity.po.User;importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.data.jpa.repository.Query;importjava.util.List;importjava.util.Map;publicinterfaceUserDaoRepositoryextendsJpaRepository<User,Integer>{@Query(value="select\"title\"ascommon,u.idasid,u.nameasname,a.idasaddressId,a.addressasaddressNamefromuseru,addressawhereu.id=a.user_id",nativeQuery=true)publicList<UserAddressDto>findAllUserAddress();@Query(value="select\"title\"ascommon,u.idasid,u.nameasname,a.idasaddressId,a.addressasaddressNamefromuseru,addressawhereu.id=a.user_idandu.id=1",nativeQuery=true)publicUserAddressDtofindAllUserAddressById();@Query(value="select\"title\"ascommon,u.idasid,u.nameasname,a.idasaddressId,a.addressasaddressNamefromuseru,addressawhereu.id=a.user_idandu.id=1",nativeQuery=true)publicMap<String,Object>findAllUserAddressByMap();}6、UserAddressDto.java代码

packagecom.lss.jpa.entity.dto;publicinterfaceUserAddressDto{IntegergetId();StringgetName();StringgetAddressName();IntegergetAddressId();StringgetCommon();}

此处我们自定义了UserAdressDto来接收两张表返回的数据,注意:此时创建的是一个interface,并且里面的字段是用get的形式创建的接收参数

7、TestController.java

packagecom.lss.jpa.web;importcom.lss.jpa.dao.UserDaoRepository;importcom.lss.jpa.entity.dto.UserAddressDto;importcom.lss.jpa.entity.po.User;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.List;importjava.util.Map;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;@RestController@Slf4jpublicclassTestController{@AutowiredprivateUserDaoRepositoryuserDaoRepository;@GetMapping("test")publicStringtest(){List<UserAddressDto>all=userDaoRepository.findAllUserAddress();all.stream().forEach(dto->{log.info("result:id:{},name:{},addressId:{},addressName:{},common:{}",dto.getId(),dto.getName(),dto.getAddressId(),dto.getAddressName(),dto.getCommon());});UserAddressDtodto=userDaoRepository.findAllUserAddressById();log.info("result:id:{},name:{},addressId:{},addressName:{},common:{}",dto.getId(),dto.getName(),dto.getAddressId(),dto.getAddressName(),dto.getCommon());Map<String,Object>map=userDaoRepository.findAllUserAddressByMap();log.info("map:{}",map);List<User>userList=userDaoRepository.findAll();log.info("userList:{}",userList);return"ok";}}

最后,启动项目,调用/test接口

curl http://localhost:13333/test

看console里打印结果

Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id
2020-02-23 13:14:33.293 INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController : result: id:1, name:zhangsan , addressId:1, addressName:beijing, common:title
2020-02-23 13:14:33.293 INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController : result: id:2, name:lisi, addressId:2, addressName:tianjin, common:title
Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1
2020-02-23 13:14:33.296 INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController : result: id:1, name:zhangsan , addressId:1, addressName:beijing, common:title
Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1
2020-02-23 13:14:33.299 INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController : map:org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap@72cce81
Hibernate: select user0_.id as id1_1_, user0_.name as name2_1_ from user user0_
2020-02-23 13:14:33.305 INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController : userList:[User(id=1, name=zhangsan ), User(id=2, name=lisi), User(id=3, name=wangwu), User(id=4, name=zhaoliu)]

我们可以拷到输出的sql和联查出来的数据结果,都被dto完美接收

特别注意,接收的dto一定要是interface,里面的参数要写成get形式的方法体,这样jpa在查询到数据后,会自动映射到interface里,通过调用get的方法体相当于调用了参数值,这样就会把数据取出来

感谢各位的阅读,以上就是“springbootjpa如何实现返回结果自定义查询”的内容了,经过本文的学习后,相信大家对springbootjpa如何实现返回结果自定义查询这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!