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

MyBatis?動態(tài)SQL使用及原理

 更新時間:2023年05月12日 08:44:21   作者:Cosolar  
這篇文章主要為大家介紹了MyBatis動態(tài)SQL使用及原理的學習詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

MyBatis 是一個優(yōu)秀的持久層框架,它提供了豐富的 SQL 映射功能,可以讓我們通過 XML 或注解方式來定義 SQL 語句。它很大程度上簡化了數據庫操作,提高了開發(fā)效率。動態(tài) SQL 是其中一個非常重要的功能,可以讓我們根據不同的條件動態(tài)生成 SQL 語句,提高了 SQL 的靈活性和可重用性。本文將詳細介紹 MyBatis 的動態(tài) SQL 使用與原理。

1. 動態(tài)SQL概述

動態(tài)SQL是指根據條件拼接SQL語句的功能,可以在SQL語句中添加或者刪除某些條件和語句。在實際開發(fā)中,我們經常需要根據不同的條件拼接不同的SQL語句。如果只使用靜態(tài)SQL,會使得代碼冗余度高、可讀性差、維護成本高等問題。而使用動態(tài)SQL可以很好地解決這些問題。

MyBatis中提供了很多種方式來實現動態(tài)SQL,包括if、choose、when、otherwise、trim、where、set等。

2. if標簽

if標簽是MyBatis中最常用的動態(tài)SQL標簽之一。它通常用來判斷條件是否成立,從而確定是否加入SQL語句中。下面是一段示例代碼:

<select id="selectUsers" resultMap="UserResultMap">
    SELECT * FROM Users 
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

上述代碼中,通過if標簽的test屬性來判斷條件是否成立。只有當"name"和"age"都不為空時,才會將其加入到SQL語句中。這樣就可以在不同的情況下生成不同的SQL語句。

3. choose、when和otherwise標簽

choose、when和otherwise標簽通常一起使用,它類似于Java中的switch語句。下面是一段示例代碼:

<select id="selectUsers" resultMap="UserResultMap">
    SELECT * FROM Users 
    <where>
        <choose>
            <when test="name != null">
                AND name = #{name}
            </when>
            <when test="age != null">
                AND age = #{age}
            </when>
            <otherwise>
                AND id > 0
            </otherwise>
        </choose>
    </where>
</select>

choose、when和otherwise標簽中,如果test條件成立,就會將當前標簽中的SQL語句加入到最終的SQL語句中。只有一個可以成立,多個成立時按順序第一個生效。

4. trim標簽

trim標簽通常用來去掉特定字符或者關鍵字。下面是一段示例代碼:

<select id="selectUsers" resultMap="UserResultMap">
    SELECT * FROM Users 
    <where>
        <trim prefix="AND" prefixOverrides="OR">
            <if test="name != null">
                OR name = #{name}
            </if>
            <if test="age != null">
                OR age = #{age}
            </if>
        </trim>
    </where>
</select>

上述代碼中,prefix屬性表示在標簽內部SQL語句前添加的字符;prefixOverrides屬性表示從標簽內部SQL語句開頭去除的字符串。

5. set標簽和where標簽

set標簽通常用來更新參數對象中的非空屬性。where標簽通常用來拼接SQL語句中的where條件。下面是一段示例代碼:

<update id="updateUser" parameterType="User">
    UPDATE Users 
    <set>
        <if test="name != null">
            name = #{name},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
    </set>
    <where>
        id = #{id}
    </where>
</update>

上述代碼中,set標簽用來設置要更新的字段,通過if標簽判斷哪些字段需要更新。where標簽用來拼接SQL語句中的where條件,具體的條件可以根據實際情況進行調整。

6. foreach

foreach 標簽用于處理集合類型的參數,比如 List、Array 等,可以遍歷集合中的元素,將每個元素都轉化為 SQL 語句的一部分,用于生成動態(tài) SQL 語句。下面是一個示例:

<select id="getUserByIdList" resultType="User">
    SELECT * FROM user
    WHERE id IN
    <foreach collection="idList" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

在上述 SQL 語句中,我們通過 foreach 標簽遍歷傳入的參數 idList,將其中的每個元素轉化為一個 id,然后根據這些 id 拼接成一個 IN 子句。

7. bind

bind 標簽用于定義一個變量,該變量可以被后續(xù)的 SQL 片段引用,方便了 SQL 的編寫。下面是一個示例:

<select id="getUserByName" resultType="User">
    <bind name="queryName" value="'%' + name + '%'"/>
    SELECT * FROM user WHERE name like #{queryName}
</select>

在上述 SQL 語句中,我們使用 bind 標簽定義了一個變量 queryName,它的值為 name 模糊查詢的條件。然后使用該變量來拼接 SQL 語句,使得 SQL 語句更加簡潔。

8. 動態(tài)SQL解析原理

MyBatis的動態(tài)SQL是通過OGNL表達式來實現的。OGNL(Object-Graph Navigation Language)是一種基于Java對象圖遍歷的表達式語言,它可以方便地訪問Java對象的屬性和方法。

在MyBatis中,通過OGNL表達式可以動態(tài)地計算條件是否成立,從而確定是否將SQL片段添加到最終的SQL語句中。OGNL表達式通常嵌入在MyBatis中的動態(tài)SQL標簽中,例如if、choose、when、otherwise等。

MyBatis使用了兩個重要的類來實現OGNL表達式的解析和計算:OgnlExpressionEvaluator和OgnlCache。OgnlExpressionEvaluator類負責將MyBatis傳入的參數對象轉換為OGNL表達式需要的上下文對象,然后將OGNL表達式計算結果返回;OgnlCache類負責緩存已經解析好的OGNL表達式,避免重復解析和計算。

具體的解析過程如下:

  • 根據MyBatis的配置將Mapper.xml文件中的SQL語句解析為一個MappedStatement對象,并將其中的OGNL表達式解析成一個一個可執(zhí)行的SQL片段。

  • 對于每一個OGNL表達式,MyBatis使用${}來表示一個簡單的OGNL表達式,使用#{}來表示一個OGNL表達式中包含復雜邏輯的情況。在解析過程中,MyBatis會將OGNL表達式中的參數進行解析和預處理,然后使用OgnlCache類將其緩存起來。

  • 當Mapper接口方法被調用時,MyBatis會將方法中傳入的參數對象轉換為一個BoundSql對象,并將該BoundSql對象與MappedStatement對象一起傳遞給OgnlExpressionEvaluator類。

  • OgnlExpressionEvaluator類中再次解析OGNL表達式,并將BoundSql對象作為上下文傳入OGNL表達式中執(zhí)行。OGNL表達式執(zhí)行的結果將被轉化為String類型,并返回給BoundSql對象。

  • 最后,MyBatis將所有BoundSql對象中的SQL片段拼接成最終的SQL語句并執(zhí)行。

MyBatis的動態(tài)SQL解析原理是將OGNL表達式解析為可執(zhí)行的SQL片段,然后根據條件判斷是否將該SQL片段加入到最終的SQL語句中。MyBatis使用OgnlExpressionEvaluator和OgnlCache類來實現OGNL表達式的解析和計算,從而實現動態(tài)SQL的功能。

在 MyBatis 的源碼中,動態(tài) SQL 還涉及到以下接口和類來實現:

  • SqlNode 接口:表示一個 SQL 節(jié)點,也就是一個 SQL 片段。它包含一個 apply 方法,在執(zhí)行 SQL 語句時會將 SQL 片段應用到相應的位置。

  • MixedSqlNode 類:實現了 SqlNode 接口,可以包含多個子節(jié)點。該類的 apply 方法會依次遍歷所有子節(jié)點,并將每個節(jié)點應用到 SQL 語句中。

  • TextSqlNode 類:表示一個純文本節(jié)點。該類包含一個文本字符串,可以將其直接應用到 SQL 語句中。

  • IfSqlNode 類:表示一個條件節(jié)點??梢愿鶕付ǖ臈l件判斷是否需要應用該節(jié)點內部的 SQL 片段。如果條件成立,則會將 SQL 片段應用到 SQL 語句中。

  • TrimSqlNode 類:表示一個修剪節(jié)點,可以根據配置對 SQL 片段進行修剪操作。常用于處理 UPDATE 和 INSERT 語句中 SET 子句的逗號問題。

  • WhereSqlNode 類:表示一個 WHERE 條件節(jié)點??梢詫?WHERE 子句的參數拼接到 SQL 語句中。

以上是 MyBatis 中實現動態(tài) SQL 的核心接口和類。MyBatis 內部通過組合這些接口和類來構建復雜的 SQL 語句。通過定義這些接口和類,可以讓開發(fā)者更加方便地書寫動態(tài) SQL 語句,并且遵循了設計模式中的單一職責原則。

還有一些Builder 接口及其實現類的作用都是用于構造 SQL 語句。下面簡單介紹一下一些常用的 Builder 類型:

  • BaseBuilder 接口:所有 Builder 的基礎接口,定義了一些共同的方法,例如獲取 Configuration 對象、創(chuàng)建 ParameterMapping 對象等。

  • XMLMapperBuilder 類:從 XML 文件中解析出各種 SQL 節(jié)點,然后通過其他 Builder 對象將其轉換成 SQL 語句。

  • MapperBuilderAssistant 類:輔助 XMLMapperBuilder 類創(chuàng)建各種類型的 SQL 節(jié)點,例如創(chuàng)建 <select><update>、<insert> 等標簽節(jié)點。

  • SqlSourceBuilder 類:根據 XML 中的 SQL 片段創(chuàng)建 SqlSource 對象,SqlSource 對象中包含了解析后的 SQL 語句和參數信息。

  • DynamicSqlSource 類:用于處理動態(tài) SQL,也就是包含各種條件判斷和循環(huán)語句的 SQL 片段。它是 SqlSource 接口的一種實現。

  • StaticSqlSource 類:用于處理靜態(tài) SQL,即不包含任何條件語句和循環(huán)語句的 SQL 片段。它同樣是 SqlSource 接口的一種實現。

  • SqlSessionFactoryBuilder 類:用于創(chuàng)建 SqlSessionFactory 對象,它會將所有的 Builder 對象組合在一起,完成 SQL 語句的解析和構造。

通過上述不同類型的 Builder 對象,我們可以將 XML 中的 SQL 片段轉換成 Java 對象,并且根據各種條件生成相應的 SQL 語句。這個過程中涉及到的類和方法非常多,需要我們深入地了解 MyBatis 的內部實現才能靈活運用。

9. 總結

本文通過介紹MyBatis動態(tài)SQL的基本概念和常用標簽(if、choose、when、otherwise、trim、where、set、foreach),希望讀者能夠更加深入地了解MyBatis的使用和原理。在實際開發(fā)過程中,要根據具體場景和需求選擇合適的動態(tài)SQL標簽,從而實現靈活拼接SQL語句的功能,提高開發(fā)效率。

在 MyBatis 中,動態(tài) SQL 主要包括以下幾種類型:

  • <if> 標簽:表示一個條件語句,可以根據條件判斷是否包含相應的 SQL 片段。
  • <where> 標簽:表示一個 WHERE 條件語句,可以根據配置自動添加 WHERE 關鍵字。
  • <choose> 標簽:表示一個選擇語句,可以根據多個條件選擇符合條件的 SQL 片段。
  • <foreach> 標簽:表示一個循環(huán)語句,在循環(huán)中動態(tài)生成 SQL 語句。
  • <set> 標簽:表示一個 SET 子句,可以根據指定的屬性值動態(tài)生成 SET 語句。

以上標簽都屬于動態(tài) SQL,在解析時需要通過特殊的方式進行處理。下面以 <if> 標簽為例介紹解析原理:

  • XMLScriptBuilder 類會根據標簽類型創(chuàng)建相應的 SQL 節(jié)點,例如 <if> 標簽對應的節(jié)點是 IfSqlNode 對象。
  • XMLScriptBuilder 類會遞歸解析節(jié)點內部的子節(jié)點,并將其組合成一個 SQL 片段。
  • 當解析到 IfSqlNode 節(jié)點時,XMLScriptBuilder 類會獲取標簽中的 test 屬性,并根據該屬性值創(chuàng)建一個 OgnlExpression 對象(OGNL 表達式對象),用于判斷條件是否滿足。
  • 如果條件滿足,則將子節(jié)點生成的 SQL 片段添加到當前 SQL 上下文中;否則忽略該節(jié)點。
  • 最終生成的 SQL 語句就是將所有滿足條件的 SQL 片段組合起來得到的。

以上就是 MyBatis 實現動態(tài) SQL 解析的大體流程。通過 XMLScriptBuilder 類的遞歸解析,可以將各種類型的動態(tài) SQL 節(jié)點轉換成 SqlNode 接口的實現,然后通過 MixedSqlNode 類將它們組合成一個完整的 SQL 片段。

以上就是MyBatis 動態(tài)SQL使用及原理的詳細內容,更多關于MyBatis 動態(tài)SQL使用及原理的資料請關注腳本之家其它相關文章!

相關文章

  • mybatis-plus動態(tài)表名的實現示例

    mybatis-plus動態(tài)表名的實現示例

    這篇文章主要介紹了mybatis-plus動態(tài)表名的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Java編程實現判斷網上鄰居文件是否存在的方法

    Java編程實現判斷網上鄰居文件是否存在的方法

    這篇文章主要介紹了Java編程實現判斷網上鄰居文件是否存在的方法,涉及Java針對路徑轉換及字符串操作的相關技巧,需要的朋友可以參考下
    2015-10-10
  • springMVC不掃描controller中的方法問題

    springMVC不掃描controller中的方法問題

    這篇文章主要介紹了springMVC不掃描controller中的方法問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java Bigdecimal使用原理詳解

    Java Bigdecimal使用原理詳解

    這篇文章主要介紹了Java Bigdecimal使用原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java面向對象之類的繼承介紹

    Java面向對象之類的繼承介紹

    大家好,本篇文章主要講的是Java面向對象之類的繼承介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • java模擬實現斗地主發(fā)牌小程序

    java模擬實現斗地主發(fā)牌小程序

    這篇文章主要為大家詳細介紹了java模擬實現斗地主發(fā)牌小程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Java中的RASP機制實現詳解

    Java中的RASP機制實現詳解

    這篇文章主要介紹了Java中的RASP實現詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • eclipse創(chuàng)建springboot項目的三種方式總結

    eclipse創(chuàng)建springboot項目的三種方式總結

    這篇文章主要介紹了eclipse創(chuàng)建springboot項目的三種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • mybatis 解決從列名到屬性名的自動映射失敗問題

    mybatis 解決從列名到屬性名的自動映射失敗問題

    這篇文章主要介紹了mybatis 解決從列名到屬性名的自動映射失敗問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java高效提取PDF文件指定坐標的文本內容實戰(zhàn)代碼

    Java高效提取PDF文件指定坐標的文本內容實戰(zhàn)代碼

    在日常工作中,有時可能會需要從龐大的PDF文檔中提取其中所包含的文本內容,下面這篇文章主要給大家介紹了關于如何利用Java高效提取PDF文件指定坐標的文本內容,需要的朋友可以參考下
    2024-01-01

最新評論