springjpa(4)-JpaRepository

springjpa合集地址:https://www.jianshu.com/nb/38441578

先看看JpaRepository的繼承樹,從繼承樹可以看出來JapRepository除了繼承了Repository那邊的路線外,還繼承了一個新的接口——QueryByExampleExecutor

QueryByExampleExecutor

很多時候我們的crud項目中有複雜查詢功能,頁面有很多的查詢字段,這些字段都是表結構的某個字段。

QueryByExampleExecutor接口

QueryByExampleExecutor接口能實現較爲簡單的上述功能。

public interface QueryByExampleExecutor<T> {
    <S extends T> Optional<S> findOne(Example<S> example);
    <S extends T> Iterable<S> findAll(Example<S> example);
    <S extends T> Iterable<S> findAll(Example<S> example, Sort sort);
    <S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
    <S extends T> boolean exists(Example<S> example);
}

我們將關注點放在findAll(Example<S> example)方法上,它接收一個Example實例,這個實例就是查詢條件,它由具體的表對象而來。這個方法的返回值是Iterable對象,需要進行轉換後才能傳遞到前端

Example接口

Example提供了兩個靜態方法用於將表對象轉換成Example對象

public interface Example<T> {
    static <T> Example<T> of(T probe) {
        return new TypedExample<>(probe, ExampleMatcher.matching());
    }
    static <T> Example<T> of(T probe, ExampleMatcher matcher) {
        return new TypedExample<>(probe, matcher);
    }
    //省略...
}
1. of(T probe)
//舉個例子,我們要查詢用戶中年齡等於12,城市在南京,姓名等於張三的用戶。
User user=new User();
user.setAge(12);
user.setCity("南京");
user.setName("張三");
Example example=Example.of(user);
Iterable<User> users=userRepository.findAll(example);

第一種是精確值查詢,所有不爲null的字段(空字符串不算null)都會作爲條件進行查詢。

2. of(probe,match)

第二種和第一種的區別就是多了一個ExampleMatcher,它是一個匹配器,用於表示具體怎麼匹配。它可以對字符串條件做處理,例如模糊查詢。注意非字符串條件無法做處理,只能精確查詢。

//例如,我們要查詢姓張的用戶---> name like '張%'
User user=new User();
user.setName("張");
//創建一個匹配器,並設置姓名只要以給的條件開始就可以,不需要精確查詢
ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
Example example=Example.of(user,matcher);
Iterable<User> users=userRepository.findAll(example);

ExampleMatcher接口

public interface ExampleMatcher {
    static ExampleMatcher matching() {
        return matchingAll();
    }
    static ExampleMatcher matchingAny() {
        return new TypedExampleMatcher().withMode(MatchMode.ANY);
    }
    static ExampleMatcher matchingAll() {
        return new TypedExampleMatcher().withMode(MatchMode.ALL);
    }
    //...
}

ExampleMatcher接口提供了三個靜態方法用於創建一個匹配器,觀察這三個方法,其實區別就是any和all的區別。

any指的是所有的條件只要有一個滿足就篩選出來。---> where age=12 or city='南京' or name like '張三%'。

all指的是所有的條件都滿足才篩選出來。---> where age=12 and city='南京' and name like '張三%'。

創建完實例以後我們可以採用鏈式編程的方式追加規則。例如

ExampleMatcher matcher = ExampleMatcher.matching()
                //where name like 'XXX%'
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
                //where name like '%XXX'
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.endsWith())
                //where name like '%XXX%'
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                //name忽略大小寫
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.ignoreCase())
                //name大小寫敏感,不忽略大小寫,默認
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.caseSensitive())、
                //name正則查詢
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.regex())
                //忽略id和age條件,即使id和age不爲空也不作爲查詢條件
                .withIgnorePaths("id", "age")
                //忽略大小寫
                .withIgnoreCase("name","city")
                //忽略null值條件(默認)
                .withIgnoreNullValues()
                //不忽略null值條件,如果條件爲null,那麼就按照is null查詢
                .withIncludeNullValues();

JpaRepository

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();
    List<T> findAll(Sort var1);
    List<T> findAllById(Iterable<ID> var1);
    <S extends T> List<S> saveAll(Iterable<S> var1);
    void flush();
    <S extends T> S saveAndFlush(S var1);
    void deleteInBatch(Iterable<T> var1);
    void deleteAllInBatch();
    T getOne(ID var1);
    <S extends T> List<S> findAll(Example<S> var1);
    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

除了繼承的PagingAndSortingRepository和QueryByExampleExecutor接口外,還增加了一些新的方法,例如皮批量增加刪除之類。繼承JpaRepository以後findAll方法返回的是List,不用再轉換了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章