最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Data?JPA查詢方式及方法名查詢規(guī)則介紹

 更新時(shí)間:2021年11月25日 11:06:06   作者:七星程序員  
這篇文章主要介紹了Spring?Data?JPA查詢方式及方法名查詢規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Spring Data JPA查詢方式及方法名查詢規(guī)則

Spring Data JPA

通過解析方法名創(chuàng)建查詢

在執(zhí)行查詢時(shí),Spring Data JPA框架會(huì)把方法名進(jìn)行解析,解析到前綴比如 get、getBy、find、findBy、read、readBy時(shí),會(huì)先把這些前綴截取掉,然后對(duì)剩下部分進(jìn)行解析,剩下部分分為兩種:一是只有屬性名,二是屬性名+條件;條件很好解析,解析的關(guān)鍵在于屬性名,下面拿一個(gè)具體的例子來幫助大家更好的理解屬性名解析規(guī)則。

解析規(guī)則例子:比如實(shí)體為Product,方法為findByGoodsTypeDetail ();

1、首先截取掉 findBy,然后對(duì)剩下的屬性進(jìn)行解析;

2、先判斷 goodsTypeDetail(根據(jù) POJO 規(guī)范,首字母變?yōu)樾?,下同)是否?Product的一個(gè)屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,繼續(xù)第三步;

3、從右往左截取第一個(gè)大寫字母開頭的字符串(本方法為 Detail),然后對(duì)比剩下的字符串(本方法為goodsType)是否為 Product的一個(gè)屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,則重復(fù)第三步,繼續(xù)從右往左截?。ù颂帪門ypeDetail,剩下goods),就這樣一直循環(huán)到最終;假設(shè) goods為 Product的一個(gè)屬性,則說明goods不是常量類型,而是一個(gè)對(duì)象類型;

4、此時(shí)剩下字符串 TypeDetail,先判斷goods對(duì)象中是否有 typeDetail屬性,如果有,則表示該方法最終是根據(jù) "Product.goods.typeDetail" 的值進(jìn)行查詢;如果沒有該屬性,則繼續(xù)按照第三步的規(guī)則從右往左截取,最終表示根據(jù) "Product.goods.type.detail" 的值進(jìn)行查詢。

不過這種解析規(guī)則不是完美的,也存在bug,不注意可能會(huì)掉到這個(gè)坑里,比如Product中有一個(gè)屬性叫g(shù)oods,同時(shí)還有一個(gè)屬性叫g(shù)oodsType,這時(shí)在解析時(shí)會(huì)出現(xiàn)混亂,不過可以在屬性之間加上 "_"來解決這個(gè)問題,注意:"_"是加在查詢方法上的,不是加在屬性名上的;比如 "findByGoods_TypeDetail()" (當(dāng)Product中不存在goods_TypeDetail時(shí),是給解析器說明Goods為一個(gè)對(duì)象)或"findByGoodsType_Detail()"(當(dāng)Product中不存在goodsType_Detail時(shí),是給解析器說明GoodsType為一個(gè)對(duì)象)。

查詢時(shí),很多時(shí)候需要同時(shí)使用多個(gè)屬性進(jìn)行查詢,而且查詢的條件也各不相同,Spring Data JPA 為此提供了一些條件查詢的關(guān)鍵字,我把常用的都整理了一下,如下表:

關(guān)鍵字

對(duì)應(yīng)SQL關(guān)鍵字

示例

列名

根據(jù)列名查詢

findByName(String name);自動(dòng)解析findBy后面的列名,然后根據(jù)列名查詢。

In

等價(jià)于SQL 中的 in

findByNameIn(Collection<String> nameList) ;參數(shù)可以是集合、數(shù)組、不定長(zhǎng)參數(shù);

Like

等價(jià)于SQL 中的 like

findByNameLike(String name);

NotLike 等價(jià)于SQL 中的 not like findByNameNotLike(String name);

And

等價(jià)于SQL 中的 and

findByNameAndPwd(String name, String pwd);

Or

等價(jià)于SQL 中的 or

findByIdOrCode(String id, String code);

Between

等價(jià)于SQL 中的 between

findByNumBetween(int max, int min);

OrderBy

等價(jià)于SQL 中的 order by

findByNameOrderByNumAsc(String name);

IsNull

等價(jià)于SQL 中的 is null

findByNameIsNull();

IsNotNull 等價(jià)于SQL 中的 is not null findByNameIsNotNull();
NotNull 等價(jià)于SQL 中的 is not null findByNameNotNull();--和IsNotNull 一樣,建議使用IsNotNull
Not 等價(jià)于SQL 中的 ! = findByNameNot(String name);
NotIn 等價(jià)于SQL 中的 not in findByNameNotIn(Collection<String> nameList) ;參數(shù)可以是集合、數(shù)組、不定長(zhǎng)參數(shù);
LessThan 等價(jià)于SQL 中的 < findByNumLessThan(int num);

GreaterThan

等價(jià)于SQL 中的 >

findByNumGreaterThan(int num);

使用 @Query 創(chuàng)建查詢

1、使用 @Query 提供的位置編號(hào)查詢:格式為":位置編號(hào)",然后方法中的參數(shù)按 JPQL 查詢語(yǔ)句的位置編號(hào)順序書寫。 如下:

public interface ProductDao extends Repository<Product , Long> {  
@Query("select * from Product p where p.id= ?1") 
public Product findById(Long id); 
 
@Query("select * from Product p where p.type = ?1 and p.name =?2") 
public Page<Product> findByTypeAndName( 
    Integer type,String name,Pageable pageable); 
}

2、使用@Query 命名參數(shù)查詢:格式為": 變量",同時(shí)在方法的參數(shù)前面使用 @Param 將方法參數(shù)與JPQL中的命名參數(shù)對(duì)應(yīng)。如下:

public interface ProductDao extends Repository<Product , Long> {  
@Query("from Product p where p.goodsName= :name") 
public Product findByGoodsName(@Param("name")String name);  
@Query("from Product p where p.num < :num") 
public Page<Product> findByNumLessThan( 
    @Param("num")Integer num,Pageable pageable); 
}

3、 使用 @Modifying 將查詢操作標(biāo)識(shí)為更新操作:在使用 @Query 的同時(shí)使用 @Modifying ,這樣會(huì)生成一個(gè)更新的操作,而非查詢。如下:

 
@Query("update Product p set p.name = ?1 where p.id = ?2") 
@Modifying 
public int updateName(String name, int id);

JPA 常用查詢方法記錄

以這張表為例:

+-------------+--------------+------+-----+-------------------+----------------+
| Field       | Type         | Null | Key | Default           | Extra          |
+-------------+--------------+------+-----+-------------------+----------------+
| id          | int(11)      | NO   | PRI | NULL              | auto_increment |
| role        | varchar(45)  | NO   |     | NULL              |                |
| permissions | varchar(512) | NO   |     | NULL              |                |
| create_time | datetime     | NO   |     | CURRENT_TIMESTAMP |                |
| status      | varchar(45)  | NO   |     | NULL              |                |
| role_name   | varchar(45)  | NO   |     | NULL              |                |
+-------------+--------------+------+-----+-------------------+----------------+

CrudRepository 默認(rèn)帶的查詢方法

@Repository
public interface RoleRepository extends CrudRepository<RoleData, Integer> {
}  
@Entity
@Table(name = "role", catalog = "message_push")
public class RoleData implements java.io.Serializable {
 
    @Id
    @GeneratedValue
    private Integer id; 
    private String role; 
    private String permissions; 
    private Long create_time; 
    private Integer status; 
// getter setter 構(gòu)造函數(shù)從略 
}

簡(jiǎn)單的擴(kuò)展-以字段為關(guān)鍵字進(jìn)行查詢

list<RoleData> findByXXX(xxx) 其中 XXX 對(duì)應(yīng)數(shù)據(jù)庫(kù)中的字段,例如:

@Repository
public interface RoleRepository extends CrudRepository<RoleData, Integer> { 
    List<RoleData> findByRole(String role);
    List<RoleData> findByStatus(String status);
}

還可以多字段AND 查詢:

@Repository
public interface RoleRepository extends CrudRepository<RoleData, Integer> { 
    List<RoleData> findByRoleAndStatus(String role, String status);
}

在 application.properties 中加入以下配置 spring.jpa.show-sql=true 可以看到SQL語(yǔ)句:

Hibernate: select roledata0_.id as id1_0_, roledata0_.create_time as create_t2_0_, roledata0_.permissions as permissi3_0_, roledata0_.role as role4_0_, roledata0_.status as status5_0_ from message_push.role roledata0_ where roledata0_.role=? and roledata0_.status=?

當(dāng)然 or 也是可以:

    List<RoleData> findByRoleOrStatus(String role, String status);

Hibernate: select roledata0_.id as id1_0_, roledata0_.create_time as create_t2_0_, roledata0_.permissions as permissi3_0_, roledata0_.role as role4_0_, roledata0_.status as status5_0_ from message_push.role roledata0_ where roledata0_.role=? or roledata0_.status=?

使用@Query 進(jìn)行復(fù)雜查詢

例如:

@Query(value = "select * from role where role = ?1", nativeQuery = true)
List<RoleData> searchByRole(String role);

或 sql in 用法

@Query(value = "select * from role where role in (?1) and status = 'valid'", nativeQuery = true)
List<RoleData> searchByRoleList(List<String> targetList);

又或 sql like 用法:

@Query(value = "select * from role where role like %?1%", nativeQuery = true)
List<RoleData> searchByRole(String keyWord);

使用 Specification 進(jìn)行復(fù)雜查詢

先來看一下 JpaSpecificationExecutor 接口

以 findAll(Specification<T>) 為例進(jìn)行說明:

Specification<T> 可以理解為一個(gè)查詢條件。findAll 以這個(gè)條件為基準(zhǔn)進(jìn)行查詢,也就是我們?cè)趕ql 里寫的 whre xxx 轉(zhuǎn)為 Specification 來寫。

首先要讓我們的 repository 繼承 JpaSpecificationExecutor

@Repository
public interface RoleRepository extends CrudRepository<RoleData, Integer>, JpaSpecificationExecutor<RoleData> {

接下來,將這個(gè)查詢 [ select * from role where role like '%a%' ] 轉(zhuǎn)為一個(gè)簡(jiǎn)單的 Specification。

        final Specification<RoleData> spec = new Specification<RoleData> () {
            @Override
            public Predicate toPredicate(Root<RoleData> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.like(root.get("role"), "%a%");
                return predicate;
            }
        };

然后直接按如下方式調(diào)用即可:

roleRepository.findAll(spec);

Specification 里又衍生出了好幾個(gè)類,分別介紹一下:

Predicate

因?yàn)槲覀儗?shí)現(xiàn) Specification 接口時(shí),只需要實(shí)現(xiàn) Predicate toPredicate() 方法。而 Specification 上文中我們當(dāng)做搜索條件來理解了,那么也可以簡(jiǎn)單的把 Predicate 視為搜索條件。

CriteriaBuilder

用于構(gòu)建搜索條件 Predicater 的。

回想一下SQL搜索條件怎么寫

where attribute = xx
where attribute > xx 
where attribute < xx
where attribute like %xx%

注意這里有三要素:

  • attribute 搜索指定的數(shù)據(jù)庫(kù)字段
  • 操作符 大于 小于 等于
  • 具體數(shù)據(jù)

CriteriaBuilder提供了一系列靜態(tài)方法構(gòu)建這三要素。

比如

  • CriteriaBuilder.like(數(shù)據(jù)庫(kù)字段, 具體數(shù)據(jù))
  • CriteriaBuilder.equal(數(shù)據(jù)庫(kù)字段, 具體數(shù)據(jù))

其中 數(shù)據(jù)庫(kù)字段 不能直接寫字符串,需要下一個(gè)工具類 Root 的 get 方法獲取。

Root

root.get( String attributeName ) 參數(shù) attributeName 就是數(shù)據(jù)庫(kù)里的字段名

現(xiàn)在相信讀者可以理解 我們剛才寫的 那個(gè)完整的 Specification了。

再下來再上一個(gè)稍微復(fù)雜點(diǎn)的例子:

[  select * from role where role like '%a%' and (id > 11 or id < 8) ] 
        final Specification<RoleData> spec = new Specification<RoleData> () {
            @Override
            public Predicate toPredicate(Root<RoleData> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate roleLikeaPredicate = criteriaBuilder.like(root.get("role"), "%a%");
                Predicate idLessThan8Predicate = criteriaBuilder.lessThan(root.get("id"), 8);
                Predicate idGreaterThan12Predicate = criteriaBuilder.greaterThan(root.get("id"), 11);
 
                Predicate idCombindedPredicate = criteriaBuilder.or(idLessThan8Predicate, idGreaterThan12Predicate);
                Predicate predicate = criteriaBuilder.and(idCombindedPredicate, roleLikeaPredicate); 
                return predicate;
            }
        };

其實(shí)也很簡(jiǎn)單,就是多了 criteriaBuilder.or criteriaBuilder.and 來把多個(gè) Predicate 合成一個(gè)新的 Predicate

最后一個(gè)例子:

可以通過root.get(xx).in(List<> list) 也是可以直接返回 Predicate 的

 
        final Specification<RoleData> spec2 = new Specification<RoleData> () {
            @Override
            public Predicate toPredicate(Root<RoleData> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<String> alist = new ArrayList<String>();
                alist.add("admin");
                Predicate predicate = root.get("role").in(alist);
                return predicate;
            }
        };

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Cloud Ubuntu環(huán)境部署的步驟與注意事項(xiàng)

    Spring Cloud Ubuntu環(huán)境部署的步驟與注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于Spring Cloud Ubuntu環(huán)境部署的步驟與注意事項(xiàng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Cloud具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Spring?Boot使用線程池處理上萬(wàn)條數(shù)據(jù)插入功能

    Spring?Boot使用線程池處理上萬(wàn)條數(shù)據(jù)插入功能

    這篇文章主要介紹了Spring?Boot使用線程池處理上萬(wàn)條數(shù)據(jù)插入功能,使用步驟是先創(chuàng)建一個(gè)線程池的配置,讓Spring Boot加載,用來定義如何創(chuàng)建一個(gè)ThreadPoolTaskExecutor,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-08-08
  • 深入理解java泛型Generic

    深入理解java泛型Generic

    這篇文章主要介紹了深入理解java泛型Generic,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • java?stream實(shí)現(xiàn)分組BigDecimal求和以及自定義分組求和

    java?stream實(shí)現(xiàn)分組BigDecimal求和以及自定義分組求和

    這篇文章主要給大家介紹了關(guān)于java?stream實(shí)現(xiàn)分組BigDecimal求和以及自定義分組求和的相關(guān)資料,Stream是Java8的一大亮點(diǎn),是對(duì)容器對(duì)象功能的增強(qiáng),它專注于對(duì)容器對(duì)象進(jìn)行各種非常便利、高效的聚合操作或者大批量數(shù)據(jù)操作,需要的朋友可以參考下
    2023-12-12
  • Spring Cloud 系列之注冊(cè)中心 Eureka詳解

    Spring Cloud 系列之注冊(cè)中心 Eureka詳解

    Netflix Eureka 是由 Netflix 開源的一款基于 REST 的服務(wù)發(fā)現(xiàn)組件,包括 Eureka Server 及 Eureka Client。這篇文章主要介紹了Spring Cloud 系列之注冊(cè)中心 Eureka,需要的朋友可以參考下
    2020-11-11
  • java基于C/S結(jié)構(gòu)實(shí)現(xiàn)多線程聊天室

    java基于C/S結(jié)構(gòu)實(shí)現(xiàn)多線程聊天室

    這篇文章主要為大家詳細(xì)介紹了java基于C/S結(jié)構(gòu)實(shí)現(xiàn)多線程聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 簡(jiǎn)單了解Spring Framework5.0新特性

    簡(jiǎn)單了解Spring Framework5.0新特性

    這篇文章主要介紹了簡(jiǎn)單了解Spring Framework5.0新特性,涉及了核心框架修訂,核心容器更新,使用Kotlin進(jìn)行函數(shù)式編程等幾個(gè)方面的介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 全面分析Java方法的使用與遞歸

    全面分析Java方法的使用與遞歸

    在java中,方法就是用來完成解決某件事情或?qū)崿F(xiàn)某個(gè)功能的辦法;程序調(diào)用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種算法在程序設(shè)計(jì)語(yǔ)言中廣泛應(yīng)用。但是如果沒終止條件會(huì)造成死循環(huán),所以遞歸代碼里要有結(jié)束自調(diào)自的條件,本篇接下來講解一下方法與遞歸
    2022-04-04
  • Java中的泛型方法詳解及簡(jiǎn)單實(shí)例

    Java中的泛型方法詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Java中的泛型方法詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xxxController required

    解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xx

    這篇文章主要介紹了解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xxxContr問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論

广西| 城固县| 陆丰市| 恩平市| 慈利县| 金溪县| 八宿县| 邯郸县| 旅游| 常德市| 汉川市| 亳州市| 无棣县| 阳高县| 怀仁县| 玉屏| 连江县| 林口县| 溆浦县| 周至县| 醴陵市| 彰化市| 乌拉特后旗| 清新县| 靖西县| 凤山县| 玉山县| 上栗县| 苍山县| 青田县| 台江县| 永修县| 榆林市| 章丘市| 洞头县| 盐津县| 克什克腾旗| 延吉市| 泽普县| 华坪县| 尼勒克县|