Spring Data JPA 指南——整理自官方參考文檔

[TOC]java

基本使用方法

繼承接口並聲明查詢方法spring

interface PersonRepository extends Repository<Person, Long> {
   List<Person> findByLastname(String lastname);
}

Autowired注入app

public class SomeClient {
 
  @Autowired
  private PersonRepository repository;
 
  public void doSomething() {
    List<Person> persons = repository.findByLastname("Matthews");
  }
}

自定義Repository

選擇性暴露CURD方法異步

@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
 
  T findOne(ID id);
 
  T save(T entity);
}
 
interface UserRepository extends MyBaseRepository<User, Long> {
  User findByEmailAddress(EmailAddress emailAddress);
}

使用特定模塊接口定義Repositoryui

interface MyRepository extends JpaRepository<User, Long> { }
 
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
  …
}
 
interface UserRepository extends MyBaseRepository<User, Long> {
  …
}

注意:中間層repository接口要使用註解@NoRepositoryBean,以確保Spring Data不會在運行時對其實例化。.net

定義查詢方法

查詢方法創建

  1. distinct flag
  2. ignoring case
  3. order by
public interface PersonRepository extends Repository<User, Long> {
 
  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
 
  // Enables the distinct flag for the query
  List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
 
  // Enabling ignoring case for an individual property
  List<Person> findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
 
  // Enabling static ORDER BY for a query
  List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

爲了消除不肯定性,能夠在方法名內使用下劃線「_」手動定義隔斷點。code

List<Person> findByAddress_ZipCode(ZipCode zipCode);

特殊參數處理

Page<User> findByLastname(String lastname, Pageable pageable);
 
Slice<User> findByLastname(String lastname, Pageable pageable);
 
List<User> findByLastname(String lastname, Sort sort);
 
List<User> findByLastname(String lastname, Pageable pageable);

限制查詢結果數量

User findFirstByOrderByLastnameAsc();
 
User findTopByOrderByAgeDesc();
 
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
 
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
 
List<User> findFirst10ByLastname(String lastname, Sort sort);
 
List<User> findTop10ByLastname(String lastname, Pageable pageable);

流式查詢結果

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
 
Stream<User> readAllByFirstnameNotNull();
 
@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

流在使用結束後須要關閉以釋放資源,能夠用 close() 方法手動將其關閉或者使用 try-with-resources 塊。繼承

  • try-with-resources 塊
try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
  stream.forEach(…);
}

異步查詢結果

  1. 使用 java.util.concurrent.Future 做爲返回類型
  2. 使用 Java 8 java.util.concurrent.CompletableFuture 做爲返回類型
  3. 使用 org.springframework.util.concurrent.ListenableFuture 做爲返回類型
@Async
Future<User> findByFirstname(String firstname);            
 
@Async
CompletableFuture<User> findOneByFirstname(String firstname);
 
@Async
ListenableFuture<User> 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<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> 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)

使用 @Query

基本用法

public interface UserRepository extends JpaRepository<User, Long> {
 
  @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);
}

使用 LIKE 表達式

public interface UserRepository extends JpaRepository<User, Long> {
 
  @Query("select u from User u where u.firstname like %?1")
  List<User> findByFirstnameEndsWith(String firstname);
}

使用原生SQL

public interface UserRepository extends JpaRepository<User, Long> {
 
  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
}

原生SQL分頁

public interface UserRepository extends JpaRepository<User, Long> {
 
  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);
}

使用 Sort 和 JpaSort

public interface UserRepository extends JpaRepository<User, Long> {
 
  @Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);
 
  @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
  List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
 
repo.findByAndSort("lannister", new Sort("firstname"));            
repo.findByAndSort("stark", new Sort("LENGTH(firstname)"));        
repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)"));
repo.findByAsArrayAndSort("bolton", new Sort("fn_len"));

使用已命名參數

public interface UserRepository extends JpaRepository<User, Long> {
 
  @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);
相關文章
相關標籤/搜索