缩略图

MyBatisPlus高效开发实践指南

2025年10月20日 文章分类 会被自动插入 会被自动插入
本文最后更新于2025-10-20已经过去了40天请注意内容时效性
热度47 点赞 收藏0 评论0

MyBatisPlus高效开发实践指南

引言

在现代企业级应用开发中,数据持久层框架的选择对开发效率和系统性能有着至关重要的影响。MyBatis作为一款优秀的持久层框架,在国内拥有广泛的应用基础。而MyBatisPlus在MyBatis的基础上进行了深度封装和功能增强,为开发者提供了更加便捷、高效的开发体验。本文将深入探讨MyBatisPlus的核心特性、使用方法和最佳实践,帮助开发者充分利用这一强大工具提升开发效率。

MyBatisPlus概述

什么是MyBatisPlus

MyBatisPlus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。它内置了通用的Mapper和Service,通过少量的配置即可实现单表的大部分CRUD操作,同时提供了强大的条件构造器,满足各类复杂查询需求。

核心特性

  1. 无侵入性:只在MyBatis的基础上进行扩展,不会影响现有项目
  2. 强大的CRUD操作:内置通用Mapper,实现单表CRUD操作无需编写XML
  3. 支持Lambda形式调用:通过Lambda表达式,避免字段硬编码
  4. 支持主键自动生成:内置多种主键策略,支持分布式唯一ID生成
  5. 内置分页插件:基于MyBatis物理分页,无需关心具体实现
  6. SQL性能分析插件:开发环境支持SQL执行效率分析,快速定位慢查询
  7. 全局拦截插件:提供全表删除、更新操作阻断机制

环境配置与集成

依赖引入

在Spring Boot项目中引入MyBatisPlus Starter依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

基础配置

在application.yml中进行基础配置:

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0

启动类配置

在Spring Boot启动类上添加Mapper扫描注解:

@SpringBootApplication
@MapperScan("com.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

实体类设计与注解

基础实体类设计

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    private String username;

    private String email;

    private Integer age;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @TableLogic
    private Integer deleted;
}

常用注解详解

  1. @TableName:指定数据库表名
  2. @TableId:指定主键字段,支持多种主键策略
  3. @TableField:指定字段映射关系,支持自动填充
  4. @TableLogic:逻辑删除注解
  5. @Version:乐观锁注解

字段自动填充策略

实现MetaObjectHandler接口实现自动填充:

@Component
public 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());
    }
}

Mapper层开发实践

基础Mapper接口

public interface UserMapper extends BaseMapper<User> {
    // 自定义方法
    List<User> selectByAgeGreaterThan(@Param("age") Integer age);
}

自定义SQL实现

在对应的XML文件中实现自定义SQL:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">

    <select id="selectByAgeGreaterThan" resultType="com.example.entity.User">
        SELECT * FROM user WHERE age > #{age} AND deleted = 0
    </select>

</mapper>

通用Mapper方法详解

BaseMapper提供了丰富的通用方法:

  • insert:插入记录
  • deleteById:根据主键删除
  • updateById:根据主键更新
  • selectById:根据主键查询
  • selectBatchIds:根据主键批量查询
  • selectByMap:根据条件查询
  • selectPage:分页查询

Service层封装技巧

基础Service接口

public interface UserService extends IService<User> {
    // 自定义业务方法
    List<User> findActiveUsers();

    Page<User> findUsersByPage(Page<User> page, UserQuery query);
}

Service实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public List<User> findActiveUsers() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getDeleted, 0)
               .orderByDesc(User::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public Page<User> findUsersByPage(Page<User> page, UserQuery query) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(query.getUsername()), 
                    User::getUsername, query.getUsername())
               .ge(query.getMinAge() != null, 
                    User::getAge, query.getMinAge())
               .le(query.getMaxAge() != null, 
                    User::getAge, query.getMaxAge())
               .eq(User::getDeleted, 0);
        return this.page(page, wrapper);
    }
}

事务管理

@Service
@Transactional(rollbackFor = Exception.class)
public class UserTransactionService {

    @Autowired
    private UserService userService;

    public void batchUpdateUsers(List<User> users) {
        for (User user : users) {
            userService.updateById(user);
        }
    }
}

条件构造器深度解析

QueryWrapper使用

// 创建查询条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("id", "username", "email")
       .like("username", "张")
       .between("age", 18, 30)
       .isNotNull("email")
       .orderByDesc("create_time");

List<User> users = userMapper.selectList(wrapper);

LambdaQueryWrapper优势

LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(User::getId, User::getUsername, User::getEmail)
             .like(User::getUsername, "张")
             .between(User::getAge, 18, 30)
             .isNotNull(User::getEmail)
             .orderByDesc(User::getCreateTime);

List<User> users = userMapper.selectList(lambdaWrapper);

复杂条件组合

public List<User> complexQuery(UserQuery query) {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

    // 条件组合
    wrapper.and(qw -> qw
            .like(User::getUsername, query.getKeyword())
            .or()
            .like(User::getEmail, query.getKeyword()))
           .ge(User::getAge, query.getMinAge())
           .le(User::getAge, query.getMaxAge())
           .in(User::getStatus, query.getStatusList())
           .groupBy(User::getType)
           .having("COUNT(*) > {0}", 1);

    return userMapper.selectList(wrapper);
}

分页查询最佳实践

分页配置

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

分页查询实现


public Page<User> searchUsers(UserSearchDTO searchDTO) {
    // 创建分页对象
    Page<User> page = new Page<>(searchDTO.getCurrent(), searchDTO.getSize());

    // 构建查询条件
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(StringUtils.isNotBlank(searchDTO.getKeyword()),
                User::get
正文结束 阅读本文相关话题
相关阅读
评论框
正在回复
评论列表

暂时还没有任何评论,快去发表第一条评论吧~

空白列表
sitemap