MyBatis-Plus 中 的動態(tài)SQL 片段(sqlSegment)詳解
以下是針對 MyBatis-Plus 中 通用 SQL 片段(sqlSegment) 的清晰詳解,結合核心功能與實用場景,逐步說明其用法:
一、什么是sqlSegment?
在 MyBatis-Plus 中,sqlSegment 通常指 動態(tài)生成的 SQL 代碼塊,例如由條件構造器(Wrapper)自動生成的 WHERE 條件、ORDER BY 排序等。開發(fā)者可通過特定語法(如 ${ew.customSqlSegment}或者${ew.sqlSegment})將這些片段插入到自定義 SQL 中,實現(xiàn)靈活組合。
二、核心使用方式
1.條件構造器(Wrapper)動態(tài)生成 SQL 片段
通過 QueryWrapper 或 LambdaQueryWrapper 構建條件,自動生成 WHERE 后的條件語句。
// 創(chuàng)建 Wrapper
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", 1)
.like("username", "Tom")
.orderByDesc("create_time");
// 執(zhí)行查詢(自動拼接條件到 SQL)
List<User> users = userMapper.selectList(wrapper);生成 SQL:
SELECT * FROM user WHERE status = 1 AND username LIKE '%Tom%' ORDER BY create_time DESC
2.在 XML 中引用 Wrapper 的 SQL 片段
使用 ${ew.customSqlSegment} 占位符,將 Wrapper 中的條件插入到自定義 SQL。
<!-- XML 映射文件 -->
<select id="selectByWrapper" resultType="User">
SELECT * FROM user
WHERE age > 18
${ew.customSqlSegment} <!-- 插入 Wrapper 的條件 -->
</select>Java 調用:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ne("email", null); // 添加條件:email IS NOT NULL
List<User> users = userMapper.selectByWrapper(wrapper);生成 SQL:
SELECT * FROM user WHERE age > 18 AND email IS NOT NULL <!-- 來自 Wrapper -->
三、關鍵語法解析
1.${ew.customSqlSegment}的作用
ew是 MyBatis-Plus 的固定參數(shù)名,代表Wrapper對象。customSqlSegment是Wrapper中生成的 SQL 片段(如WHERE條件、ORDER BY)。- 注意:必須確保
Wrapper對象作為參數(shù)傳遞到 XML 中(通常參數(shù)名為ew)。
2.Lambda 表達式避免硬編碼字段名
使用 LambdaQueryWrapper 提升代碼安全性和可讀性:
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(User::getStatus, 1) // 方法引用代替字符串
.ge(User::getAge, 18)
.orderByAsc(User::getCreateTime);3.${ew.customSqlSegment} 與 ${ew.sqlSegment} 的區(qū)別對比
1.${ew.customSqlSegment}:動態(tài)拼接完整 WHERE 條件:常用于無需手動編寫 WHERE 的自定義 SQL 中
2.${ew.sqlSegment}:僅注入條件表達式:需手動拼接 WHERE,適用于需要精確控制 SQL 結構的場景
// Mapper 接口
@Select("SELECT * FROM user ${ew.customSqlSegment}")
List<User> selectPageCustom(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
@Select("SELECT * FROM user WHERE ${ew.sqlSegment}")
List<User> selectPageWhere(@Param(Constants.WRAPPER) Wrapper<User> wrapper); 四、實際應用場景
場景 1:動態(tài)條件查詢
根據(jù)用戶輸入動態(tài)拼接查詢條件,無需手動編寫 if 判斷。
public List<User> searchUsers(String name, Integer minAge) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(name), User::getUsername, name)
.ge(minAge != null, User::getAge, minAge);
return userMapper.selectList(wrapper);
}like和ge方法中的第一個參數(shù)為條件布爾值,自動決定是否拼接該條件。
場景 2:復用公共 SQL 片段
在 XML 中定義公共片段,結合 Wrapper 實現(xiàn)復用。
<!-- 定義公共的 WHERE 條件 -->
<sql id="activeUser">
is_deleted = 0 AND status = 'ACTIVE'
</sql>
<!-- 在查詢中復用 -->
<select id="selectActiveUsers" resultType="User">
SELECT * FROM user
WHERE <include refid="activeUser"/>
${ew.customSqlSegment} <!-- 追加其他動態(tài)條件 -->
</select>Java 調用:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("username", "Admin");
List<User> users = userMapper.selectActiveUsers(wrapper);生成 SQL:
SELECT * FROM user WHERE is_deleted = 0 AND status = 'ACTIVE' <!-- 公共片段 --> AND username LIKE '%Admin%' <!-- 動態(tài)條件 -->
場景 3:邏輯刪除自動過濾
配置 MyBatis-Plus 全局邏輯刪除,自動在所有查詢中注入 WHERE is_deleted=0。
# application.yml
mybatis-plus:
global-config:
db-config:
logic-delete-field: isDeleted # 實體類字段名
logic-delete-value: 1 # 刪除后的值
logic-not-delete-value: 0 # 未刪除的值- 無需手動編寫條件,刪除操作自動變?yōu)?
UPDATE語句,查詢自動過濾已刪除數(shù)據(jù)。
五、最佳實踐與避坑指南
1.優(yōu)先使用 LambdaQueryWrapper
- 優(yōu)勢:避免字段名硬編碼,編譯時檢查,重構友好。
- 示例:
lambdaWrapper.eq(User::getStatus, 1) // 正確性由編譯器保證
2.謹慎使用${}防止 SQL 注入
- 安全寫法:
WHERE username = #{param} <!-- 使用 #{} 預編譯 --> - 風險寫法:
ORDER BY ${orderBy} <!-- 直接拼接字符串,需手動過濾參數(shù) -->
3.復雜 SQL 結合 XML 片段
對于多表 JOIN 或復雜統(tǒng)計,仍可在 XML 中編寫完整 SQL,利用 <include> 復用片段。
<select id="selectUserWithRole" resultType="map">
SELECT u.*, r.role_name
FROM user u
LEFT JOIN role r ON u.role_id = r.id
${ew.customSqlSegment}
</select>六、總結
- 核心機制:通過
Wrapper生成動態(tài) SQL 片段,結合${ew.customSqlSegment}嵌入自定義 SQL。 - 適用場景:動態(tài)條件查詢、邏輯刪除、多租戶隔離、公共代碼復用。
- 優(yōu)勢:減少重復代碼、提升可維護性、保持 SQL 靈活性。
通過合理利用 MyBatis-Plus 的 SQL 片段功能,可顯著簡化開發(fā)流程,尤其適合快速迭代的中大型項目。
到此這篇關于MyBatis-Plus 中 的動態(tài)SQL 片段(sqlSegment)講解的文章就介紹到這了,更多相關MyBatis-Plus動態(tài)SQL內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring boot+beetl+i18n國際化處理的方法
這篇文章主要介紹了Spring boot+beetl+i18n國際化處理的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-04-04
解決idea中svn提交時performing vcs refresh時間很長的問題
這篇文章主要介紹了解決idea中svn提交時performing vcs refresh時間很長的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Windows系統(tǒng)下Java連接SQL Server的方法簡介
這篇文章主要介紹了Windows系統(tǒng)下Java連接SQL Server的方法,分別是JDBC和JTDS的相關使用,需要的朋友可以參考下2015-09-09
springboot模塊里面調用另外一個模塊的方法實現(xiàn)
在Spring-Boot項目開發(fā)中,存在著本模塊的代碼需要訪問外面模塊接口,本文就來介紹一下springboot模塊里面調用另外一個模塊的方法實現(xiàn),感興趣的可以了解一下2023-11-11

