跳到主要内容
Spring Boot 集成 MyBatis-Plus 数据库操作与完整 CRUD 示例 | 极客日志
Java java
Spring Boot 集成 MyBatis-Plus 数据库操作与完整 CRUD 示例 综述由AI生成 在 Spring Boot 项目中集成 MyBatis-Plus 的完整流程。内容包括依赖引入、数据源配置、Mapper 扫描及插件设置。核心功能涵盖基础 CRUD、条件查询构造器、分页查询、Service 层封装以及逻辑删除和乐观锁等扩展功能。此外,还提供了完整的 CRUD 项目代码示例,包括数据库脚本、配置文件、实体类、Mapper、Service 及 Controller 实现,并针对多表关联查询、动态 SQL 优化及批量操作性能提升给出了最佳实践方案。
心动瞬间 发布于 2026/3/30 更新于 2026/5/24 30 浏览如何在 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 接口测试集成效果:
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 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.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 方法 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 , 30 )
.orderByAsc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);
}
@Test
public void testAndOr () {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper <>();
wrapper.eq(User::getAge, 25 )
.and(w -> w.like(User::getName, "张" ).or().like(User::getEmail, "example.com" ));
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 接口与实现 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 {
}
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 的数据。
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);
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 >
<artifactId > mysql-connector-java</artifactId >
<version > 8.0.33</version >
</dependency >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<optional > true</optional >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-test</artifactId >
<scope > test</scope >
</dependency >
</dependencies >
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 success = userService.updateById(user);
return success ? "更新成功" : "更新失败(版本号不匹配)" ;
}
@GetMapping("/{id}")
public User getUserById (@PathVariable Long id) {
return userService.getById(id);
}
@GetMapping("/list")
public List<User> listUsers (@RequestParam(required = false) String name, @RequestParam(required = false) Integer minAge) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper <>();
wrapper.like(name != null , User::getName, name)
.ge(minAge != null , User::getAge, minAge);
return userService.list(wrapper);
}
@GetMapping("/page")
public Page<User> pageUsers (@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
Page<User> page = new Page <>(current, size);
return userService.page(page, null );
}
@PostMapping("/batch")
public String batchAddUsers (@RequestBody List<User> users) {
boolean success = userService.saveBatch(users);
return 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:
第二部分:复杂查询场景最佳实践 针对多表关联、动态 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" />
<result column ="order_amount" property ="amount" />
</collection >
</resultMap >
<select id ="selectUserOrderPage" resultMap ="UserOrderVOMap" >
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
<where >
u.deleted = 0
<if test ="name != null and name != ''" >
AND u.name LIKE CONCAT('%', #{name}, '%')
</if >
</where >
</select >
</mapper >
(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 执行性能。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online