如何在 Spring Boot 项目中集成 MyBatis-Plus?
一、引入依赖
在项目的 pom.xml 中添加 MyBatis-Plus 启动器和数据库驱动(以 MySQL 为例):
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
二、配置数据源与 MyBatis-Plus
在 application.yml(或 application.properties)中配置数据库连接和 MyBatis-Plus 基础设置:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/your_database?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
username: root
password: your_password
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
type-aliases-package: com.example.demo.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
三、配置 Mapper 扫描
在 Spring Boot 启动类上添加 @MapperScan 注解,指定 Mapper 接口的包路径:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
四、(可选)配置常用插件
若需使用分页、乐观锁等功能,可创建配置类注册插件:
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
五、快速验证
创建一个简单的实体类和 Mapper 接口测试集成效果:
- 实体类(
User.java):
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
}
- Mapper 接口(
UserMapper.java):
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
- 测试调用:
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void testInsert() {
User user = new User();
user.setName("张三");
user.setAge(25);
userMapper.insert(user);
System.out.println("插入成功,ID:" + user.getId());
}
}
如何在 Spring Boot 项目中使用 MyBatis-Plus 进行数据库操作?
在 Spring Boot 项目中使用 MyBatis-Plus 进行数据库操作,核心是利用其通用 Mapper、条件构造器和插件,无需编写大量 SQL 即可完成 80% 以上的单表操作。以下是完整的操作指南:
一、基础 CRUD 操作(通过 BaseMapper)
只要 Mapper 接口继承 BaseMapper<T>,即可自动拥有单表的增删改查能力。
1. 定义实体类与 Mapper
Mapper 接口:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
实体类(以 User 为例):
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
2. 调用 CRUD 方法
直接注入 UserMapper 即可使用:
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void addUser(User user) {
userMapper.insert(user);
}
public void deleteUserById(Long id) {
userMapper.deleteById(id);
}
public void updateUser(User user) {
userMapper.updateById(user);
}
public User getUserById(Long id) {
return userMapper.selectById(id);
}
public List<User> getAllUsers() {
return userMapper.selectList(null);
}
}
二、条件查询(通过 Wrapper 构造器)
对于复杂查询条件,使用 QueryWrapper 或 LambdaQueryWrapper 构建,避免手写 SQL。
1. 常用条件构造器
QueryWrapper:普通条件构造器,通过字段名(字符串)指定。
LambdaQueryWrapper:Lambda 形式,通过方法引用(如 User::getName)指定,避免字段名拼写错误(推荐)。
2. 常用条件方法示例
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class UserWrapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testQueryWrapper() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 25)
.like("name", "张")
.gt("age", 20)
.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
}
@Test
public void testLambdaQueryWrapper() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getAge, 25)
.like(User::getName, "张")
.between(User::getAge, 20, )
.orderByAsc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);
}
{
LambdaQueryWrapper<User> wrapper = <>();
wrapper.eq(User::getAge, )
.and(w -> w.like(User::getName, ).or().like(User::getEmail, ));
List<User> users = userMapper.selectList(wrapper);
}
}
三、分页查询
需先在配置类中注册 PaginationInnerInterceptor 插件(参考集成步骤),然后通过 Page 对象实现分页。
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class UserPageTest {
@Autowired
private UserMapper userMapper;
@Test
public void testPage() {
Page<User> page = new Page<>(1, 10);
Page<User> resultPage = userMapper.selectPage(page, null);
System.out.println("总记录数:" + resultPage.getTotal());
System.out.println("总页数:" + resultPage.getPages());
System.out.println("当前页数据:" + resultPage.getRecords());
}
}
四、Service 层封装(可选但推荐)
MyBatis-Plus 提供了 IService<T> 接口和 ServiceImpl<M, T> 实现类,进一步封装业务层操作。
1. 定义 Service 接口与实现
Service 实现类:
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
Service 接口:
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.User;
public interface UserService extends IService<User> {
}
2. 调用 Service 方法
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/batch")
public void batchAdd(@RequestBody List<User> users) {
userService.saveBatch(users);
}
@GetMapping("/list")
public List<User> listByIds(@RequestParam List<Long> ids) {
return userService.listByIds(ids);
}
@PutMapping("/batch")
public void batchUpdate(@RequestBody List<User> users) {
userService.updateBatchById(users);
}
}
五、扩展功能使用
1. 逻辑删除
- 调用
deleteById 时,实际执行的是 UPDATE user SET deleted=1 WHERE id=?,查询时自动过滤 deleted=1 的数据。
实体类字段添加 @TableLogic 注解:
import com.baomidou.mybatisplus.annotation.TableLogic;
@Data
@TableName("user")
public class User {
@TableLogic
private Integer deleted;
}
2. 乐观锁
更新时需传入 version 字段,若版本号不匹配则更新失败:
User user = userMapper.selectById(1L);
user.setName("李四");
userMapper.updateById(user);
实体类字段添加 @Version 注解:
import com.baomidou.mybatisplus.annotation.Version;
@Data
@TableName("user")
public class User {
@Version
private Integer version;
}
六、自定义 SQL(复杂查询场景)
若需编写复杂 SQL,可结合 MyBatis-Plus 的条件构造器使用。
1. Mapper 接口定义方法
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Param;
public interface UserMapper extends BaseMapper<User> {
IPage<User> selectUserPageByCondition(Page<User> page, @Param("name") String name);
}
2. 编写 XML 文件
在 resources/mapper/UserMapper.xml 中:
<?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.demo.mapper.UserMapper">
<select id="selectUserPageByCondition" resultType="com.example.demo.entity.User">
SELECT * FROM user
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
</where>
</select>
</mapper>
3. 调用自定义方法
Page<User> page = new Page<>(1, 10);
IPage<User> resultPage = userMapper.selectUserPageByCondition(page, "张");
MyBatis-Plus(完整 + 可运行)CRUD 项目代码示例
第一部分:完整 CRUD 项目代码示例
我们以「用户管理」为核心场景,覆盖实体映射、自动填充、逻辑删除、乐观锁、分页查询、Service 层封装等核心功能。
1. 数据库初始化脚本
先创建数据库和表(包含用户表 user,覆盖所有核心字段):
CREATE DATABASE IF NOT EXISTS mybatis_plus_demo DEFAULT CHARSET utf8mb4;
USE mybatis_plus_demo;
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL COMMENT '主键 ID',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`age` INT(11) DEFAULT NULL COMMENT '年龄',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
`deleted` TINYINT(1) DEFAULT '0' COMMENT '逻辑删除(0:未删除,1:已删除)',
`version` INT(11) DEFAULT '1' COMMENT '乐观锁版本号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
2. 项目依赖(pom.xml)
使用 Spring Boot 2.7.x + MyBatis-Plus 3.5.5(稳定兼容组合):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<>mysql-connector-java
8.0.33
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
3. 项目配置(application.yml)
配置数据库连接、MyBatis-Plus 基础设置和 SQL 日志:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
username: root
password: your_password
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
type-aliases-package: com.example.demo.entity
global-config:
db-config:
id-type: assign_id
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4. 核心代码实现
(1)实体类(User.java)
包含主键、自动填充、逻辑删除、乐观锁等注解:
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
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;
@TableLogic
private Integer deleted;
@Version
private Integer version;
}
(2)自动填充处理器(MyMetaObjectHandler.java)
实现 MetaObjectHandler 接口,自动设置创建时间和更新时间:
package com.example.demo.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@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());
}
}
(3)MyBatis-Plus 配置类(MybatisPlusConfig.java)
注册分页插件和乐观锁插件:
package com.example.demo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
(4)Mapper 接口(UserMapper.java)
继承 BaseMapper 即可拥有基础 CRUD 能力:
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
(5)Service 层
Service 实现类(UserServiceImpl.java):
package com.example.demo.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
Service 接口(UserService.java):
package com.example.demo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.User;
public interface UserService extends IService<User> {
}
(6)Controller 层(UserController.java)
提供 RESTful 接口,演示完整 CRUD 和分页查询:
package com.example.demo.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public String addUser(@RequestBody User user) {
boolean success = userService.save(user);
return success ? "新增成功,ID:" + user.getId() : "新增失败";
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
boolean success = userService.removeById(id);
return success ? "删除成功" : "删除失败";
}
@PutMapping
public String updateUser(@RequestBody User user) {
boolean userService.updateById(user);
success ? : ;
}
User {
userService.getById(id);
}
List<User> {
LambdaQueryWrapper<User> wrapper = <>();
wrapper.like(name != , User::getName, name)
.ge(minAge != , User::getAge, minAge);
userService.list(wrapper);
}
Page<User> {
Page<User> page = <>(current, size);
userService.page(page, );
}
String {
userService.saveBatch(users);
success ? : ;
}
}
(7)Spring Boot 启动类(DemoApplication.java)
添加 @MapperScan 注解扫描 Mapper 接口:
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
5. 快速测试
启动项目后,使用 Postman 或 curl 测试接口:
- 分页查询:GET
http://localhost:8080/user/page?current=1&size=10
- 条件查询:GET
http://localhost:8080/user/list?name=张&minAge=20
新增用户:POST http://localhost:8080/user,Body 传 JSON:
{
"name": "张三",
"age": 25,
"email": "[email protected]"
}
第二部分:复杂查询场景最佳实践
针对多表关联、动态 SQL、批量操作优化等复杂场景,以下是 MyBatis-Plus 的最佳实践方案。
场景 1:多表关联查询(用户 + 订单)
假设我们有一个订单表 order,需要查询「用户及其订单列表」,MyBatis-Plus 推荐结合自定义 XML 实现。
(1)数据库表扩展(订单表)
CREATE TABLE `order` (
`id` BIGINT(20) NOT NULL COMMENT '主键 ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户 ID',
`order_no` VARCHAR(50) DEFAULT NULL COMMENT '订单号',
`amount` DECIMAL(10,2) DEFAULT NULL COMMENT '订单金额',
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
(2)订单实体类(Order.java)
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName("order")
public class Order {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private Long userId;
private String orderNo;
private BigDecimal amount;
private LocalDateTime createTime;
}
(3)自定义 VO(UserOrderVO.java)
用于接收关联查询结果:
package com.example.demo.vo;
import com.example.demo.entity.Order;
import com.example.demo.entity.User;
import lombok.Data;
import java.util.List;
@Data
public class UserOrderVO extends User {
private List<Order> orderList;
}
(4)UserMapper 扩展方法
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.vo.UserOrderVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper extends BaseMapper<User> {
IPage<UserOrderVO> selectUserOrderPage(Page<UserOrderVO> page, @Param("name") String name);
}
(5)编写 UserMapper.xml
在 resources/mapper/UserMapper.xml 中实现关联查询:
<?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.demo.mapper.UserMapper">
<resultMap id="UserOrderVOMap" type="com.example.demo.vo.UserOrderVO">
<id column="user_id" property="id"/>
<result column="user_name" property="name"/>
<result column="user_age" property="age"/>
<collection property="orderList" ofType="com.example.demo.entity.Order">
<id column="order_id" property="id"/>
<result column="order_no" property="orderNo"/>
< = =/>
SELECT u.id AS user_id, u.name AS user_name, u.age AS user_age, o.id AS order_id, o.order_no, o.amount AS order_amount
FROM user u LEFT JOIN `order` o ON u.id = o.user_id
u.deleted = 0
AND u.name LIKE CONCAT('%', #{name}, '%')
(6)调用关联查询方法
@Autowired
private UserMapper userMapper;
@Test
public void testUserOrderPage() {
Page<UserOrderVO> page = new Page<>(1, 10);
IPage<UserOrderVO> resultPage = userMapper.selectUserOrderPage(page, "张");
System.out.println("总记录数:" + resultPage.getTotal());
System.out.println("用户订单列表:" + resultPage.getRecords());
}
场景 2:动态 SQL 优化(复杂条件组合)
对于多条件动态组合的查询,推荐使用 LambdaQueryWrapper 的 nested、and、or 方法,避免拼接 SQL 字符串。
@Test
public void testDynamicQuery() {
String name = "张";
Integer minAge = 20;
Integer maxAge = 30;
String email = "example.com";
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.nested(w -> w.like(name != null, User::getName, name).or().like(email != null, User::getEmail, email))
.and(w -> w.ge(minAge != null, User::getAge, minAge).le(maxAge != null, User::getAge, maxAge))
.orderByDesc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);
}
场景 3:批量操作优化(性能提升)
MyBatis-Plus 提供的 saveBatch 方法默认是逐条插入,若需提升性能,可通过rewriteBatchedStatements 参数开启 MySQL 批量插入优化。
(1)修改数据库连接 URL
在 application.yml 中添加 rewriteBatchedStatements=true:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis_plus_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true
(2)调整批量插入批次大小
saveBatch 方法默认批次大小为 1000,可通过第二个参数调整:
@Autowired
private UserService userService;
@Test
public void testBatchSaveOptimized() {
List<User> users = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setName("用户" + i);
user.setAge(20 + i % 30);
user.setEmail("user" + i + "@example.com");
users.add(user);
}
userService.saveBatch(users, 500);
}
第三部分:项目运行与调试建议
- SQL 日志:开发环境务必开启
log-impl,方便查看执行的 SQL 语句。
- 代码生成器:若需快速生成 Entity、Mapper、Service、Controller,可使用 MyBatis-Plus 官方代码生成器(引入
mybatis-plus-generator 依赖)。
- 性能监控:生产环境可结合 P6Spy 等工具监控 SQL 执行性能。