[TOC]
基本使用方法
继承接口并声明查询方法
interface PersonRepository extends Repository {
List findByLastname(String lastname);
}
Autowired注入
public class SomeClient {
@Autowired
private PersonRepository repository;
public void doSomething() {
List persons = repository.findByLastname("Matthews");
}
}
自定义Repository
选择性暴露CURD方法
@NoRepositoryBean
interface MyBaseRepository extends Repository {
T findOne(ID id);
T save(T entity);
}
interface UserRepository extends MyBaseRepository {
User findByEmailAddress(EmailAddress emailAddress);
}
使用特定模块接口定义Repository
interface MyRepository extends JpaRepository { }
@NoRepositoryBean
interface MyBaseRepository extends JpaRepository {
…
}
interface UserRepository extends MyBaseRepository {
…
}
注意:中间层repository接口要使用注解@NoRepositoryBean,以确保Spring Data不会在运行时对其实例化。
定义查询方法
查询方法建立
- distinct flag
- ignoring case
- order by
public interface PersonRepository extends Repository {
List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// Enables the distinct flag for the query
List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// Enabling ignoring case for an individual property
List findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
// Enabling static ORDER BY for a query
List findByLastnameOrderByFirstnameAsc(String lastname);
List findByLastnameOrderByFirstnameDesc(String lastname);
}
为了消除不确定性,可以在方法名内使用下划线“_”手动定义隔断点。
List findByAddress_ZipCode(ZipCode zipCode);
特殊参数处理
Page findByLastname(String lastname, Pageable pageable);
Slice findByLastname(String lastname, Pageable pageable);
List findByLastname(String lastname, Sort sort);
List findByLastname(String lastname, Pageable pageable);
限制查询结果数量
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page queryFirst10ByLastname(String lastname, Pageable pageable);
Slice findTop3ByLastname(String lastname, Pageable pageable);
List findFirst10ByLastname(String lastname, Sort sort);
List findTop10ByLastname(String lastname, Pageable pageable);
流式查询结果
@Query("select u from User u")
Stream findAllByCustomQueryAndStream();
Stream readAllByFirstnameNotNull();
@Query("select u from User u")
Stream streamAllPaged(Pageable pageable);
流在使用结束后需要关闭以释放资源,可以用 close() 方法手动将其关闭或者使用 try-with-resources 块。
- try-with-resources 块
try (Stream stream = repository.findAllByCustomQueryAndStream()) {
stream.forEach(…);
}
异步查询结果
- 使用
java.util.concurrent.Future
作为返回类型 - 使用 Java 8
java.util.concurrent.CompletableFuture
作为返回类型 - 使用
org.springframework.util.concurrent.ListenableFuture
作为返回类型
@Async
Future findByFirstname(String firstname);
@Async
CompletableFuture findOneByFirstname(String firstname);
@Async
ListenableFuture findOneByLastname(String lastname);
关键字
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 | 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 |
… where x.age in ?1 |
NotIn | findByAgeNotIn(Collection |
… 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) |
使用 @Query
基本用法
public interface UserRepository extends JpaRepository {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
使用 LIKE 表达式
public interface UserRepository extends JpaRepository {
@Query("select u from User u where u.firstname like %?1")
List findByFirstnameEndsWith(String firstname);
}
使用原生SQL
public interface UserRepository extends JpaRepository {
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
User findByEmailAddress(String emailAddress);
}
原生SQL分页
public interface UserRepository extends JpaRepository {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page findByLastname(String lastname, Pageable pageable);
}
使用 Sort 和 JpaSort
public interface UserRepository extends JpaRepository {
@Query("select u from User u where u.lastname like ?1%")
List findByAndSort(String lastname, Sort sort);
@Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
List
使用已命名参数
public interface UserRepository extends JpaRepository {
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}
修改查询
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);