# Fluent Mybatis中Update語法詳解
## 一、Fluent Mybatis簡介
### 1.1 什么是Fluent Mybatis
Fluent Mybatis是一個基于Mybatis的增強工具,它通過流暢的API設計讓Mybatis的使用更加簡單直觀。相比傳統Mybatis需要編寫XML或注解SQL的方式,Fluent Mybatis提供了Java鏈式調用的語法糖,使得代碼更易讀、更易維護。
### 1.2 核心特性
- **流暢的API**:通過方法鏈實現SQL構建
- **類型安全**:編譯時檢查SQL語法
- **動態SQL**:支持復雜的條件構造
- **代碼生成**:自動生成Entity、Mapper等基礎代碼
- **減少樣板代碼**:簡化CRUD操作
### 1.3 與傳統Mybatis對比
| 特性 | 傳統Mybatis | Fluent Mybatis |
|---------------------|------------------|---------------------|
| SQL編寫方式 | XML/注解 | Java鏈式調用 |
| 可讀性 | 中等 | 高 |
| 類型安全 | 部分支持 | 完全支持 |
| 動態SQL復雜度 | 高 | 低 |
| 學習曲線 | 陡峭 | 平緩 |
## 二、Update語法基礎
### 2.1 基本Update操作
Fluent Mybatis提供了`update()`方法開啟Update操作:
```java
public int updateBasic() {
return new YourMapper()
.update()
.set(YourEntity.Column.name).is("newName")
.set(YourEntity.Column.age).is(25)
.where(YourEntity.Column.id).eq(1L)
.execute();
}
update()
: 開始構建update語句set()
: 設置要更新的字段is()
: 指定字段的新值where()
: 開始構建where條件eq()
: 等于條件execute()
: 執行操作并返回影響行數可以通過連續調用set()
方法更新多個字段:
public int updateMultiFields() {
return new UserMapper()
.update()
.set(User.Column.userName).is("張三")
.set(User.Column.age).is(30)
.set(User.Column.gmtModified).is(new Date())
.where(User.Column.id).eq(1L)
.execute();
}
Fluent Mybatis支持豐富的條件表達式:
.where(User.Column.age).gt(18) // 大于
.where(User.Column.age).ge(18) // 大于等于
.where(User.Column.age).lt(65) // 小于
.where(User.Column.age).le(65) // 小于等于
.where(User.Column.name).like("%張%") // 模糊查詢
.where(User.Column.name).notLike("%李%") // 非模糊匹配
使用and
和or
連接多個條件:
public int updateWithMultiConditions() {
return new UserMapper()
.update()
.set(User.Column.status).is("ACTIVE")
.where(User.Column.age).gt(18)
.and(User.Column.age).lt(65)
.and(User.Column.status).eq("INACTIVE")
.execute();
}
通過apply
方法實現復雜嵌套條件:
public int updateWithNestedConditions() {
return new UserMapper()
.update()
.set(User.Column.remark).is("VIP")
.where(User.Column.vipLevel).gt(3)
.and(
condition -> condition.where(User.Column.regTime).ge(LocalDate.now().minusYears(1))
.or(User.Column.consumption).gt(10000)
)
.execute();
}
使用when
實現條件判斷更新:
public int dynamicUpdate(Long id, String newName, Integer newAge) {
return new UserMapper()
.update()
.set(User.Column.userName).is(newName).when(Objects::nonNull)
.set(User.Column.age).is(newAge).when(newAge != null)
.where(User.Column.id).eq(id)
.execute();
}
通過Lambda實現更靈活的條件:
public int updateWithLambda(User user) {
return new UserMapper()
.update()
.set(User.Column.userName).is(user::getUserName).when(user::getUserName)
.set(User.Column.age).is(user::getAge).when(user::getAge)
.where(User.Column.id).eq(user::getId)
.execute();
}
配置全局空值處理:
@Configuration
public class FluentMybatisConfig {
@Bean
public FluentMybatisConfig config() {
return new FluentMybatisConfig()
.setGlobalUpdateIfNull(false); // 默認不更新null值
}
}
更新滿足條件的所有記錄:
public int batchUpdateByCondition() {
return new UserMapper()
.update()
.set(User.Column.status).is("INACTIVE")
.where(User.Column.lastLoginTime).lt(LocalDateTime.now().minusYears(1))
.execute();
}
使用in
條件批量更新:
public int batchUpdateByIds(List<Long> ids, String newStatus) {
return new UserMapper()
.update()
.set(User.Column.status).is(newStatus)
.where(User.Column.id).in(ids)
.execute();
}
@BatchSize
注解使用數學表達式實現:
public int incrementAge(Long userId) {
return new UserMapper()
.update()
.set(User.Column.age).increase(1) // 年齡+1
.where(User.Column.id).eq(userId)
.execute();
}
更新JSON類型字段:
public int updateJsonField(Long userId, String newExtInfo) {
return new UserMapper()
.update()
.set(User.Column.extInfo).isJson(newExtInfo)
.where(User.Column.id).eq(userId)
.execute();
}
通過版本號實現樂觀鎖:
public int updateWithOptimisticLock(User user) {
return new UserMapper()
.update()
.set(User.Column.userName).is(user.getUserName())
.set(User.Column.version).increase(1) // 版本號+1
.where(User.Column.id).eq(user.getId())
.and(User.Column.version).eq(user.getVersion()) // 原始版本號條件
.execute();
}
使用join
實現聯表更新:
public int updateWithJoin() {
return new UserMapper()
.update()
.set(User.Column.status).is("VIP")
.join(Order.class)
.on(User.Column.id, Order.Column.userId)
.where(Order.Column.amount).gt(10000)
.execute();
}
多表關聯更新:
public int multiTableUpdate() {
return new UserMapper()
.update()
.set(User.Column.level).is("GOLD")
.join(Order.class)
.on(User.Column.id, Order.Column.userId)
.join(Product.class)
.on(Order.Column.productId, Product.Column.id)
.where(Product.Column.category).eq("ELECTRONICS")
.and(Order.Column.createTime).ge(LocalDate.now().minusMonths(3))
.execute();
}
獲取更新后的實體:
public User updateAndReturn(User user) {
return new UserMapper()
.update()
.set(User.Column.userName).is(user.getUserName())
.set(User.Column.age).is(user.getAge())
.where(User.Column.id).eq(user.getId())
.executeAndFetch();
}
@Transactional
public void updateWithTransaction(User user1, User user2) {
userMapper.updateById(user1);
userMapper.updateById(user2);
// 如果發生異常會自動回滾
}
@UpdateTime
自動記錄更新時間explain
分析復雜更新語句配置日志級別:
logging.level.tech.richard.vo.user.mapper=DEBUG
public int batchUpdateUserStatus(List<Long> ids, String newStatus) {
return new UserMapper()
.update()
.set(User.Column.status).is(newStatus)
.set(User.Column.gmtModified).is(new Date())
.where(User.Column.id).in(ids)
.and(User.Column.isDeleted).eq(false)
.execute();
}
public int adjustOrderPrices(String category, BigDecimal ratio) {
return new OrderMapper()
.update()
.set(Order.Column.amount).math("amount * " + ratio)
.join(Product.class)
.on(Order.Column.productId, Product.Column.id)
.where(Product.Column.category).eq(category)
.and(Order.Column.status).eq("UNPD")
.execute();
}
public int updateUserPoints(Long userId, int pointsToAdd) {
return new UserMapper()
.update()
.set(User.Column.points).increase(pointsToAdd)
.set(User.Column.vipLevel).case()
.when(User.Column.points).ge(10000).then(3)
.when(User.Column.points).ge(5000).then(2)
.elseThen(1)
.end()
.where(User.Column.id).eq(userId)
.execute();
}
Fluent Mybatis的Update語法通過流暢的API提供了強大的數據更新能力,從簡單的單字段更新到復雜的聯表更新都能優雅實現。關鍵要點包括:
通過本文的全面介紹,相信您已經能夠熟練運用Fluent Mybatis進行各種更新操作。建議結合官方文檔和實際項目練習來鞏固這些知識。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。