美文网首页程序员Java学习笔记Spring Boot
Spring Data JPA 指南——整理自官方参考文档

Spring Data JPA 指南——整理自官方参考文档

作者: lzp4ever | 来源:发表于2017-03-29 16:06 被阅读3433次

    [TOC]

    基本使用方法

    继承接口并声明查询方法

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

    Autowired注入

    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);
    }
    

    使用特定模块接口定义Repository

    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不会在运行时对其实例化。

    定义查询方法

    查询方法建立

    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);
    }
    

    为了消除不确定性,可以在方法名内使用下划线“_”手动定义隔断点。

    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);
    

    相关文章

      网友评论

        本文标题:Spring Data JPA 指南——整理自官方参考文档

        本文链接:https://www.haomeiwen.com/subject/ctxyottx.html