引言
MyBatis-Plus 是 MyBatis 的增強工具包,提供了許多方便快捷的功能來簡化開發,提高效率。除了基本的 CRUD 操作外,MyBatis-Plus 還提供了一些高級功能,本文將探討 MyBatis-Plus 的高階用法,幫助開發者更好地利用該工具包。
1. 動態表名和字段
MyBatis-Plus 支持動態表名和字段,這在一些特殊場景下非常有用,比如多租戶系統或者動態數據源切換。通過注解 @TableName
和 @TableField
可以動態指定表名和字段名。
@TableName("user_${dynamicValue}")
public class User {@TableField(value = "name_${dynamicValue}")private String name;
}
2. 自定義全局操作
MyBatis-Plus 允許自定義全局操作,比如自定義全局的查詢條件、插入前操作、更新前操作等。通過實現 com.baomidou.mybatisplus.core.injector.ISqlInjector
接口可以實現自定義 SQL 注入器,通過實現 com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
接口可以實現字段自動填充等。
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);}@Overridepublic void updateFill(MetaObject metaObject) {this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);}
}
3. 自動分頁
MyBatis-Plus 提供了自動分頁的功能,可以自動根據查詢條件進行分頁,無需手動編寫分頁 SQL。只需在查詢條件中添加分頁參數即可。
Page<User> page = new Page<>(1, 10);
userMapper.selectPage(page, null);
4. 邏輯刪除
MyBatis-Plus 支持邏輯刪除,通過注解 @TableLogic
可以指定邏輯刪除字段,并在查詢時自動過濾掉已被邏輯刪除的記錄。
@Configuration
@MapperScan("com.example.mapper")
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new LogicSqlInjector());interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}@Beanpublic ISqlInjector sqlInjector() {return new LogicSqlInjector();}
}
@TableLogic
@TableField(value = "is_deleted")
private Integer deleted;
// 執行邏輯刪除
userMapper.deleteById(userId);// 查詢用戶列表,自動過濾已被邏輯刪除的記錄
List<User> userList = userMapper.selectList(null);
5. 實現多租戶系統
在多租戶系統中,不同的租戶需要訪問不同的數據,但數據結構相同。通過動態表名可以很方便地實現多租戶數據的隔離存儲。
@TableName("user_${tenantId}")
public class User {@TableField(value = "name")private String name;
}
根據不同的租戶(tenantId
),用戶數據將存儲在不同的表中,實現了多租戶數據的隔離存儲。?
?
6. 動態數據源切換
在一些特殊的場景中,需要根據不同的條件切換數據源。通過動態表名和字段可以很方便地實現動態數據源切換。
@TableName("user_${dataSource}")
public class User {@TableField(value = "name_${dynamicValue}")private String name;
}
7. 數據權限控制
在一些需要進行數據權限控制的系統中,不同的用戶可能只能訪問部分數據。通過動態表名和字段可以很方便地實現數據權限控制。
@TableName("user_${roleId}")
public class User {@TableField(value = "name_${dynamicValue}")private String name;
}
根據不同的用戶角色(roleId
),用戶數據將存儲在不同的表中,并且字段名也會動態變化,實現數據權限控制的需求。?
?
8. 分表分庫
在數據量較大的系統中,為了提高性能和擴展性,可能會采用分表分庫的方式來存儲數據。通過動態表名和字段可以很方便地實現分表分庫。
@TableName("user_${shardingValue}")
public class User {@TableId(type = IdType.AUTO)private Long id;private String username;private Integer age;// 其他字段...
}
?分庫分表策略配置
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 配置分頁插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 配置分片插件interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor());return interceptor;}@Beanpublic DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {return new DynamicTableNameInnerInterceptor();}
}
分庫分表策略實現?
public class DynamicTableNameInnerInterceptor extends InnerInterceptor {@Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {if (parameter instanceof Map) {Map<?, ?> paramMap = (Map<?, ?>) parameter;ShardingValue shardingValue = (ShardingValue) paramMap.get("shardingValue");if (shardingValue != null) {String tableName = "user_" + shardingValue.getValue() % 2; // 根據分片值計算表名String sql = boundSql.getSql().replaceFirst("user", tableName); // 替換原始 SQL 中的表名ReflectionUtils.setField(boundSql, "sql", sql); // 修改 BoundSql 中的 SQL}}}
}
9. 動態 SQL
在一些復雜的業務場景中,可能需要根據不同的條件動態生成 SQL,比如動態拼接 WHERE 子句、動態排序等。MyBatis-Plus 提供了方便的 API 來實現動態 SQL。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", status);
if (StringUtils.isNotBlank(keyword)) {wrapper.like("name", keyword);
}
wrapper.orderByDesc("create_time");
List<User> userList = userMapper.selectList(wrapper);
10. 樂觀鎖
在并發場景下,為了保證數據的一致性,可能會使用樂觀鎖機制來控制并發訪問。MyBatis-Plus 提供了樂觀鎖的支持,通過 @Version
注解標注實體類中的版本字段即可實現樂觀鎖功能。
@Version
@TableField(value = "version")
private Integer version;
11. 邏輯分頁
在一些特殊的場景中,可能需要進行復雜的分頁操作,比如根據某個字段的范圍進行分頁查詢。MyBatis-Plus 提供了邏輯分頁的功能,通過 last()
方法可以實現自定義的分頁邏輯。根據年齡大于等于 18 并按照創建時間降序排列的條件進行分頁查詢
IPage<User> page = new Page<>(1, 10);
userMapper.selectPage(page, Wrappers.<User>lambdaQuery().ge(User::getAge, 18).orderByDesc(User::getCreateTime).last("limit 10"));
12. 代碼生成器????????
public class CodeGenerator {public static void main(String[] args) {AutoGenerator generator = new AutoGenerator();// 配置數據源、包配置、策略配置等generator.execute();}
}
結語
MyBatis-Plus 是一個非常優秀的 MyBatis 增強工具包,它在簡化開發、提高效率、提升性能等方面都有著顯著的優勢,是開發中不可或缺的利器。希望本文對讀者對 MyBatis-Plus 的了解有所幫助,歡迎大家深入學習和使用 MyBatis-Plus。
?
更多文章
??Spring中的事務是如何實現的-CSDN博客
ZooKeeper 使用介紹和原理詳解-CSDN博客
Redis集群選舉流程詳解-CSDN博客
Hadoop技術解析:分布式存儲與計算-CSDN博客
ES底層原理深度剖析_es 的底層原理-CSDN博客
?