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

MyBatis實現(xiàn)動態(tài)SQL模糊查詢的示例代碼

 更新時間:2026年02月02日 09:06:40   作者:鹿角片ljp  
在數(shù)據(jù)庫查詢中,模糊查詢是最常用的功能之一,今天我們來探討如何通過動態(tài)SQL實現(xiàn)靈活、安全的模糊查詢,文中的示例代碼講解詳細(xì),有需要的小伙伴可以了解下

在數(shù)據(jù)庫查詢中,模糊查詢是最常用的功能之一。然而,當(dāng)查詢條件變得復(fù)雜多變時,靜態(tài)SQL往往顯得力不從心。今天我們來探討如何通過動態(tài)SQL實現(xiàn)靈活、安全的模糊查詢。

一、為什么需要動態(tài)SQL模糊查詢

1.1 傳統(tǒng)模糊查詢的局限性

-- 靜態(tài)SQL示例
SELECT * FROM users WHERE username LIKE '%張%' 
AND email LIKE '%example.com%';

這種寫法的問題在于:

  • 當(dāng)某個條件為空時,查詢會失效
  • 條件組合多變時,需要寫大量重復(fù)代碼
  • 難以應(yīng)對復(fù)雜的業(yè)務(wù)邏輯

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

  • 靈活性:根據(jù)實際參數(shù)動態(tài)生成SQL
  • 可維護(hù)性:代碼更簡潔,易于維護(hù)
  • 性能優(yōu)化:避免不必要的查詢條件

二、MyBatis動態(tài)SQL實現(xiàn)模糊查詢

2.1 基礎(chǔ)示例:單條件模糊查詢

<!-- MyBatis Mapper XML -->
<select id="searchUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="keyword != null and keyword != ''">
            AND (username LIKE CONCAT('%', #{keyword}, '%')
            OR email LIKE CONCAT('%', #{keyword}, '%')
            OR phone LIKE CONCAT('%', #{keyword}, '%'))
        </if>
    </where>
</select>

2.2 多條件組合模糊查詢

<select id="advancedSearch" resultType="User">
    SELECT * FROM users
    <where>
        <!-- 姓名模糊查詢 -->
        <if test="name != null and name != ''">
            AND username LIKE CONCAT('%', #{name}, '%')
        </if>
        
        <!-- 郵箱模糊查詢 -->
        <if test="email != null and email != ''">
            AND email LIKE CONCAT('%', #{email}, '%')
        </if>
        
        <!-- 電話號碼模糊查詢(支持中間四位*號) -->
        <if test="phonePattern != null and phonePattern != ''">
            AND phone LIKE REPLACE(#{phonePattern}, '*', '%')
        </if>
        
        <!-- 地址多字段模糊查詢 -->
        <if test="address != null and address != ''">
            AND (
                province LIKE CONCAT('%', #{address}, '%')
                OR city LIKE CONCAT('%', #{address}, '%')
                OR detail LIKE CONCAT('%', #{address}, '%')
            )
        </if>
    </where>
    ORDER BY create_time DESC
</select>

2.3 使用<choose>實現(xiàn)條件選擇

<select id="smartSearch" resultType="User">
    SELECT * FROM users
    <where>
        <choose>
            <when test="searchType == 'name' and keyword != null">
                AND username LIKE CONCAT('%', #{keyword}, '%')
            </when>
            <when test="searchType == 'email' and keyword != null">
                AND email LIKE CONCAT('%', #{keyword}, '%')
            </when>
            <when test="searchType == 'phone' and keyword != null">
                AND phone LIKE CONCAT('%', #{keyword}, '%')
            </when>
            <otherwise>
                AND status = 'ACTIVE'
            </otherwise>
        </choose>
    </where>
</select>

三、Java代碼中的動態(tài)構(gòu)建

3.1 使用StringBuilder動態(tài)構(gòu)建SQL

// 服務(wù)層代碼示例
public List<User> dynamicSearch(UserSearchCriteria criteria) {
    StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE 1=1");
    List<Object> params = new ArrayList<>();
    
    // 姓名模糊查詢
    if (StringUtils.isNotBlank(criteria.getName())) {
        sql.append(" AND username LIKE ?");
        params.add("%" + criteria.getName() + "%");
    }
    
    // 郵箱模糊查詢
    if (StringUtils.isNotBlank(criteria.getEmail())) {
        sql.append(" AND email LIKE ?");
        params.add("%" + criteria.getEmail() + "%");
    }
    
    // 分頁處理
    if (criteria.getPageSize() > 0) {
        sql.append(" LIMIT ?, ?");
        params.add(criteria.getOffset());
        params.add(criteria.getPageSize());
    }
    
    return jdbcTemplate.query(sql.toString(), params.toArray(), 
        new BeanPropertyRowMapper<>(User.class));
}

3.2 使用JPA Specification實現(xiàn)(Spring Data JPA)

// 使用Specification構(gòu)建動態(tài)查詢
public class UserSpecifications {
    
    public static Specification<User> nameContains(String name) {
        return (root, query, cb) -> 
            StringUtils.isBlank(name) ? 
            cb.conjunction() : 
            cb.like(root.get("username"), "%" + name + "%");
    }
    
    public static Specification<User> emailContains(String email) {
        return (root, query, cb) -> 
            StringUtils.isBlank(email) ? 
            cb.conjunction() : 
            cb.like(root.get("email"), "%" + email + "%");
    }
    
    public static Specification<User> multiFieldSearch(String keyword) {
        return (root, query, cb) -> {
            if (StringUtils.isBlank(keyword)) {
                return cb.conjunction();
            }
            String pattern = "%" + keyword + "%";
            return cb.or(
                cb.like(root.get("username"), pattern),
                cb.like(root.get("email"), pattern),
                cb.like(root.get("phone"), pattern)
            );
        };
    }
}

// 使用示例
public List<User> searchUsers(String name, String email) {
    return userRepository.findAll(
        Specification.where(UserSpecifications.nameContains(name))
            .and(UserSpecifications.emailContains(email))
    );
}

四、高級技巧與優(yōu)化

4.1 防止SQL注入

// 使用預(yù)編譯語句,永遠(yuǎn)不要直接拼接用戶輸入
String safePattern = "%" + escapeSql(keyword) + "%";

// MyBatis自動處理參數(shù),防止SQL注入
<if test="keyword != null">
    AND username LIKE CONCAT('%', #{keyword}, '%')
</if>

4.2 性能優(yōu)化建議

-- 為經(jīng)常查詢的字段創(chuàng)建索引
CREATE INDEX idx_username ON users(username);
CREATE INDEX idx_email ON users(email);

-- 避免前導(dǎo)通配符導(dǎo)致索引失效的情況
-- 不推薦:LIKE '%keyword%' 
-- 推薦:LIKE 'keyword%'(如果業(yè)務(wù)允許)

4.3 使用全文索引提升模糊查詢性能

-- MySQL全文索引示例
ALTER TABLE users ADD FULLTEXT INDEX ft_search (username, email);

-- 使用全文索引進(jìn)行模糊查詢
SELECT * FROM users 
WHERE MATCH(username, email) AGAINST('+張* +example*' IN BOOLEAN MODE);

五、實際應(yīng)用場景

5.1 電商商品搜索

<select id="searchProducts" resultType="Product">
    SELECT * FROM products
    <where>
        <if test="productName != null">
            AND product_name LIKE CONCAT('%', #{productName}, '%')
        </if>
        <if test="categoryId != null">
            AND category_id = #{categoryId}
        </if>
        <if test="minPrice != null">
            AND price >= #{minPrice}
        </if>
        <if test="maxPrice != null">
            AND price <= #{maxPrice}
        </if>
        <!-- 模糊搜索商品描述 -->
        <if test="keyword != null">
            AND (
                product_name LIKE CONCAT('%', #{keyword}, '%')
                OR description LIKE CONCAT('%', #{keyword}, '%')
                OR tags LIKE CONCAT('%', #{keyword}, '%')
            )
        </if>
    </where>
    ORDER BY 
    <choose>
        <when test="sortBy == 'price'">price ${sortOrder}</when>
        <when test="sortBy == 'sales'">sales_count DESC</when>
        <otherwise>create_time DESC</otherwise>
    </choose>
</select>

5.2 日志查詢系統(tǒng)

public List<Log> searchLogs(LogQuery query) {
    StringBuilder sql = new StringBuilder(
        "SELECT * FROM system_logs WHERE 1=1");
    
    // 模糊匹配操作內(nèi)容
    if (StringUtils.isNotBlank(query.getContent())) {
        sql.append(" AND content LIKE ?");
        params.add("%" + query.getContent() + "%");
    }
    
    // 模糊匹配用戶IP
    if (StringUtils.isNotBlank(query.getIp())) {
        sql.append(" AND ip_address LIKE ?");
        params.add(query.getIp() + "%");  // IP前綴匹配
    }
    
    // 時間范圍查詢
    if (query.getStartTime() != null) {
        sql.append(" AND create_time >= ?");
        params.add(query.getStartTime());
    }
    
    return jdbcTemplate.query(sql.toString(), 
        params.toArray(), 
        new BeanPropertyRowMapper<>(Log.class));
}

六、最佳實踐總結(jié)

安全性第一:始終使用參數(shù)化查詢,防止SQL注入

性能優(yōu)化:為頻繁查詢的字段建立索引,考慮使用全文搜索

代碼可讀性:保持SQL語句的清晰和可維護(hù)性

適度使用:避免過度復(fù)雜的動態(tài)SQL,必要時拆分查詢

測試覆蓋:確保各種條件組合都能正確工作

結(jié)語

動態(tài)SQL模糊查詢是現(xiàn)代應(yīng)用開發(fā)中不可或缺的技能。通過合理運(yùn)用MyBatis動態(tài)標(biāo)簽、JPA Specification或自定義SQL構(gòu)建,我們可以在保證安全性的同時,實現(xiàn)靈活高效的查詢功能。記住,好的查詢設(shè)計不僅能讓程序跑得更快,也能讓代碼更易于維護(hù)和擴(kuò)展。

到此這篇關(guān)于MyBatis實現(xiàn)動態(tài)SQL模糊查詢的示例代碼的文章就介紹到這了,更多相關(guān)MyBatis SQL模糊查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 探討:使用httpClient在客戶端與服務(wù)器端傳輸對象參數(shù)的詳解

    探討:使用httpClient在客戶端與服務(wù)器端傳輸對象參數(shù)的詳解

    本篇文章是對使用httpClient在客戶端與服務(wù)器端傳輸對象參數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Java8 Instant 時間戳實例講解

    Java8 Instant 時間戳實例講解

    Instant類是Java8 中補(bǔ)充的一個 時間戳類,nstant 可以使用靜態(tài)方法 now()或者of()方法來創(chuàng)建一個實例對象,本文通過實例代碼講解Java8 Instant 時間戳,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Java實現(xiàn)的最大匹配分詞算法詳解

    Java實現(xiàn)的最大匹配分詞算法詳解

    這篇文章主要介紹了Java實現(xiàn)的最大匹配分詞算法,簡單說明了最大匹配分詞算法的原理并結(jié)合具體實例形式最大匹配分詞算法的實現(xiàn)方法與相關(guān)注意事項,需要的朋友可以參考下
    2017-09-09
  • 一文教會你如何從0到1搭建一個SpringBoot項目

    一文教會你如何從0到1搭建一個SpringBoot項目

    今天剛好學(xué)習(xí)到SpringBoot,就順便記錄一下吧,下面這篇文章主要給大家介紹了關(guān)于如何從0到1搭建一個SpringBoot項目的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 面試JAVA時,問到spring該怎么回答

    面試JAVA時,問到spring該怎么回答

    這篇文章主要介紹了Spring面試資料,學(xué)Java的小伙伴都知道Spring是面試的必問環(huán)節(jié),看完了一天就可掌握數(shù)據(jù)結(jié)構(gòu)和算法的面試題,快來看看吧
    2021-08-08
  • Spring?Boot源碼實現(xiàn)StopWatch優(yōu)雅統(tǒng)計耗時

    Spring?Boot源碼實現(xiàn)StopWatch優(yōu)雅統(tǒng)計耗時

    這篇文章主要為大家介紹了Spring?Boot源碼實現(xiàn)StopWatch優(yōu)雅統(tǒng)計耗時,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • SpringBoot 內(nèi)置 CollectionUtil用法實戰(zhàn)指南

    SpringBoot 內(nèi)置 CollectionUtil用法實戰(zhàn)指南

    文章介紹了SpringBoot中自帶的CollectionUtil類,包括判空、轉(zhuǎn)換、合并、匹配和兜底功能,并通過實戰(zhàn)例子詳細(xì)展示了這些功能的應(yīng)用場景和優(yōu)勢,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • 使用Maven和SpringBoot搭建客戶數(shù)據(jù)清洗項目框架

    使用Maven和SpringBoot搭建客戶數(shù)據(jù)清洗項目框架

    這篇文章主要為大家詳細(xì)介紹了如何使用Maven和SpringBoot搭建客戶數(shù)據(jù)清洗項目框架,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2025-07-07
  • springcloud教程之zuul路由網(wǎng)關(guān)的實現(xiàn)

    springcloud教程之zuul路由網(wǎng)關(guān)的實現(xiàn)

    這篇文章主要介紹了springcloud教程之zuul路由網(wǎng)關(guān)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • java接口返回參數(shù)按照請求參數(shù)進(jìn)行排序方式

    java接口返回參數(shù)按照請求參數(shù)進(jìn)行排序方式

    這篇文章主要介紹了java接口返回參數(shù)按照請求參數(shù)進(jìn)行排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

武鸣县| 鞍山市| 光泽县| 伽师县| 永平县| 阿尔山市| 额济纳旗| 巫溪县| 深泽县| 长岛县| 黔西县| 宕昌县| 都昌县| 湘潭县| 临海市| 宜阳县| 招远市| 通州市| 临夏市| 富顺县| 泾阳县| 水富县| 芮城县| 三都| 张家口市| 夹江县| 永和县| 沭阳县| 彰化县| 特克斯县| 西贡区| 滦平县| 佛学| 资兴市| 丰台区| 易门县| 怀宁县| 华池县| 昌吉市| 蚌埠市| 新田县|