MyBatis-Plus的高级特性
MyBatis-Plus 作为 MyBatis 的增强工具,提供了诸多高级特性:内置通用 Mapper 和 Service,支持 Lambda 查询,减少 SQL 编写;会自动生成实体类、Mapper 和 Service 代码;动态 SQL支持多租户、逻辑删除和动态表名;插件扩展提供分页、性能分析、乐观锁等插件;多数据源的支持简化了分布式数据库操作;SQL 注入器可扩展全局方法。这些特性显著提升开发效率,适用于复杂业务场景。
学长致力于Java后端及相关技术分享,可以悄悄的点个关注,偷偷告诉你,文末还可以领取39个八股文的PDF哟~快去看看(免费哟)
1、MyBatis-Plus的主要优势
-
简化开发:内置通用 Mapper 和通用 Service,减少大量模板代码
-
增强功能:提供条件构造器、代码生成器、分页插件等实用功能
-
性能优化:内置性能分析插件和 SQL 注入防护
-
开箱即用:无需额外配置即可使用大部分功能
2、核心高级特性
-
ActiveRecord 模式:实体类可直接进行 CRUD 操作
-
Lambda 表达式:类型安全的查询条件构造
-
自动填充:自动处理创建时间、更新时间等字段
-
逻辑删除:软删除实现
-
乐观锁:版本号控制并发
-
多租户:SAAS 系统支持
-
动态表名:按规则动态切换表名
-
SQL 注入器:自定义全局 SQL 方法
3、Spring 整合 MyBatis-Plus
首先添加依赖:
<!-- pom.xml --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>最新版本</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>最新版本</version></dependency>
配置 application.yml:
spring:datasource:url: jdbc:mysql://localhost:3306/test?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL日志global-config:db-config:id-type: auto # 主键策略logic-delete-field: deleted # 逻辑删除字段logic-delete-value: 1 # 逻辑已删除值logic-not-delete-value: 0 # 逻辑未删除值
基础 CRUD 操作(复制可用):
@Data@TableName("user")public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@Versionprivate Integer version; // 乐观锁版本号@TableLogicprivate Integer deleted; // 逻辑删除}// Mapper 接口public interface UserMapper extends BaseMapper<User> {}// Service 层@Servicepublic class UserService {@Autowiredprivate UserMapper userMapper;public void testCRUD() {// 插入User user = new User();user.setName("张三");user.setAge(25);user.setEmail("zhangsan@example.com");userMapper.insert(user);// 更新user.setAge(26);userMapper.updateById(user);// 查询User dbUser = userMapper.selectById(user.getId());// 删除userMapper.deleteById(user.getId());}}
条件构造器与分页:
@Servicepublic class UserQueryService {@Autowiredprivate UserMapper userMapper;public void testQueryWrapper() {// 条件查询QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.lambda().ge(User::getAge, 20).le(User::getAge, 30).like(User::getName, "张").orderByDesc(User::getAge);List<User> users = userMapper.selectList(wrapper);// 分页查询Page<User> page = new Page<>(1, 10); // 第一页,每页10条IPage<User> userPage = userMapper.selectPage(page, wrapper);System.out.println("总记录数: " + userPage.getTotal());System.out.println("总页数: " + userPage.getPages());userPage.getRecords().forEach(System.out::println);}}
自动填充与乐观锁:
@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}@Overridepublic void updateFill(MetaObject metaObject) {this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}}@Servicepublic class UserOptimisticLockService {@Autowiredprivate UserMapper userMapper;public void testOptimisticLock() {// 模拟并发更新User user = userMapper.selectById(1L);user.setName("新名称");// 另一个线程先更新了数据,version会变化User user2 = userMapper.selectById(1L);user2.setName("另一个名称");userMapper.updateById(user2);// 此时user的version已经过期,更新会失败int result = userMapper.updateById(user);if (result == 0) {System.out.println("更新失败,数据已被其他线程修改");}}}
Lambda 表达式查询:
public class UserLambdaService {@Autowiredprivate UserMapper userMapper;public void testLambdaQuery() {// 使用Lambda表达式,避免字段名硬编码List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery().select(User::getId, User::getName) // 只查询特定字段.gt(User::getAge, 18).between(User::getCreateTime,LocalDateTime.now().minusDays(30),LocalDateTime.now()).orderByAsc(User::getAge));// 使用Lambda更新userMapper.update(null, Wrappers.<User>lambdaUpdate().set(User::getEmail, "updated@example.com").eq(User::getName, "张三"));}}
4、高级特性实现
多租户实现:
@Configurationpublic class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 多租户插件interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {@Overridepublic Expression getTenantId() {// 从上下文获取租户IDString tenantId = TenantContext.getCurrentTenant();return new StringValue(tenantId);}@Overridepublic String getTenantIdColumn() {return "tenant_id";}@Overridepublic boolean ignoreTable(String tableName) {// 忽略不需要租户过滤的表return "sys_tenant".equals(tableName);}}));return interceptor;}}
动态表名处理:
public class DynamicTableNameParser implements ITableNameHandler {@Overridepublic String dynamicTableName(String sql, String tableName) {// 根据业务规则动态返回表名if ("order".equals(tableName)) {return "order_" + LocalDate.now().getYear();}return tableName;}}// 配置@Beanpublic DynamicTableNameParser dynamicTableNameParser() {return new DynamicTableNameParser();}@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor(dynamicTableNameParser()));return interceptor;}
MyBatis-Plus 通过提供丰富的增强功能,显著简化了 MyBatis 的开发流程。与 Spring 的整合非常简便,通过上述案例可以看到:
-
基础 CRUD 操作几乎不需要编写 SQL
-
条件构造器让复杂查询更加直观
-
自动填充、乐观锁等特性简化了常见业务场景的实现
-
Lambda 表达式提供了类型安全的查询方式
-
高级特性如多租户、动态表名等可以应对复杂业务需求
1万+

被折叠的 条评论
为什么被折叠?



