jpa中查询分为两类:一类是继承了父类的方法的基本查询(前文已大概讲述了),另一类是自定义查询。
Spring Data JPA 可以根据接口方法名来实现数据库操作,主要的语法是 findXXBy、readAXXBy、queryXXBy、countXXBy、getXXBy 后面跟属性名称,利用这个功能仅需要在定义的 Repository 中添加对应的方法名即可,使用时 Spring Boot 会自动帮我们实现.
1、根据用户名查询用户:
User findByUserName(String userName);
2、也可以加一些关键字 And、or:
User findByUserNameOrEmail(String username,String email);
3、修改、删除、统计也是类似语法:
Long deleteById(Long id); Long countByUserName(String userName)
4、基本上 SQL 体系中的关键词都可以使用,如 LIKE 、IgnoreCase、OrderBy:
List findByEmailLike(String email); User findByUserNameIgnoreCase(String userName); List findByUserNameOrderByEmailDesc(String email);
| Keyword | Sample | JPQL snippet |
|---|---|---|
| And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
| Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
| Is,Equals | 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 ages) | … where x.age in ?1 |
| NotIn | findByAgeNotIn(Collection age) | … 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) |
在UserRepository中增加方法:
/**
* @Author Smith
* @Description 自定义Sql查询.(这个本来是HQL的写法,我的运行不了,改成了本地的SQL)
* @Date 10:18 2019/1/24
* @Param
* @return org.springframework.data.domain.Page<com.jpa.springdatajpa.model.User>
**/
@Query(value = "select * from user",nativeQuery = true)
Page<User> findALL(Pageable pageable);
/**
* @Author Smith
* @Description 原生SQL的写法,?1表示方法参数中的顺序
* @Date 10:20 2019/1/24
* @Param
* @return org.springframework.data.domain.Page<com.jpa.springdatajpa.model.User>
**/
@Query(value = "select * from user where nick_name = ?1",nativeQuery = true)
Page<User> findByNickName(String nickName, Pageable pageable);
/**
* @Author Smith
* @Description 修改,添加事务的支持
* @Date 10:21 2019/1/24
* @Param
* @return int
**/
@Transactional(timeout = 10)
@Modifying
@Query("update User set userName = ?1 where id = ?2")
int modifyById(String userName, Long id);
/**
* @Author Smith
* @Description 删除
* @Date 10:22 2019/1/24
* @Param
* @return void
**/
@Transactional
@Modifying
@Query("delete from User where id = ?1")
@Override
void deleteById(Long id);
@Test
public void testFindALL(){
int page = 1;
int size = 1;
Sort sort = new Sort(Sort.Direction.DESC,"id");
Pageable pageable = PageRequest.of(page,size,sort);
Page<User> all = userRepository.findALL(pageable);
Assert.assertEquals(1,all.getContent().size());
Assert.assertEquals(2,all.getTotalPages());
}
@Test
public void testFindByNickName(){
int page = 0;
int size = 1;
Sort sort = new Sort(Sort.Direction.DESC,"id");
Pageable pageable = PageRequest.of(page,size,sort);
Page<User> all = userRepository.findByNickName("bb",pageable);
Assert.assertEquals(1,all.getContent().size());
Assert.assertEquals(1,all.getTotalPages());
}
只需要查询前 N 个元素,或者只取前一个实体。
User findFirstByOrderByNickNameAsc(); User findTopByOrderByIdDesc(); Page<User> queryFirst10ByNickName(String nickName, Pageable pageable); List<User> findFirst10ByNickName(String nickName, Sort sort); List<User> findTop10ByNickName(String nickName, Pageable pageable);
在某些情况下查询条件很多,需要不断拼接属性,方法名会显得很长,这个时候就要使用JpaSpecificationExecutor 接口了.
概念: