实体类

  @Entity

  @Table(name = "t_hotel")

  @Data

  public class THotel {

  @Id

  private int id;

  private String name;

  private String address;

  /**

  * 城市id

  */

  private String city;

  }

  @Entity

  @Table(name = "t_city")

  @Data

  public class TCity {

  @Id

  private int id;

  private String name;

  private String state;

  private String country;

  private String map;

  }

  在启动SpringBoot的时候 SpringDataJpa会自动的在数据库中生成表结构.

  为了查询要求,我随便的增加了一些数据,如下图所示

  

  新建接口

  public interface TCityRepository extends JpaRepository, JpaSpecificationExecutor {

  }

  单元测试类

  @RunWith(SpringRunner.class)

  @SpringBootTest

  public class TCityRepositoryTest{

  @Autowired

  private TCityRepository tCityRepository;

  }

  1.查找出Id小于3,并且名称带有shanghai的记录.

  /**

  * 查找出Id小于3,并且名称带有`shanghai`的记录.

  *

  * @param id id

  * @param name 城市名称

  * @return 城市列表

  */

  List findByIdLessThanAndNameLike(int id, String name);

  单元测试

  @Test

  public void findByIdLessThanAndNameLike() throws Exception {

  List shanghai = tCityRepository.findByIdLessThanAndNameLike(3, "%shanghai%");

  Assert.assertTrue(shanghai.size() > 0);

  }

  2.通过旅店名称分页查询旅店以及城市的所有信息

  /**

  * 通过旅店名称分页查询旅店以及城市的信息

  *

  * @param name 旅店名称

  * @param pageable 分页信息

  * @return Page

  */

  @Query(value = "select t1.name as cityName,t2.name as hotelName\n" +

  "from t_city t1\n" +

  " left join t_hotel t2 on t2.city = t1.id\n" +

  "where t2.name = :name",

  countQuery = "select count(*)" +

  "from t_city t1 \n" +

  " left join t_hotel t2 on t2.city = t1.id\n" +

  "where t2.name = :name"

  , nativeQuery = true)

  Page findCityAndHotel(@Param("name") String name, Pageable pageable);

  为了节约时间 我只在select 与 from 之间 分别查询了城市的名称以及旅店的名称如果要查所有的信息,可以换成

  t1.* ,

  t2.*

  单元测试

  @Test

  public void findCityAndHotel() throws Exception {

  Page cityAndHotel = tCityRepository.findCityAndHotel("酒店", new PageRequest(0, 10));

  Assert.assertTrue(cityAndHotel.getTotalElements() > 0);

  }

  关于把List 转换成List<对象> 的方法 我已经在上一篇JPA的文章中比较清楚的说了,因此我就不再重复的叙述一遍了

  3.HQL通过旅店名称查询旅店以及城市的所有信息

  3和2其实是一样的,为了方便我就不作出分页查询了

  HQL可以用map来接受返回的参数,具体的用法如下所示:

  /**

  * HQL通过旅店名称查询旅店以及城市的所有信息

  *

  * @return

  */

  @Query(value = "select new map(t1,t2) from TCity t1 left join THotel t2 on t1.id=t2.city where t2.name =:name")

  List> findCityAndHotelByHQL(@Param("name") String name);

  测试方法和2是差不多的 我就不粘贴了

  Map 转换实体类的方法也挺多的我就不多说了,如果是直接返回给前台的话,也没有必要转换成对象.

  4.HQL通过旅店名称查询旅店以及城市的所有信息 直接返回实体类

  /**

  * 关联查询

  *

  * @return

  */

  @Query(value = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from TCity t1 left join THotel t2 on t1.id=t2.city where t2.name =:name")

  List findCityAndHotelByHQLResultObj(@Param("name") String name);

  为了方便CityHohel我只封装了2个属性,这和HQL查询的字段是完全一致的,也必须要保持一致.

  /**

  * Created by ZhuPengWei on 2018/5/12.

  */

  @Data

  public class CityHohel {

  private String cityName;

  private String hotelName;

  public CityHohel(String cityName, String hotelName) {

  this.cityName = cityName;

  this.hotelName = hotelName;

  }

  }

  当然这个带参的构造方法是必须要写的,否则会抛出转换实体的异常

  单元测试

  @Test 无锡人流医院 http://www.wxbhnk120.com/

  public void findCityAndHotelByHQLResultObj() throws Exception {

  List cityAndHotelByHQLResultObj = tCityRepository.findCityAndHotelByHQLResultObj("酒店");

  Assert.assertTrue(cityAndHotelByHQLResultObj.size() > 0);

  }

  4.HQL通过旅店名称分页查询旅店以及城市的所有信息 直接返回实体类

  /**

  * 关联查询

  *

  * @return

  */

  @Query(value = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from TCity t1 left join THotel t2 on t1.id=t2.city where t2.name =:name",

  countQuery = "select count(*) from TCity t1 left join THotel t2 on t1.id=t2.city where t2.name =:name")

  Page findCityAndHotelAllSelf(@Param("name") String name, Pageable pageable);

  @Test

  public void findCityAndHotelAllSelf() throws Exception {

  Page cityAndHotelAllSelf = tCityRepository.findCityAndHotelAllSelf("酒店", new PageRequest(0, 10));

  Assert.assertTrue(cityAndHotelAllSelf.getTotalElements() > 0);

  }

  5.动态查询旅店以及城市的所有信息 直接返回实体类

  如果是动态查询的话当然首先得构造一条sql去查询了,当然如果不是自定义实体对象的话这样的网上一大堆我就不写了.

  直接走测试

  @Autowired

  @PersistenceContext

  private EntityManager entityManager;

  @Test

  public void testDynamic() throws Exception {

  String sql = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from TCity t1 left join THotel t2 on t1.id=t2.city where t2.name ='酒店'";

  Query query = entityManager.createQuery(sql);

  List resultList = query.getResultList();

  Assert.assertTrue(resultList.size() > 0);

  }

  这样测试是通过的,因此可以知道在业务层的方法中我们可以动态的构造SQL语句. 比如说可以在接口中这样子来定义一个方法

  /**

  * 自定义查询

  * @param sql

  * @param entityManager

  * @return

  */

  default List customQuery(String sql, EntityManager entityManager) {

  return entityManager.createQuery(sql).getResultList();

  }

  然后在测试类中动态的根据条件去拼接SQL语句去调用

Spring Data Jpa 复杂查询总结的更多相关文章

  1. spring data jpa 分页查询

    https://www.cnblogs.com/hdwang/p/7843405.html spring data jpa 分页查询   法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特 ...

  2. spring data JPA entityManager查询 并将查询到的值转为实体对象

    spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...

  3. 【Spring Data 系列学习】Spring Data JPA 基础查询

    [Spring Data 系列学习]Spring Data JPA 基础查询 前面的章节简单讲解了 了解 Spring Data JPA . Jpa 和 Hibernate,本章节开始通过案例上手 S ...

  4. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  5. Spring Data JPA 简单查询--接口方法

    一.接口方法整理速查 下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.( ...

  6. Spring Data JPA 实例查询

    一.相关接口方法     在继承JpaRepository接口后,自动拥有了按"实例"进行查询的诸多方法.这些方法主要在两个接口中定义,一是QueryByExampleExecut ...

  7. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  8. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  9. Spring Data JPA 条件查询的关键字

    Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...

  10. Spring Data JPA简单查询接口方法速查

    下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.(1)先按照功能进行分类 ...

随机推荐

  1. jcenter下载不了时,用国内镜像下载解决

    修改build.gradle,以下是原本的配置信息 buildscript { repositories { google() jcenter() } dependencies { classpath ...

  2. cannot connect to daemon at tcp:5037: cannot connect to 127.0.0.1:5037: 由于目标计算机积极拒绝,无法连接。 (10061)

    原因是:5037端口被占用 解决方法:1.查找5037被谁占用   netstat -ano | findstr "3037" 2.查看对应的是哪个任务  tasklist | f ...

  3. parquet 简介(转)

    原文 Parquet 列式存储格式 面向分析型业务的列式存储格式 由 Twitter 和 Cloudera 合作开发,2015 年 5 月从 Apache 的孵化器里毕业成为 Apache 顶级项目 ...

  4. php-7.3.4 configure: error: Please reinstall the libzip distribution

    php-7.3.4 configure: error: Please reinstall the libzip distribution # wget https://libzip.org/downl ...

  5. MySQL语句和命令大全

    前言 这里记录的是这两年学习工作过程中遇到的常用的 MySQL 语句和命令,部分是网上收集来的,出处已经不记得了,这里先谢过这些大佬.本文包括常见 SQL 语句,还有部分运维语句和命令,没有做详细的说 ...

  6. 解决SQL Server 阻止了对组件Ad Hoc Distributed Queries访问的方法

    来源:http://www.htmer.com/article/922.htm 今天单位一ASP.NET网站,里面有个功能是导出数据,发现一导出就报错,报错内容是:SQL  Server 阻止了对组件 ...

  7. Java13新特性 -- ZGC:取消使用未使用的内存

    在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的.号称不管你开了多大的堆内存,它都能保证在 10 毫秒内释放 JVM ,不让它停顿在那.但是,当时的设计是 ...

  8. Centos7下的文件压缩

    [root@web01 ~]# yum provides zip 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * ba ...

  9. python工程设置工具(pipenv)

    原始安装 pip工具 --- 包安装工具, 可以从Python包索引hub上安装,也可以使用自定义的hub. 命令: pip install xxx 缺点: 1.命令方式, 一次只能安装一个包, 对于 ...

  10. flink ---- 系统内部消息传递的exactly once语义

    At Most once,At Least once和Exactly once 在分布式系统中,组成系统的各个计算机是独立的.这些计算机有可能fail. 一个sender发送一条message到rec ...