Mybatis-Plus高级特性的深入分析及Spring快速整合

MyBatis-Plus的高级特性

MyBatis-Plus 作为 MyBatis 的增强工具,提供了诸多高级特性:内置通用 Mapper 和 Service,支持 Lambda 查询,减少 SQL 编写;会自动生成实体类、Mapper 和 Service 代码;动态 SQL支持多租户、逻辑删除和动态表名;插件扩展提供分页、性能分析、乐观锁等插件;多数据源的支持简化了分布式数据库操作;SQL 注入器可扩展全局方法。这些特性显著提升开发效率,适用于复杂业务场景。

学长致力于Java后端及相关技术分享,可以悄悄的点个关注,偷偷告诉你,文末还可以领取39个八股文的PDF哟~快去看看(免费哟)


1、MyBatis-Plus的主要优势

  1. 简化开发:内置通用 Mapper 和通用 Service,减少大量模板代码

  2. 增强功能:提供条件构造器、代码生成器、分页插件等实用功能

  3. 性能优化:内置性能分析插件和 SQL 注入防护

  4. 开箱即用:无需额外配置即可使用大部分功能


2、核心高级特性

  1. ActiveRecord 模式:实体类可直接进行 CRUD 操作

  2. Lambda 表达式:类型安全的查询条件构造

  3. 自动填充:自动处理创建时间、更新时间等字段

  4. 逻辑删除:软删除实现

  5. 乐观锁:版本号控制并发

  6. 多租户:SAAS 系统支持

  7. 动态表名:按规则动态切换表名

  8. 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=false    username: root    password: root    driver-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;
    @Version    private Integer version; // 乐观锁版本号
    @TableLogic    private Integer deleted; // 逻辑删除}// Mapper 接口public interface UserMapper extends BaseMapper<User> {}// Service 层@Servicepublic class UserService {    @Autowired    private 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 {    @Autowired    private 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 {    @Override    public void insertFill(MetaObject metaObject) {        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());    }
    @Override    public void updateFill(MetaObject metaObject) {        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());    }}@Servicepublic class UserOptimisticLockService {    @Autowired    private 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 {    @Autowired    private 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 {    @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor() {        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 多租户插件        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {            @Override            public Expression getTenantId() {                // 从上下文获取租户ID                String tenantId = TenantContext.getCurrentTenant();                return new StringValue(tenantId);            }
            @Override            public String getTenantIdColumn() {                return "tenant_id";            }
            @Override            public boolean ignoreTable(String tableName) {                // 忽略不需要租户过滤的表                return "sys_tenant".equals(tableName);            }        }));
        return interceptor;    }}

动态表名处理:

public class DynamicTableNameParser implements ITableNameHandler {    @Override    public 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 表达式提供了类型安全的查询方式

  • 高级特性如多租户、动态表名等可以应对复杂业务需求

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值