前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增、删、改、查的功能。JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现完整的数据操作方法。JPA除了这些功能和优势之外,还有非常强大的查询的功能。以前复查的查询都需要拼接很多查询条件,JPA 有非常方便和优雅的方式来解决。接下来就聊一聊JPA 自定义查询,体验Spring Data JPA 的强大。
Spring Data JPA 查询分为两种,一种是 Spring Data JPA 默认实现的预定义的方法,另一种是需要根据查询的情况定义查询条件。
一、预定义查询
预定义方法就是我们上面看到的那些自带的方法,因为UserRepository继承了 JpaRepository 拥有了父类的这些JPA自带的方法。如下图所示:
调用预定义方法:
@RequestMapping("/test") public void test() { Users user = new Users(); user.setId((long) 1); userRespository.findById((long) 1); userRespository.findAll(); userRespository.delete(user); userRespository.deleteById((long) 1); userRespository.existsById((long) 1); }
上面所有JpaRepository父类拥有的方法都可以直接调用 。
二、自定义查询
Spring Data JPA 支持根据实体的某个属性实现数据库操作,主要的语法是 findByXX、 readAByXX、queryByXX、 countByXX、 getByXX 后跟属性名称,利用这个功能仅需要在定义的 Repository 中添加对应的方法名即可,无需具体实现完整的方法,使用时 Spring Boot 会自动动帮我们实现对应的sql语句。
1、属性查询
根据姓名查询,示例如下:
@Repository public interface UserRespository extends JpaRepository<Users, Long> { Users findByName(String name,String account); }
上面的实例可以看到,我们可以在UserRepository 接口中进行接口声明。例如,如果想根据实体的 name和account 这两个属性来进行查询User的信息。那么直接在 UserRepository 中增加一个接口声明即可。
2、组合条件查询
JPA不仅支持单个属性查询,还能支持多个属性,根据And、or 等关键字组合查询:
Users findByNameAndAccount(String name,String account);
上面的例子,就是根据姓名和账号两个条件组合查询。这个是组合查询的例子,删除和统计也是类似的:deleteByXXXAndXXX、countByXXXAndXXX。可以根据查询的条件不断地添加和拼接, Spring Boot 都可以正确解析和执行。
3、JPA关键字
JPA的自定义查询除了And、or 关键字外,基本上SQL语法中的关键字,JPA都支持,比如:like,between 等。
这个语句结构可以用下面的表来说明:
关键字 |
示例方法 |
JPQL语句 |
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals |
findByFirstname,findByFirstnameIs,findByFirstnameEquals |
… where x.firstname = ?1 |
Between |
findByStartDateBetween |
… where x.startDate between ?1 and ?2 |
LessThan |
findByAgeLessThan |
… where x.age < ?1 |
LessThanEqual |
findByAgeLessThanEqual |
… where x.age <= ?1 |
GreaterThan |
findByAgeGreaterThan |
… where x.age > ?1 |
GreaterThanEqual |
findByAgeGreaterThanEqual |
… where x.age >= ?1 |
After |
findByStartDateAfter |
… where x.startDate > ?1 |
Before |
findByStartDateBefore |
… where x.startDate < ?1 |
IsNull |
findByAgeIsNull |
… where x.age is null |
IsNotNull,NotNull |
findByAge(Is)NotNull |
… where x.age not null |
Like |
findByFirstnameLike |
… where x.firstname like ?1 |
NotLike |
findByFirstnameNotLike |
… where x.firstname not like ?1 |
StartingWith |
findByFirstnameStartingWith |
… where x.firstname like ?1 (parameter bound with appended %) |
EndingWith |
findByFirstnameEndingWith |
… where x.firstname like ?1 (parameter bound with prepended %) |
Containing |
findByFirstnameContaining |
… where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy |
findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
Not |
findByLastnameNot |
… where x.lastname <> ?1 |
In |
findByAgeIn(Collection<Age> ages) |
… where x.age in ?1 |
NotIn |
findByAgeNotIn(Collection<Age> ages) |
… where x.age not in ?1 |
True |
findByActiveTrue() |
… where x.active = true |
False |
findByActiveFalse() |
… where x.active = false |
IgnoreCase |
findByFirstnameIgnoreCase |
… where UPPER(x.firstame) = UPPER(?1) |
三、自定义SQL语句
上面介绍了JPA的很多条件查询的方法。但是,实际项目中,还是有些场景上面的查询条件无法满足。那么我们就可以通过 @Query 注解写hql 来实现。
@Query("select u from Users u where u.name = :name1") List<UserDO> findByHql(@Param("name1") String name1);
代码说明:
1、@Query 注解,表示用执行hql语句。
2、name1等参数对应定义的参数。
上面是通过hql,如果hql 写着不习惯,也可以用本地 SQL 语句来完成查询:
@Query(value = "select * from users where name = ?1",nativeQuery = true) List<User> findUserBySql(String name);
上面示例中的 ?1 表示方法参数中的顺序,nativeQuery = true 表示执行原生sql语句。
最后
以上就把Spring Data JPA的查询功能介绍完了, JPA 简化了我们对数据库的操作,预定义很多常用的数据库方法,直接使用即可。另外 JPA 还有一个特点,就是不用关心数据库的表结构,需要更改的时候只需要修改对应 Model 的属性即可。
这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码 ,获取这个系列课程的完整源码。
推荐阅读:
SpringBoot从入门到精通(二十六)超级简单的数据持久化框架!Spring Data JPA 的使用!
SpringBoot从入门到精通(二十四)3分钟搞定Spring Boot 多环境配置!
SpringBoot从入门到精通(二十三)Mybatis系列之——实现Mybatis多数据源配置
SpringBoot从入门到精通(二十二)使用Swagger2优雅构建 RESTful API文档
SpringBoot从入门到精通(二十一)如何优雅的设计 RESTful API 接口版本号,实现 API 版本控制!
SpringBoot从入门到精通(二十)快速构建RESTful Web API 服务
SpringBoot从入门到精通(十九)使用注解实现动态Sql、参数传递
SpringBoot从入门到精通(十八)Mybatis系列之——使用注解的方式实现后台管理功能
SpringBoot从入门到精通(十七)MyBatis系列之——创建自定义mapper 实现多表关联查询!
SpringBoot从小白到精通(十六)使用pagehelper实现分页查询功能
SpringBoot从小白到精通(十四)使用JdbcTemplate操作数据库,配置多数据源!
SpringBoot从小白到精通(十二)logback日志配置
SpringBoot从小白到精通(十)使用Interceptor拦截器,一学就会!
SpringBoot从小白到精通(九)使用@Async实现异步执行任务
SpringBoot从小白到精通(八)熟悉@EnableScheduling,一秒搞定定时任务
SpringBoot从小白到精通(七)使用Redis实现高速缓存架构
SpringBoot从小白到精通(六)使用Mybatis实现增删改查【附详细步骤】
SpringBoot从小白到精通(五)Thymeleaf的语法及常用标签
SpringBoot从小白到精通(四)Thymeleaf页面模板引擎
SpringBoot从小白到精通(二)如何返回统一的数据格式
SpringBoot从小白到精通(一)如何快速创建SpringBoot项目