欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring的data派生查詢(xún)機(jī)制的實(shí)現(xiàn)

 更新時(shí)間:2025年03月19日 10:27:33   作者:LCY133  
SpringData的派生查詢(xún)是一種通過(guò)方法名約定自動(dòng)生成數(shù)據(jù)庫(kù)查詢(xún)的機(jī)制,無(wú)需手動(dòng)編寫(xiě)SQL或JPQL,下面就來(lái)介紹一下spring data派生查詢(xún)的實(shí)現(xiàn),感興趣的可以了解一下

Spring Data 的 派生查詢(xún)(Derived Query) 是一種通過(guò) 方法名約定 自動(dòng)生成數(shù)據(jù)庫(kù)查詢(xún)的機(jī)制,無(wú)需手動(dòng)編寫(xiě) SQL 或 JPQL。以下是其核心原理和用法的詳細(xì)解析:

一、核心機(jī)制

1. 方法名解析規(guī)則

Spring Data 根據(jù) 方法名的結(jié)構(gòu) 解析出查詢(xún)邏輯,生成對(duì)應(yīng)的數(shù)據(jù)庫(kù)查詢(xún)。
關(guān)鍵步驟:

  • 拆分方法名:以 findBy、existsBy、deleteBy 等關(guān)鍵字為分隔符,提取查詢(xún)條件。
  • 解析屬性路徑:將方法名中的屬性名(如 name)映射到實(shí)體類(lèi)的字段。
  • 識(shí)別操作符:通過(guò)關(guān)鍵字(如 And、Or、LessThan)確定查詢(xún)條件的關(guān)系和操作。

2. 動(dòng)態(tài)代理實(shí)現(xiàn)

• 接口代理:Spring Data 在運(yùn)行時(shí)為 Repository 接口生成動(dòng)態(tài)代理類(lèi)。
• 查詢(xún)構(gòu)建:根據(jù)方法名,代理類(lèi)生成對(duì)應(yīng)的 Criteria 或 MongoDB 的 Query 對(duì)象。

二、方法命名規(guī)范

1. 方法前綴

前綴作用示例
findBy查詢(xún)并返回結(jié)果findByName(String name)
existsBy檢查是否存在記錄existsByEmail(String email)
deleteBy刪除符合條件的記錄deleteByStatus(Status status)
countBy統(tǒng)計(jì)符合條件的記錄數(shù)countByAgeGreaterThan(int age)

2. 條件關(guān)鍵字

關(guān)鍵字操作符示例
AndAND 連接多個(gè)條件findByNameAndAge
OrOR 連接多個(gè)條件findByNameOrEmail
Is/Equals等于 (=)findByEmailIs
LessThan小于 (<)findByAgeLessThan
Like模糊匹配 (%value%)findByNameLike
Null/NotNull字段為空/非空findByDescriptionNull

3. 特殊語(yǔ)法

• 忽略大小寫(xiě):findByNameIgnoreCase• 排序:findByOrderByNameAsc• 分頁(yè):findByName(String name, Pageable pageable)

三、實(shí)現(xiàn)原理(以 MongoDB 為例)

1. 方法名到查詢(xún)的轉(zhuǎn)換

假設(shè)定義方法:

fun findByModelIdAndName(modelId: ObjectId, name: String): List<ScenarioField>

生成邏輯:

解析條件:ModelId 和 Name 為實(shí)體字段。

構(gòu)建查詢(xún):

db.scenarioField.find({
  modelId: ObjectId("xxx"),
  name: "xxx"
})

2. 復(fù)雜查詢(xún)示例

fun existsByIdIsNotAndNameAndModelId(id: ObjectId?, name: String, modelId: ObjectId): Boolean

轉(zhuǎn)換后的 MongoDB 查詢(xún):

db.scenarioField.exists({
  name: "xxx",
  modelId: ObjectId("xxx"),
  _id: { $ne: ObjectId("xxx") }  // 當(dāng) id 非空時(shí)
})

四、高級(jí)用法

1. 嵌套屬性查詢(xún)

若實(shí)體包含嵌套對(duì)象 User,可查詢(xún)嵌套字段:

interface UserRepository : MongoRepository<User, ObjectId> {
    fun findByAddressCity(city: String): List<User>
}

對(duì)應(yīng)實(shí)體:

data class User(
    val name: String,
    val address: Address
)

data class Address(
    val city: String,
    val street: String
)

2. 自定義返回類(lèi)型

支持返回 部分字段 或 DTO 投影:

interface UserRepository : MongoRepository<User, ObjectId> {
    fun findNameByEmail(email: String): String
}

3. 組合注解查詢(xún)

與 @Query 注解結(jié)合,處理復(fù)雜邏輯:

@Query("{'modelId': ?0, 'status': { \$in: ?1 }}")
fun findByModelIdAndStatusIn(modelId: ObjectId, statuses: List<Status>): List<ScenarioField>

五、最佳實(shí)踐與限制

1. 適用場(chǎng)景

簡(jiǎn)單查詢(xún):快速實(shí)現(xiàn) CRUD 操作。
動(dòng)態(tài)條件:通過(guò)方法名靈活組合條件。
快速原型開(kāi)發(fā):減少樣板代碼。

2. 局限性

復(fù)雜查詢(xún):多表關(guān)聯(lián)、聚合操作需手動(dòng)編寫(xiě) @Query。
命名冗長(zhǎng):深度嵌套屬性可能導(dǎo)致方法名過(guò)長(zhǎng)。
性能陷阱:未優(yōu)化索引時(shí),復(fù)雜條件可能影響性能。

3. 調(diào)試技巧

開(kāi)啟日志:查看生成的查詢(xún)語(yǔ)句:

logging.level.org.springframework.data.mongodb.core=DEBUG

 驗(yàn)證方法名:確保屬性名與實(shí)體字段 嚴(yán)格匹配。

六、總結(jié)

Spring Data 的派生查詢(xún)機(jī)制通過(guò) 約定優(yōu)于配置 的方式,將方法名轉(zhuǎn)化為數(shù)據(jù)庫(kù)查詢(xún),其核心價(jià)值在于:

  • 簡(jiǎn)化開(kāi)發(fā):減少手動(dòng)編寫(xiě)查詢(xún)的工作量。
  • 提升可讀性:方法名直接反映業(yè)務(wù)邏輯。
  • 類(lèi)型安全:編譯時(shí)檢查屬性名合法性。

合理使用派生查詢(xún),可顯著提高開(kāi)發(fā)效率,但在復(fù)雜場(chǎng)景下需結(jié)合 @Query 或自定義實(shí)現(xiàn)靈活應(yīng)對(duì)。

示例如下:

方法 deleteAllByModelId 與 existsByIdIsNotAndNameAndModelId 詳解

1. deleteAllByModelId(modelId: ObjectId)

1.1 定義依據(jù)

• Spring Data 派生查詢(xún)機(jī)制基于 方法名命名規(guī)則,Spring Data MongoDB 自動(dòng)解析方法名并生成對(duì)應(yīng)的刪除操作。
• deleteAllBy:表示刪除所有符合條件的文檔。
• ModelId:映射到實(shí)體字段 modelId,需與 ScenarioField 類(lèi)中的屬性名嚴(yán)格一致。

1.2 實(shí)現(xiàn)的功能

• 操作類(lèi)型:批量刪除。
• 查詢(xún)條件:刪除所有 modelId 字段等于參數(shù)值的文檔。
• 等效 MongoDB 查詢(xún):

db.scenarioField.deleteMany({ modelId: ObjectId("xxx") })

1.3 使用場(chǎng)景

• 模型級(jí)聯(lián)刪除:當(dāng)刪除一個(gè)模型(Model)時(shí),同步清理其關(guān)聯(lián)的所有場(chǎng)景項(xiàng)(ScenarioField)。
• 數(shù)據(jù)維護(hù):批量清理無(wú)效或測(cè)試數(shù)據(jù)。

1.4 技術(shù)細(xì)節(jié)

• 方法名解析流程:

1. deleteAllBy → 刪除操作(對(duì)應(yīng) `deleteMany`)  
2. ModelId → 條件字段名 `modelId`  

• 參數(shù)類(lèi)型匹配:ObjectId 確保與 MongoDB 的 _id 類(lèi)型兼容。
• 事務(wù)性:若父類(lèi)或方法上有 @Transactional,操作將在一個(gè)事務(wù)中執(zhí)行。

2. existsByIdIsNotAndNameAndModelId(id: ObjectId?, name:String, modelId: ObjectId): Boolean

2.1 定義依據(jù)

• Spring Data 派生查詢(xún)規(guī)則通過(guò)方法名中的 條件表達(dá)式 動(dòng)態(tài)生成查詢(xún)邏輯:
• existsBy:檢查是否存在符合條件的文檔(返回 true/false)。
• IdIsNotid 字段不等于參數(shù)值(對(duì)應(yīng) id != {id})。
• Name 和 ModelId:字段等于參數(shù)值(對(duì)應(yīng) name = {name} 和 modelId = {modelId})。

2.2 實(shí)現(xiàn)的功能

• 操作類(lèi)型:存在性檢查。
• 查詢(xún)條件:

WHERE name = {name} 
  AND modelId = {modelId} 
  AND id != {id} (如果 id 不為空)

• 等效 MongoDB 查詢(xún):

db.scenarioField.exists({
  name: "xxx",
  modelId: ObjectId("xxx"),
  _id: { $ne: ObjectId("xxx") } // 當(dāng) id 不為空時(shí)
})

2.3 使用場(chǎng)景

• 唯一性校驗(yàn):
• 新增場(chǎng)景項(xiàng):檢查同一模型下是否存在同名項(xiàng)(此時(shí) id 為 null,條件簡(jiǎn)化為 name 和 modelId)。
• 更新場(chǎng)景項(xiàng):確保修改后的名稱(chēng)不與同模型下其他項(xiàng)重復(fù)(排除自身 id)。

2.4 技術(shù)細(xì)節(jié)

• 方法名解析流程:

1. existsBy → 存在性檢查(對(duì)應(yīng) `count` > 0)  
2. IdIsNot → 轉(zhuǎn)換為 `_id: { $ne: id }`  
3. Name → `name = {name}`  
4. ModelId → `modelId = {modelId}`  

參數(shù)處理:

  • 可空 id:若 id 為 null,IdIsNot 條件會(huì)被忽略,查詢(xún)僅基于 name 和 modelId。
  • 字段映射:需確保 ScenarioField 實(shí)體包含 idname、modelId 屬性,并與數(shù)據(jù)庫(kù)字段匹配(默認(rèn)駝峰轉(zhuǎn)下劃線(xiàn))。

性能優(yōu)化:
建議在 modelId 和 name 上創(chuàng)建 復(fù)合索引,加速查詢(xún):

db.scenarioField.createIndex({ modelId: 1, name: 1 })

3. 完整代碼示例與驗(yàn)證

3.1 實(shí)體定義

@Document(collection = "scenarioField")
data class ScenarioField(
    @Id
    val id: ObjectId? = null,
    val name: String,
    val modelId: ObjectId
)

3.2 測(cè)試用例

// 測(cè)試存在性檢查(新增場(chǎng)景)
fun testExistsForCreate() {
    val modelId = ObjectId()
    scenarioFieldRepository.save(ScenarioField(name = "Field1", modelId = modelId))
    
    val exists = scenarioFieldRepository.existsByIdIsNotAndNameAndModelId(null, "Field1", modelId)
    assertTrue(exists) // 應(yīng)返回 true
}

// 測(cè)試存在性檢查(更新場(chǎng)景)
fun testExistsForUpdate() {
    val modelId = ObjectId()
    val field = scenarioFieldRepository.save(ScenarioField(name = "Field1", modelId = modelId))
    
    // 嘗試修改為同名
    val exists = scenarioFieldRepository.existsByIdIsNotAndNameAndModelId(field.id, "Field1", modelId)
    assertFalse(exists) // 應(yīng)返回 false(僅自身匹配)
}

// 測(cè)試批量刪除
fun testDeleteByModelId() {
    val modelId = ObjectId()
    scenarioFieldRepository.save(ScenarioField(name = "Field1", modelId = modelId))
    scenarioFieldRepository.save(ScenarioField(name = "Field2", modelId = modelId))
    
    scenarioFieldRepository.deleteAllByModelId(modelId)
    val count = scenarioFieldRepository.countByModelId(modelId)
    assertEquals(0, count)
}

4. 總結(jié)

方法核心作用技術(shù)實(shí)現(xiàn)業(yè)務(wù)場(chǎng)景
deleteAllByModelId按模型ID批量刪除場(chǎng)景項(xiàng)Spring Data 派生查詢(xún)生成 deleteMany模型刪除時(shí)清理關(guān)聯(lián)數(shù)據(jù)
existsByIdIsNotAndNameAndModelId校驗(yàn)同一模型下名稱(chēng)唯一性(排除自身)動(dòng)態(tài)生成 $ne 和等值條件新增/更新時(shí)防止數(shù)據(jù)重復(fù)

 Spring Data 優(yōu)勢(shì):通過(guò)方法名約定減少手寫(xiě)查詢(xún)代碼,提升開(kāi)發(fā)效率。

注意事項(xiàng):

  • 嚴(yán)格遵循命名規(guī)則,避免字段名拼寫(xiě)錯(cuò)誤。
  • 對(duì)高頻查詢(xún)字段建立索引,優(yōu)化性能。
  • 可空參數(shù)需在業(yè)務(wù)邏輯中處理邊界條件(如 id 為 null 時(shí)的行為)。

到此這篇關(guān)于spring的data派生查詢(xún)機(jī)制的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)spring data派生查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中關(guān)于命令執(zhí)行匯總

    java中關(guān)于命令執(zhí)行匯總

    這篇文章主要介紹了java中關(guān)于命令執(zhí)行匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 如何使用axis調(diào)用WebService及Java?WebService調(diào)用工具類(lèi)

    如何使用axis調(diào)用WebService及Java?WebService調(diào)用工具類(lèi)

    Axis是一個(gè)基于Java的Web服務(wù)框架,可以用來(lái)調(diào)用Web服務(wù)接口,下面這篇文章主要給大家介紹了關(guān)于如何使用axis調(diào)用WebService及Java?WebService調(diào)用工具類(lèi)的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Spring + Spring Boot + MyBatis + MongoDB的整合教程

    Spring + Spring Boot + MyBatis + MongoDB的整合教程

    這篇文章主要給大家介紹了關(guān)于Spring + Spring Boot + MyBatis + MongoDB的整合教程,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-12-12
  • Java中為什么ArrayList初始化容量大小為10

    Java中為什么ArrayList初始化容量大小為10

    這篇文章主要介紹了Java中為什么ArrayList初始化容量大小為10,帶著問(wèn)題圍展開(kāi)詳細(xì)的介紹,感興趣的小伙伴可以參考一下
    2022-06-06
  • Spring框架依賴(lài)注入方法示例

    Spring框架依賴(lài)注入方法示例

    這篇文章主要介紹了Spring框架依賴(lài)注入方法示例,分享了三種方法示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java圖書(shū)管理系統(tǒng),課程設(shè)計(jì)必用(源碼+文檔)

    Java圖書(shū)管理系統(tǒng),課程設(shè)計(jì)必用(源碼+文檔)

    本系統(tǒng)采用Java,MySQL 作為系統(tǒng)數(shù)據(jù)庫(kù),重點(diǎn)開(kāi)發(fā)并實(shí)現(xiàn)了系統(tǒng)各個(gè)核心功能模塊,包括采編模塊、典藏模塊、基礎(chǔ)信息模塊、流通模塊、期刊模塊、查詢(xún)模塊、評(píng)論模塊、系統(tǒng)統(tǒng)計(jì)模塊以及幫助功能模塊
    2021-06-06
  • java實(shí)現(xiàn)對(duì)Hadoop的操作

    java實(shí)現(xiàn)對(duì)Hadoop的操作

    這篇文章主要介紹了java實(shí)現(xiàn)對(duì)Hadoop的操作,通過(guò)非常完整詳細(xì)的代碼展示了如何去進(jìn)行一系列操作,包括基本操作,文件讀寫(xiě),需要的朋友可以參考下
    2021-07-07
  • java中BigDecimal的操作方法

    java中BigDecimal的操作方法

    這篇文章主要介紹了java中BigDecimal的操作方法,較為詳細(xì)的分析了BigDecimal類(lèi)在進(jìn)行商業(yè)計(jì)算時(shí)的應(yīng)用方法,精度以及注意事項(xiàng)等問(wèn)題,需要的朋友可以參考下
    2014-12-12
  • Mac中IntelliJ IDEA 2019.1注冊(cè)過(guò)程分享

    Mac中IntelliJ IDEA 2019.1注冊(cè)過(guò)程分享

    這篇文章主要介紹了Mac中IntelliJ IDEA 2019.1注冊(cè)過(guò)程,本文給大家分享到腳本之家平臺(tái)供大家學(xué)習(xí),需要的朋友可以參考下
    2020-02-02
  • spring boot實(shí)現(xiàn)profiles動(dòng)態(tài)切換的示例

    spring boot實(shí)現(xiàn)profiles動(dòng)態(tài)切換的示例

    Spring Boot支持在不同的環(huán)境下使用不同的配置文件,該技術(shù)非常有利于持續(xù)集成,在構(gòu)建項(xiàng)目的時(shí)候只需要使用不同的構(gòu)建命令就可以生成不同運(yùn)行環(huán)境下war包,而不需要手動(dòng)切換配置文件。
    2020-10-10

最新評(píng)論