第38课:MyBatis-Plus
本课目标:掌握MyBatis-Plus的使用,包括BaseMapper、条件构造器、分页查询,提升开发效率。
一、概念讲解
1.1 什么是MyBatis-Plus
MyBatis-Plus是MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,简化开发、提高效率。
┌─────────────────────────────────────────────────────────────┐
│ MyBatis-Plus特性 │
├─────────────────────────────────────────────────────────────┤
│ – 通用CRUD,无需编写SQL │
│ – 条件构造器,链式调用 │
│ – 分页插件,开箱即用 │
│ – 代码生成器 │
│ – 逻辑删除 │
│ – 自动填充 │
└─────────────────────────────────────────────────────────────┘
1.2 架构关系
┌─────────────────────────────────────────┐
│ MyBatis-Plus │
├─────────────────────────────────────────┤
│ IService Service层增强 │
│ BaseMapper Mapper层增强 │
│ Wrapper 条件构造器 │
├─────────────────────────────────────────┤
│ MyBatis │
├─────────────────────────────────────────┤
│ SqlSession 会话 │
│ Mapper 映射器 │
│ XML 映射文件 │
└─────────────────────────────────────────┘
二、语法格式
2.1 BaseMapper方法
// 插入
int insert(T entity);
// 删除
int deleteById(Serializable id);
int deleteByMap(Map<String, Object> map);
int delete(Wrapper<T> wrapper);
int deleteBatchIds(Collection<? extends Serializable> idList);
// 更新
int updateById(T entity);
int update(T entity, Wrapper<T> wrapper);
// 查询
T selectById(Serializable id);
List<T> selectList(Wrapper<T> wrapper);
T selectOne(Wrapper<T> wrapper);
int selectCount(Wrapper<T> wrapper);
List<T> selectPage(Page<T> page, Wrapper<T> wrapper);
2.2 条件构造器
// QueryWrapper
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
.like("email", "@example.com")
.orderByDesc("create_time");
// LambdaQueryWrapper (推荐)
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(User::getName, "张三")
.like(User::getEmail, "@example.com");
// LambdaUpdateWrapper
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(User::getName, "李四")
.eq(User::getId, 1);
三、代码案例
3.1 Maven依赖
<dependencies>
<!– MyBatis-Plus –>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!– MySQL驱动 –>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!– Lombok (可选) –>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
3.2 实体类
package com.example.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.util.Date;
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@TableLogic
private Integer deleted;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// getter/setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
public Date getUpdateTime() { return updateTime; }
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
public Integer getDeleted() { return deleted; }
public void setDeleted(Integer deleted) { this.deleted = deleted; }
}
3.3 Mapper接口
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
public interface UserMapper extends BaseMapper<User> {
// MyBatis-Plus已经提供通用CRUD,无需编写基础方法
}
3.4 Service接口和实现
package com.example.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.User;
import java.util.List;
public interface UserService extends IService<User> {
List<User> findByName(String name);
}
package com.example.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService {
@Override
public List<User> findByName(String name) {
return lambdaQuery()
.like(User::getName, name)
.list();
}
}
3.5 条件构造器使用
package com.example;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.User;
import com.example.mapper.UserMapper;
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 UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
User user = new User("张三", "zhangsan@example.com");
int rows = userMapper.insert(user);
System.out.println("插入行数: " + rows);
System.out.println("生成ID: " + user.getId());
}
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println("用户: " + user);
}
@Test
public void testSelectList() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
@Test
public void testSelectByWrapper() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "张")
.orderByDesc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
@Test
public void testUpdate() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.set(User::getName, "李四")
.eq(User::getId, 1);
int rows = userMapper.update(null, wrapper);
System.out.println("更新行数: " + rows);
}
@Test
public void testDelete() {
int rows = userMapper.deleteById(1L);
System.out.println("删除行数: " + rows);
}
@Test
public void testPage() {
Page<User> page = new Page<>(1, 10);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(User::getCreateTime);
Page<User> result = userMapper.selectPage(page, wrapper);
System.out.println("总数: " + result.getTotal());
System.out.println("当前页数据: " + result.getRecords());
}
@Test
public void testCount() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "张");
int count = userMapper.selectCount(wrapper);
System.out.println("数量: " + count);
}
}
▶ 运行结果:
// testInsert
插入行数: 1
生成ID: 1
// testSelectById
用户: User{id=1, name='张三', email='zhangsan@example.com'}
// testSelectList
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}
// testUpdate
更新行数: 1
// testDelete
删除行数: 1
// testPage
总数: 10
当前页数据: [User{id=1, name='李四', email='lisi@example.com'}, …]
// testCount
数量: 3
3.6 分页配置
package com.example.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
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));
return interceptor;
}
}
3.7 代码生成器
package com.example.generator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create(
"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8",
"root", "123456")
.globalConfig(builder -> {
builder.author("example")
.outputDir("F:\\\\code\\\\output")
.disableOpenDir();
})
.packageConfig(builder -> {
builder.parent("com.example")
.moduleName("demo")
.entity("entity")
.mapper("mapper")
.service("service")
.controller("controller");
})
.strategyConfig(builder -> {
builder.addInclude("user", "order")
.entityBuilder()
.naming(NamingStrategy.underline_to_camel)
.columnNaming(NamingStrategy.underline_to_camel)
.enableLombok()
.controllerBuilder()
.enableRestStyle();
})
.execute();
}
}
四、常见错误
| Invalid bound statement | Mapper方法未找到 | 检查接口方法名和XML |
| 字段映射错误 | 命名不匹配 | 使用@TableField或开启驼峰映射 |
| 分页不生效 | 未配置分页插件 | 添加PaginationInnerInterceptor |
| 逻辑删除无效 | 未配置@TableLogic | 添加@TableLogic注解 |
| 自动填充不触发 | 未实现MetaObjectHandler | 实现填充处理器 |
五、课后练习
六、本课小结
| BaseMapper | 通用Mapper,提供基础CRUD |
| IService | 通用Service,提供业务方法 |
| LambdaWrapper | 类型安全的条件构造器 |
| 分页插件 | PaginationInnerInterceptor |
| 代码生成器 | 自动生成Controller/Service/Mapper |
本课程持续更新中,欢迎关注!





