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

MyBatis 動態(tài) SQL 優(yōu)化之標簽的實戰(zhàn)與技巧(常見用法)

 更新時間:2025年04月02日 16:56:07   作者:權(quán)^  
本文通過詳細的示例和實際應(yīng)用場景,介紹了如何有效利用這些標簽來優(yōu)化 MyBatis 配置,提升開發(fā)效率,確保 SQL 的高效執(zhí)行和安全性,感興趣的朋友跟隨小編一起看看吧

動態(tài)SQL詳解

動態(tài)SQL是一種在運行時生成和執(zhí)行SQL語句的技術(shù),廣泛應(yīng)用于處理復(fù)雜查詢條件和動態(tài)數(shù)據(jù)需求。以下是動態(tài)SQL的核心概念、常見用法及注意事項。

一、動態(tài)SQL的核心概念

1.1 什么是動態(tài)SQL?

動態(tài)SQL是一種靈活的SQL編寫方式,允許開發(fā)者在程序運行時根據(jù)條件生成SQL語句,而不是在編譯時固化。動態(tài) SQL 是Mybatis的強大特性之一,能夠完成不同條件下不同的 SQL拼接。

1.2 動態(tài)SQL的優(yōu)點

  • 靈活性:根據(jù)不同條件生成不同的SQL語句。
  • 復(fù)用性:減少重復(fù)代碼,提高代碼維護性。
  • 性能:在某些場景下可以優(yōu)化查詢性能。

1.3 動態(tài)SQL的常見用途

  • 處理多條件查詢。
  • 動態(tài)指定表名、字段或排序方式。
  • 處理批量操作。

二、動態(tài)SQL的常見用法(XML方式)

數(shù)據(jù)庫數(shù)據(jù)信息

2.1 < if > 標簽

主要用于在動態(tài)SQL中根據(jù)條件判斷是否執(zhí)行某個SQL片段。它可以根據(jù)傳入的參數(shù)或條件動態(tài)地添加或移除SQL語句的一部分,從而實現(xiàn)靈活的查詢需求。

UserInfoMapperXML.java 接口代碼

 Integer insertUserBySQL(UserInfo userInfo);

UserInfoMapper.xml 文件

    <insert id="insertUserBySQL">
        insert into user_info (
        username,
        password,
        age,
        <if test="gender!=null">
            gender,
        </if>
        phone)
        values(
        #{username},
        #{password},
        #{age},
        <if test="gender!=null">
            #{gender},
        </if>
        #{phone})
    </insert>

測試類沒有插入gender的情況

    @Test
    void insertUserBySQL() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("qq");
        userInfo.setPassword("qq");
        userInfo.setAge(46);
        userInfo.setPhone("465131");
        userInfoMapperXML.insertUserBySQL(userInfo);
    }

運行結(jié)果:

可以看到把gender這個字段使用if標簽之后,這個字段就被移除了。

2.2< trim>標簽

trim標簽在動態(tài)SQL中起到格式化SQL語句的作用,允許開發(fā)者在生成SQL時自動處理空格、換行符以及前綴后綴的添加。通過合理使用trim標簽,可以簡化動態(tài)SQL的開發(fā),提高代碼的可讀性和維護性,同時確保生成的SQL語句高效且正確。

prefix:表示整個語句塊,以prefix的值作為前綴
suffix:表示整個語句塊,以suffix的值作為后綴
prefixOverrides:表示整個語句塊要去除掉的前綴
suffixOverrides:表示整個語句塊要去除掉的后綴

為了更好的了解trim標簽的作用,先來個錯誤的示范。

XML.java 文件

Integer insertUserBySQL1(UserInfo userInfo);

.xml文件

    <insert id="insertUserBySQL1">
        insert into user_info
        <trim prefix="(" suffix=")" >
    <if test="username!=null">
        username,
    </if>
            <if test="password!=null">
                password,
            </if>
            <if test="age!=null">
                age,
            </if>
            <if test="gender!=null">
                gender,
            </if>
            <if test="phone!=null">
                phone
            </if>
        </trim>
        values
        <trim suffix="(" prefix=")" >
            <if test="username!=null">
                #{username},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="age!=null">
                #{age},
            </if>
            <if test="gender!=null">
                #{gender},
            </if>
            <if test="phone">
                #{phone}
            </if>
        </trim>
    </insert>

測試類

 @Test
    void insertUserBySQL1() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("zhangs");
        userInfo.setPassword("123461");
        userInfo.setPhone("7489");
        userInfoMapperXML.insertUserBySQL1(userInfo);

運行結(jié)果:

修改 .xml文件,通過trim標簽給SQL語句添加或者去除前后綴。

再進行測試;

可以看到成功了。

2.3 <where>標簽

標簽用于在動態(tài)SQL中自動處理WHERE子句的生成,簡化多條件查詢的開發(fā)。它能自動處理邏輯連接詞(如AND、OR)以及去除多余的關(guān)鍵字,使得代碼更加簡潔和高效。

XML.java文件代碼:

List<UserInfo> selectByWhere();

.xml文件代碼

  <select id="selectByWhere" resultType="com.sliqvers.model.UserInfo">
            select * from user_info
        <where>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=null">
                or password=#{password}
            </if>
        <if test="age!=null">
            and age=#{age}
        </if>
            <if test="phone!=null">
             or   phone=#{phone}
            </if>
        </where>
    </select>

測試類

  @Test
    void selectByWhere() {
        userInfoMapperXML.selectByWhere().stream().forEach(x-> System.out.println(x));
    }

觀察數(shù)據(jù)庫,這幾個都有值,所以運行結(jié)果是全部

生成的SQL:
當(dāng)username和phonel都有值:
SELECT * FROM user_info WHERE username = ? AND phone =?;
當(dāng)只有username有值:
SELECT * FROM user_info WHERE username =?;
當(dāng)兩者都為null:
SELECT * FROM user_info;

2.4<set>標簽

標簽在UPDATE語句中起到動態(tài)設(shè)置字段值的作用,自動處理SET關(guān)鍵字和逗號,避免空更新。通過合理使用<set>標簽,可以簡化代碼,提高SQL執(zhí)行效率,確保系統(tǒng)的安全性和穩(wěn)定性。

XML.java文件

 Integer upadteUserSql(UserInfo userInfo);

.xml文件

    <update id="upadteUserSql">
        update user_info
        <set>
            <if test="password!=null">
                password = #{password} ,
            </if>
            <if test="username!=null">
                username = #{username},
            </if>
        </set>
        where id=#{id}
    </update>

測試類:

    @Test
    void upadteUserSql() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("Sliqvers");
        userInfo.setPassword("111111");
        userInfo.setId(1);
        userInfoMapperXML.upadteUserSql(userInfo);
    }

運行結(jié)果:

生成的SQL:
當(dāng)username和password都有值:
UPDATE user_info SET username = ?, email = ? WHERE id = ?
當(dāng)只有username有值:
UPDATE user_info SET username = ? WHERE id = ?
當(dāng)只有password有值:
UPDATE users_info SET password = ? WHERE id = ?
當(dāng)兩者都為null:
UPDATE user_info WHERE id = ?

2.5 <foreach> 標簽

<foreach>標簽在動態(tài)SQL中起到遍歷集合或數(shù)組的作用,生成IN子句、批量INSERT或UPDATE等操作。通過合理使用標簽,可以簡化批量操作的SQL拼接,提高開發(fā)效率和系統(tǒng)性能。同時,注意避免SQL注入和空集合處理等問題,可確保動態(tài)SQL的安全性和可靠性。

<foreach> 標簽的屬性

collection:必填,指定要遍歷的集合名。
item:必填,指定遍歷時的變量名。
open:可選,遍歷開始時添加的字符串。
close:可選,遍歷結(jié)束時添加的字符串。
separator:可選,遍歷時的分隔符(默認",")。
index:可選,遍歷時的索引變量。
select:可選,用于嵌套查詢。

XML.java接口

  List<UserInfo> selectBySql(List<Integer> ids);

.xml文件

    <select id="selectBySql" resultType="com.sliqvers.model.UserInfo">
        select * from user_info where id in
        <foreach collection="ids" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
    </select>

測試類

    @Test
    void selectBySql() {
        List<Integer> ids=new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        userInfoMapperXML.selectBySql(ids).stream().forEach(x-> System.out.println(x));
    }

運行結(jié)果:

生成的SQL:
ids = [1, 2, 3] 時:
SELECT * FROM user_info WHERE id IN (1, 2, 3)

2.6 <include>標簽

在xml映射?件中配置的SQL,有時可能會存在很多重復(fù)的片段,此時就會存在很多冗余的代碼,我們可以對重復(fù)的代碼片段進行抽取,將其通過 <sql> 標簽封裝到?個SQL片段,然后再通過<include> 標簽進行引用。

定義一個常用的WHERE條件

<sql id="allColumn">
 id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

通過 <include> 標簽在原來抽取的地方進行引用。操作如下:

<select id="queryAllUser" resultMap="BaseMap">
 select
 <include refid="allColumn"></include>
 from user_info
</select>

三、動態(tài)SQL的注意事項

3.1 SQL注入問題(搞破壞)

  • 風(fēng)險:直接拼接用戶輸入可能導(dǎo)致SQL注入。
  • 解決方案:使用參數(shù)化查詢或ORM框架(如MyBatis)提供的安全功能。

3.2 performance

  • 執(zhí)行計劃緩存:動態(tài)SQL可能導(dǎo)致數(shù)據(jù)庫無法有效利用執(zhí)行計劃緩存。
  • 優(yōu)化建議:盡量減少動態(tài)SQL的使用場景,或者使用有限的條件組合。

3.3 動態(tài)SQL的可讀性和維護性

  • 復(fù)雜性:動態(tài)SQL可能使代碼更難閱讀和維護。
  • 建議:合理分層代碼,遵循編碼規(guī)范。

四、總結(jié)

本文通過詳細的示例和實際應(yīng)用場景,介紹了如何有效利用這些標簽來優(yōu)化 MyBatis 配置,提升開發(fā)效率,確保 SQL 的高效執(zhí)行和安全性。學(xué)習(xí)這些技巧,幫助開發(fā)者更高效地構(gòu)建和維護數(shù)據(jù)庫交互層。

到此這篇關(guān)于MyBatis 動態(tài) SQL 優(yōu)化:標簽的實戰(zhàn)與技巧的文章就介紹到這了,更多相關(guān)MyBatis 動態(tài) SQL 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IntelliJ IDEA(2017)安裝和破解的方法

    IntelliJ IDEA(2017)安裝和破解的方法

    這篇文章主要介紹了IntelliJ IDEA(2017)安裝和破解的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 淺談SpringBoot 中關(guān)于自定義異常處理的套路

    淺談SpringBoot 中關(guān)于自定義異常處理的套路

    這篇文章主要介紹了淺談SpringBoot 中關(guān)于自定義異常處理的套路,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Kotlin中l(wèi)et、run、with、apply及also的用法和差別

    Kotlin中l(wèi)et、run、with、apply及also的用法和差別

    作用域函數(shù)是Kotlin比較重要的一個特性,分為5種let、run、with、apply及also,這五個函數(shù)的工作方式非常相似,但是我們需要了解這5種函數(shù)的差異,以便在不同的場景更好的利用它,這篇文章主要介紹了Kotlin中l(wèi)et、run、with、apply及also的差別,需要的朋友可以參考下
    2023-11-11
  • SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn)

    SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn)

    Spring Security中實現(xiàn)基于JWT的無狀態(tài)認證是一種常見的做法,本文就來介紹一下SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn),感興趣的可以了解一下
    2025-04-04
  • java.lang.FileNotFoundException 異常的正確解決方法(親測有效)

    java.lang.FileNotFoundException 異常的正確解決方法(親測有效)

    java.io.FileNotFoundException是一個在文件操作過程中常見的異常,它屬于IOException的一個子類,這篇文章主要介紹了java.lang.FileNotFoundException 異常的正確解決方法(親測有效),需要的朋友可以參考下
    2024-01-01
  • 解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system的異常問題

    解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system

    今天小編就為大家分享一篇關(guān)于解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system的異常問題,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 解決mybatis映射結(jié)果集失效的問題

    解決mybatis映射結(jié)果集失效的問題

    這篇文章主要介紹了解決mybatis映射結(jié)果集失效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 深入了解JAVA 軟引用

    深入了解JAVA 軟引用

    這篇文章主要介紹了JAVA 軟引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • JavaScript實現(xiàn)鼠標移動粒子跟隨效果

    JavaScript實現(xiàn)鼠標移動粒子跟隨效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)鼠標移動粒子跟隨效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Springboot項目因為kackson版本問題啟動報錯解決方案

    Springboot項目因為kackson版本問題啟動報錯解決方案

    這篇文章主要介紹了Springboot項目因為kackson版本問題啟動報錯解決方案,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論