mybatisplus(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言:为什么选择 MyBatisPlus?

在 Java 后端开发领域,数据库操作始终是开发者需要频繁面对的核心任务。传统 MyBatis 虽然功能强大,但其繁琐的 XML 配置和重复代码编写让许多开发者感到疲惫。正是在这种背景下,MyBatisPlus 应运而生,它通过一系列增强功能和简化设计,将 MyBatis 的开发效率提升了数倍。本文将通过循序渐进的方式,帮助编程初学者和中级开发者理解 MyBatisPlus 的核心理念,并掌握其在实际项目中的应用技巧。


一、MyBatisPlus 的核心功能解析

1.1 什么是 MyBatisPlus?

MyBatisPlus 是基于 MyBatis 的增强工具,通过简化 CRUD 操作、提供通用方法、增强查询条件等方式,大幅减少开发者的重复劳动。想象一下,如果你在装修房子时,原本需要自己切割瓷砖,而 MyBatisPlus 就像一位经验丰富的装修师傅,直接为你提供切割好的瓷砖,你只需按照图纸拼装即可。

1.2 核心功能概述

  • 代码生成器:自动生成实体类、Mapper、Service 等代码框架,节省 80% 的模板化开发时间。
  • 链式查询:通过 QueryWrapper 等工具,实现复杂 SQL 的链式调用,避免 XML 的冗余配置。
  • 自动填充:支持创建时间、更新时间等字段的自动填充,无需手动编写逻辑。
  • 逻辑删除:通过标记字段替代物理删除,保留数据历史记录,同时不影响业务逻辑。
  • 分页插件:提供统一的分页接口,兼容多种数据库的分页语法。

二、快速入门:从零开始搭建 MyBatisPlus 环境

2.1 项目环境准备

假设我们使用 Maven 管理项目依赖,只需在 pom.xml 中添加以下依赖:

<!-- MyBatisPlus 核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
<!-- 数据库驱动(以 MySQL 为例) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>

2.2 配置数据库连接

application.properties 中配置数据库信息:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

2.3 第一个 MyBatisPlus 示例

步骤 1:创建实体类

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

步骤 2:创建 Mapper 接口

public interface UserMapper extends BaseMapper<User> { }

步骤 3:使用 Service 层操作数据

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public void addUser() {
        User user = new User();
        user.setName("张三");
        user.setAge(25);
        user.setEmail("zhangsan@example.com");
        userMapper.insert(user); // 自动完成 SQL 生成
    }
}

三、深入理解核心概念与高级特性

3.1 链式查询:优雅的 SQL 构建方式

通过 QueryWrapper,可以轻松实现复杂查询条件的拼接:

// 查询年龄大于 20 且邮箱包含 "example" 的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 20)
       .like("email", "example");
List<User> users = userMapper.selectList(wrapper);

3.2 自动填充:让字段维护更智能

通过 MetaObjectHandler 接口,可以实现字段的自动填充:

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("create_time", LocalDateTime.now(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("update_time", LocalDateTime.now(), metaObject);
    }
}

3.3 逻辑删除:数据安全与历史保留

在实体类中添加 deleted 字段,并在全局配置中启用逻辑删除:

@Configuration
public class MyBatisPlusConfig {
    @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig config = new GlobalConfig();
        config.setMetaObjectHandler(new MyMetaObjectHandler());
        config.setLogicDeleteValue("1");
        config.setLogicNotDeleteValue("0");
        return config;
    }
}

四、实战案例:构建用户管理系统

4.1 需求分析

开发一个简单的用户管理模块,包含以下功能:

  1. 用户信息增删改查
  2. 根据年龄分组统计用户数量
  3. 支持分页查询

4.2 实现步骤

步骤 1:设计数据库表

CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT NOT NULL,
    email VARCHAR(100) UNIQUE,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    deleted TINYINT DEFAULT 0
);

步骤 2:编写 Service 层代码

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    // 分页查询示例
    public IPage<User> getUsers(int currentPage, int pageSize) {
        Page<User> page = new Page<>(currentPage, pageSize);
        return userMapper.selectPage(page, null);
    }

    // 统计年龄分组
    public List<Map<String, Object>> countByAge() {
        return userMapper.selectObjs(
            new QueryWrapper<User>()
                .groupBy("age")
                .select("age, COUNT(*) AS count")
        ).stream()
         .map(obj -> {
             Map<String, Object> map = new HashMap<>();
             Map<String, Object> row = (Map<String, Object>) obj;
             map.put("age", row.get("age"));
             map.put("count", row.get("count"));
             return map;
         })
         .collect(Collectors.toList());
    }
}

4.3 控制层实现

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/users")
    public IPage<User> getUsers(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "10") int size
    ) {
        return userService.getUsers(page, size);
    }
}

五、性能优化与最佳实践

5.1 分页查询优化

使用 Page 对象时,建议通过 select 方法指定需要的字段,减少网络传输:

Page<User> page = new Page<>(1, 10);
page.addOrderDesc("age");
userMapper.selectPage(page, new QueryWrapper<User>().select("id", "name"));

5.2 避免 N+1 查询

通过 LambdaQueryWrapperlast 方法添加 JOIN 语句,或使用 MyBatisPlus 的 join 工具类优化关联查询。

5.3 事务管理

对于需要事务支持的操作,使用 @Transactional 注解,并合理配置回滚规则:

@Transactional(rollbackFor = Exception.class)
public void batchInsert(List<User> users) {
    users.forEach(user -> userMapper.insert(user));
}

六、常见问题与解决方案

6.1 "No mapper was found in" 错误

确保 Mapper 接口路径被正确扫描,或在启动类上添加 @MapperScan("com.example.mapper")

6.2 自动填充不生效

检查 MetaObjectHandler 是否被正确注入,并确认实体类字段名与数据库列名匹配。


结论:MyBatisPlus 的价值与未来展望

MyBatisPlus 通过其简洁的设计和强大的功能,已经成为现代 Java 后端开发中不可或缺的工具。它不仅降低了开发门槛,还通过一系列优化策略提升了代码的可维护性和扩展性。对于开发者而言,掌握 MyBatisPlus 不仅能显著提升工作效率,更能为构建高性能、可扩展的企业级应用奠定坚实基础。

随着技术的不断演进,MyBatisPlus 的生态也在持续丰富,例如与 Spring Boot 的深度集成、异步查询支持等新特性。建议开发者定期关注官方文档和社区动态,以充分利用最新的功能优化。希望本文能为你打开 MyBatisPlus 的学习之门,并在实际项目中发挥其最大价值。

最新发布