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

MyBatis 動(dòng)態(tài) SQL的使用場(chǎng)景與實(shí)現(xiàn)方法

 更新時(shí)間:2026年05月28日 09:40:23   作者:一條泥憨魚(yú)  
這段文章詳細(xì)介紹了MyBatis動(dòng)態(tài)SQL的使用場(chǎng)景與實(shí)現(xiàn)方法,通過(guò)具體案例深入淺出地地解動(dòng)態(tài)SQL在企業(yè)級(jí)開(kāi)發(fā)中的的廣泛應(yīng)用與重要性,感興趣的朋友跟隨小編一起看看吧

前言:

在學(xué)習(xí) JavaWeb 或企業(yè)級(jí)開(kāi)發(fā)時(shí),很多同學(xué)都會(huì)遇到一個(gè)問(wèn)題:

“查詢(xún)條件不固定,SQL 語(yǔ)句到底該怎么寫(xiě)?”

比如:

  • 用戶(hù)可能輸入用戶(hù)名,也可能不輸入
  • 商品查詢(xún)可能按價(jià)格、分類(lèi)、庫(kù)存組合搜索
  • 更新用戶(hù)信息時(shí),有些字段可能為空

如果全靠字符串拼接 SQL,不但代碼難看,而且容易出錯(cuò)。

于是,MyBatis 提供了一個(gè)非常強(qiáng)大的功能:

動(dòng)態(tài) SQL

它可以讓 SQL “像程序一樣”動(dòng)態(tài)變化。

這篇文章會(huì)帶你從零開(kāi)始,徹底搞懂 MyBatis 動(dòng)態(tài) SQL。

一、什么是動(dòng)態(tài) SQL?

先看一個(gè)普通 SQL:

SELECT * FROM user WHERE username = 'Tom';

但現(xiàn)實(shí)中,用戶(hù)名可能為空。

那么 SQL 就需要?jiǎng)討B(tài)變化:

SELECT * FROM user;

或者:

SELECT * FROM user WHERE username = 'Tom';

這就是:SQL 根據(jù)條件動(dòng)態(tài)變化

MyBatis 提供了很多標(biāo)簽幫助我們實(shí)現(xiàn)這種功能。

最常用的有:

標(biāo)簽作用
<if>條件判斷
<where>自動(dòng)處理 WHERE
<set>自動(dòng)處理 UPDATE
<foreach>循環(huán)遍歷
<choose>類(lèi)似 switch
<trim>自定義拼接規(guī)則

二、為什么需要?jiǎng)討B(tài) SQL?

如果不用動(dòng)態(tài) SQL,代碼會(huì)非常麻煩。

例如:

String sql = "select * from user where 1=1";
if(username != null){
    sql += " and username = #{username}";
}
if(age != null){
    sql += " and age = #{age}";
}

問(wèn)題很多:

  • 可讀性差
  • SQL 拼接容易出錯(cuò)
  • 不方便維護(hù)
  • 容易產(chǎn)生 SQL 注入風(fēng)險(xiǎn)

MyBatis 動(dòng)態(tài) SQL 可以?xún)?yōu)雅解決這些問(wèn)題。

三、準(zhǔn)備工作

假設(shè)有一張用戶(hù)表:

CREATE TABLE user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    age INT,
    gender VARCHAR(10)
);

對(duì)應(yīng)實(shí)體類(lèi):

public class User {
    private Integer id;
    private String username;
    private Integer age;
    private String gender;
    // getter/setter
}

Mapper接口:

public interface UserMapper {
    List<User> select(User user);
}

四、<if>標(biāo)簽

這是最常用的動(dòng)態(tài) SQL 標(biāo)簽。

作用:

條件成立時(shí)才拼接 SQL

1、基本使用

<select id="select" resultType="User">
    SELECT * FROM user
    WHERE 1=1
    <if test="username != null">
        AND username = #{username}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

2、執(zhí)行效果

情況1:

User user = new User();
user.setUsername("Tom");

生成 SQL:

SELECT * FROM user
WHERE 1=1
AND username = 'Tom'

情況2:

User user = new User();
user.setAge(20);

生成 SQL:

SELECT * FROM user
WHERE 1=1
AND age = 20

五、<where>標(biāo)簽

很多初學(xué)者都會(huì)寫(xiě):

WHERE 1=1

雖然能用,但不優(yōu)雅。

MyBatis 提供了:

<where>

它能自動(dòng):

  • 添加 WHERE
  • 去掉多余的 AND

1、改造代碼

<select id="select" resultType="User">
    SELECT * FROM user
    <where>
        <if test="username != null">
            AND username = #{username}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

2、效果

如果沒(méi)有任何條件:

SELECT * FROM user

如果有條件:

SELECT * FROM user
WHERE username = 'Tom'

是不是優(yōu)雅很多?

六、<set>標(biāo)簽

用于動(dòng)態(tài)更新 SQL

1、需求

用戶(hù)修改信息時(shí):

  • 只修改傳入的字段
  • 空字段不更新

2、代碼實(shí)現(xiàn)

<update id="updateUser">
    UPDATE user
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="gender != null">
            gender = #{gender},
        </if>
    </set>
    WHERE id = #{id}
</update>

3、作用

<set> 會(huì)自動(dòng):

  • 添加 SET
  • 去掉最后一個(gè)逗號(hào)

4、生成 SQL

UPDATE user
SET username = 'Tom',
    age = 20
WHERE id = 1

七、<foreach>標(biāo)簽

這是開(kāi)發(fā)中非常重要的標(biāo)簽。

作用:循環(huán)遍歷集合

最經(jīng)典的場(chǎng)景:批量查詢(xún)

1、需求

查詢(xún)多個(gè) ID:

SELECT * FROM user WHERE id IN (1,2,3)

2、Mapper接口

List<User> selectByIds(List<Integer> ids);

3、XML寫(xiě)法

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

4、參數(shù)解釋

屬性作用
collection集合名稱(chēng)
item每次遍歷元素
open開(kāi)始字符串
separator分隔符
close結(jié)束字符串

5、生成 SQL

SELECT * FROM user
WHERE id IN (1,2,3)

八、<choose>標(biāo)簽

類(lèi)似 Java 中的:

switch-case

作用:多選一

示例

<select id="select" resultType="User">
    SELECT * FROM user
    <where>
        <choose>
            <when test="username != null">
                username = #{username}
            </when>
            <when test="age != null">
                age = #{age}
            </when>
            <otherwise>
                gender = '男'
            </otherwise>
        </choose>
    </where>
</select>

邏輯

  • username 有值 → 按 username 查詢(xún)
  • 否則 age 有值 → 按 age 查詢(xún)
  • 都沒(méi)有 → 默認(rèn)查詢(xún) gender='男'

九、<trim>標(biāo)簽

這是一個(gè)高級(jí)標(biāo)簽。

作用:自定義字符串拼接規(guī)則

示例

<trim prefix="WHERE" prefixOverrides="AND |OR ">
    <if test="username != null">
        AND username = #{username}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</trim>

含義

屬性作用
prefix添加前綴
prefixOverrides刪除前綴
suffix添加后綴
suffixOverrides刪除后綴

實(shí)際上:

<where>

底層本質(zhì)上就是:

<trim>

的封裝。

十、動(dòng)態(tài) SQL 執(zhí)行流程

很多同學(xué)會(huì)問(wèn):

MyBatis 是怎么讓 SQL 動(dòng)態(tài)變化的?

流程如下:

XML動(dòng)態(tài)SQL
    ↓
MyBatis解析標(biāo)簽
    ↓
拼接最終SQL
    ↓
預(yù)編譯SQL
    ↓
執(zhí)行數(shù)據(jù)庫(kù)操作

所以:

動(dòng)態(tài) SQL 本質(zhì)上是 SQL 的動(dòng)態(tài)拼接

但它比手寫(xiě)字符串安全得多。

十一、動(dòng)態(tài) SQL 的開(kāi)發(fā)技巧

1、優(yōu)先使用<where>

不要再:

WHERE 1=1

了。

2、更新操作使用<set>

避免:

age = 20,

最后多逗號(hào)報(bào)錯(cuò)。

3、批量操作一定學(xué)會(huì)<foreach>

企業(yè)開(kāi)發(fā)中極其常見(jiàn)。

例如:

  • 批量刪除
  • 批量查詢(xún)
  • 批量插入

4、避免 SQL 過(guò)于復(fù)雜

動(dòng)態(tài) SQL 很強(qiáng)大,但不要把所有業(yè)務(wù)邏輯都寫(xiě)進(jìn) SQL

否則后期維護(hù)會(huì)非常痛苦。

十二、完整案例:多條件查詢(xún)

Mapper接口

List<User> selectCondition(User user);

XML

<select id="selectCondition" resultType="User">
    SELECT * FROM user
    <where>
        <if test="username != null and username != ''">
            AND username LIKE CONCAT('%',#{username},'%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
        <if test="gender != null">
            AND gender = #{gender}
        </if>
    </where>
</select>

測(cè)試代碼

User user = new User();
user.setUsername("o");
user.setGender("男");
List<User> users = mapper.selectCondition(user);
users.forEach(System.out::println);

生成 SQL

SELECT * FROM user
WHERE username LIKE '%o%'
AND gender = '男'

十三、動(dòng)態(tài) SQL 常見(jiàn)面試題

1、動(dòng)態(tài) SQL 有哪些標(biāo)簽?

常見(jiàn):

  • <if>
  • <where>
  • <set>
  • <foreach>
  • <choose>
  • <trim>

2、<where>有什么作用?

自動(dòng):

  • 添加 WHERE
  • 刪除多余 AND/OR

3、<set>有什么作用?

自動(dòng):

  • 添加 SET
  • 刪除最后逗號(hào)

4、#{}和${}區(qū)別?

#{}

預(yù)編譯:

WHERE id = ?

安全,推薦使用。

${}

字符串拼接:

ORDER BY age

存在 SQL 注入風(fēng)險(xiǎn)。

十四、總結(jié)

動(dòng)態(tài) SQL 是 MyBatis 中最核心的能力之一。

掌握后你就能真正寫(xiě)出:

  • 靈活的查詢(xún)
  • 動(dòng)態(tài)更新
  • 批量操作
  • 企業(yè)級(jí) SQL

重點(diǎn)回顧

標(biāo)簽核心作用
<if>條件判斷
<where>自動(dòng)處理 WHERE
<set>動(dòng)態(tài)更新
<foreach>循環(huán)集合
<choose>多選一
<trim>自定義拼接

很多初學(xué)者覺(jué)得:

“動(dòng)態(tài) SQL 好復(fù)雜。”

“根據(jù)條件,動(dòng)態(tài)拼接 SQL。”

只要理解這一點(diǎn),你就已經(jīng)入門(mén)了。

到此這篇關(guān)于MyBatis 動(dòng)態(tài) SQL的使用場(chǎng)景與實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)MyBatis 動(dòng)態(tài) SQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Security 登錄認(rèn)證流程詳細(xì)分析詳解

    Security 登錄認(rèn)證流程詳細(xì)分析詳解

    本文Security登錄認(rèn)證流程詳細(xì)分析詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    本文介紹了Spring Boot中 @KafkaListener 注解的介紹、原理和使用方法,通過(guò)本文的介紹,我們希望讀者能夠更好地理解Spring Boot中 @KafkaListener 注解的使用方法,并在項(xiàng)目中更加靈活地應(yīng)用
    2023-09-09
  • Java?9中的"菱形"語(yǔ)法詳解

    Java?9中的"菱形"語(yǔ)法詳解

    Java?9?再次增強(qiáng)了“菱形”語(yǔ)法,它甚至允許在創(chuàng)建匿名內(nèi)部類(lèi)時(shí)使用菱形語(yǔ)法,Java?可根據(jù)上下文來(lái)推斷匿名內(nèi)部類(lèi)中泛型的類(lèi)型,下面程序示范了在匿名內(nèi)部類(lèi)中使用菱形語(yǔ)法,感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • Java關(guān)鍵字synchronized基本使用詳解

    Java關(guān)鍵字synchronized基本使用詳解

    這篇文章主要給大家介紹了關(guān)于Java關(guān)鍵字synchronized基本使用的相關(guān)資料,synchronized可以用來(lái)同步靜態(tài)和非靜態(tài)方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • SpringBoot+Vue項(xiàng)目打包部署完整步驟教程

    SpringBoot+Vue項(xiàng)目打包部署完整步驟教程

    這篇文章主要介紹了SpringBoot+Vue項(xiàng)目打包部署的相關(guān)資料,包括Vue項(xiàng)目的打包設(shè)置、SpringBoot的配置修改、跨域問(wèn)題處理、使用Nginx配置反向代理以及最終的項(xiàng)目啟動(dòng),教程假定開(kāi)發(fā)者已具備完整的前后端分離項(xiàng)目和配置好環(huán)境的服務(wù)器,需要的朋友可以參考下
    2024-10-10
  • Spring中的注解@Autowired實(shí)現(xiàn)過(guò)程全解(@Autowired 背后的故事)

    Spring中的注解@Autowired實(shí)現(xiàn)過(guò)程全解(@Autowired 背后的故事)

    這篇文章主要介紹了Spring中的注解@Autowired實(shí)現(xiàn)過(guò)程全解,給大家聊聊@Autowired 背后的故事及實(shí)現(xiàn)原理,需要的朋友可以參考下
    2021-07-07
  • java組裝樹(shù)形結(jié)構(gòu)List問(wèn)題

    java組裝樹(shù)形結(jié)構(gòu)List問(wèn)題

    這篇文章主要介紹了java組裝樹(shù)形結(jié)構(gòu)List問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java異常(Exception)處理以及常見(jiàn)異常總結(jié)

    Java異常(Exception)處理以及常見(jiàn)異常總結(jié)

    在《Java編程思想》中這樣定義異常,阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問(wèn)題,雖然java中有異常處理機(jī)制,但是要明確一點(diǎn),決不應(yīng)該用"正常"的態(tài)度來(lái)看待異常,這篇文章主要給大家介紹了關(guān)于Java異常(Exception)處理以及常見(jiàn)異常的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 詳解如何自定義parallelStream線程池

    詳解如何自定義parallelStream線程池

    這篇文章主要為大家介紹了如何自定義parallelStream的線程池實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Mybatis-plus依賴(lài)及配置文件方式

    Mybatis-plus依賴(lài)及配置文件方式

    這篇文章主要介紹了Mybatis-plus依賴(lài)及配置文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

伊川县| 广西| 焉耆| 香河县| 修文县| 榆中县| 天柱县| 连山| 米泉市| 台中县| 建德市| 安阳市| 寿光市| 浮山县| 武强县| 中江县| 涟水县| 云梦县| 安远县| 卫辉市| 洛南县| 于都县| 延庆县| 惠水县| 连云港市| 林甸县| 洪江市| 墨玉县| 柳州市| 怀宁县| 和顺县| 红原县| 霍城县| 吕梁市| 浑源县| 南郑县| 天水市| 沅陵县| 浏阳市| 马关县| 剑河县|