Spring Data Jpa 复杂查询总结
实体类
@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 复杂查询总结的更多相关文章
- spring data jpa 分页查询
https://www.cnblogs.com/hdwang/p/7843405.html spring data jpa 分页查询 法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特 ...
- spring data JPA entityManager查询 并将查询到的值转为实体对象
spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...
- 【Spring Data 系列学习】Spring Data JPA 基础查询
[Spring Data 系列学习]Spring Data JPA 基础查询 前面的章节简单讲解了 了解 Spring Data JPA . Jpa 和 Hibernate,本章节开始通过案例上手 S ...
- Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!
前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...
- Spring Data JPA 简单查询--接口方法
一.接口方法整理速查 下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.( ...
- Spring Data JPA 实例查询
一.相关接口方法 在继承JpaRepository接口后,自动拥有了按"实例"进行查询的诸多方法.这些方法主要在两个接口中定义,一是QueryByExampleExecut ...
- springboot整合spring data jpa 动态查询
Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...
- springboot集成Spring Data JPA数据查询
1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...
- Spring Data JPA 条件查询的关键字
Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...
- Spring Data JPA简单查询接口方法速查
下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.(1)先按照功能进行分类 ...
随机推荐
- pycharm 生成requirements.txt
在命令行中输入 pip freeze>requirements.txt 1 安装requirements文件中的包 pip install -r requirements.txt
- WebGL学习笔记(十三):拾取
目前为止,我们还没有涉及到交互相关的内容,实际上,我们是需要知道我们点击的地方下面的第一个物体的信息,这个过程称为拾取. 简单拾取实现 我们可以通过颜色来获取是否成功点击,具体方式如下: 场景中有一个 ...
- WebGL学习笔记(八):光照
局部光照与全局光照 局部光照 只考虑光源到模型表面的照射效果,运算量较小: 全局光照 考虑到环境中所有表面和光源相互作用的照射效果,即让没有直接受光照射的位置也会受周围反射光的影响,运算量较大: Ph ...
- c++ Array运用实例
myprint.hpp #include <iostream> #include <string> template <typename T> inline voi ...
- docker入门-基本概念(一)
Docker是什么 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker的应用场景 Web 应用的自动化打包和发布. 自动化测试和持续集成.发 ...
- 大幅度改变celery日志外观,修改成日志可点击跳转和鲜艳五彩日志,解决脚本中已添加handler的logger和框架日志重复记录问题。
大幅度改变celery日志外观,修改成日志可点击跳转和鲜艳五彩日志,解决脚本中已添加handler的logger和框架日志重复记录问题.打猴子补丁. 先把脚本中的所有logger的handlers全部 ...
- IDEA光标类的操作
1.Ctrl+Alt+Left/Right 光标定位到上一个/下一个浏览位置处: 2.Ctrl+Shift+Backspace 光标定位到上次修改的地方: 3.Alt+Up/Down 移动 ...
- Qt编写安防视频监控系统15-远程回放
一.前言 远程回放有两种处理方式,一种是采用NVR厂家提供的SDK开发包来登录到NVR上,然后根据SDK的函数接口指定的视频文件,当然也有接口查询视频文件列表等:一种是采用视频监控行业的国标GB281 ...
- elasticsearch中mapping的_source和store的笔记(转)
原文地址: https://www.cnblogs.com/zklidd/p/6149120.html 0.故事引入 无意中看到了ES的mapping中有store字段,作为一个ES菜鸡,有必要对这个 ...
- pycharm更改缩进快捷键-ubuntu系统
前言 ubuntu系统tab+shirt是切换窗口的快捷键,而这个快捷键也恰恰是pycharm这个快捷键,他们的快捷键产生了冲突,所以目前我们需要更改下pycharm的快捷键,这样就能愉快使用缩进功能 ...