主题
MyBatis-Plus 数据访问
一、MyBatis-Plus 是什么
MyBatis-Plus(MP)是 MyBatis 的增强工具——只增强、不改变:单表 CRUD 不用写 SQL,复杂查询还能用 Lambda 表达式。是 Java 后端最主流的持久层框架。
核心能力:
BaseMapper内置 CRUD 方法LambdaQueryWrapper条件构造器(类型安全的条件查询)- 分页插件
- 逻辑删除、自动填充
二、Entity:表对应的 Java 类
java
package com.mall.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName("product") // 对应数据库表
public class Product {
@TableId(type = IdType.AUTO) // 主键自增
private Long id;
private String name;
private BigDecimal price;
private Integer stock;
private String image;
private String description;
@TableField("category_id") // 下划线字段 → 驼峰属性
private Long categoryId;
@TableLogic // 逻辑删除(查出来自动过滤 deleted=1)
private Integer deleted;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
}
map-underscore-to-camel-case: true配置后,category_id列会自动映射categoryId字段,多数场景不需要@TableField。
三、Mapper:数据访问接口
java
package com.mall.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mall.entity.Product;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
// 继承 BaseMapper,自动获得 insert/selectById/updateById/deleteById 等方法
}BaseMapper 常用方法:
| 方法 | 作用 |
|---|---|
selectById(id) | 按主键查 |
selectList(wrapper) | 条件查询列表 |
selectPage(page, wrapper) | 分页查询 |
insert(entity) | 插入 |
updateById(entity) | 按主键更新 |
deleteById(id) | 按主键删除 |
四、Service:业务层
java
package com.mall.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.entity.Product;
import com.mall.mapper.ProductMapper;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductService {
private final ProductMapper productMapper;
public ProductService(ProductMapper productMapper) {
this.productMapper = productMapper;
}
// 关键词 + 分类 + 分页 查询
public Page<Product> list(String keyword, Long categoryId, Integer page, Integer size) {
LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
wrapper.like(keyword != null && !keyword.isEmpty(), Product::getName, keyword)
.eq(categoryId != null, Product::getCategoryId, categoryId)
.orderByDesc(Product::getId);
return productMapper.selectPage(new Page<>(page, size), wrapper);
}
public Product getById(Long id) {
return productMapper.selectById(id);
}
}LambdaQueryWrapper 优势
Product::getName 写法在编译期就能发现字段写错(拼错直接编译不过),比字符串 "name" 安全。这是 MP 的推荐写法。
五、条件构造器速查
java
// 等值
wrapper.eq(Product::getCategoryId, 1)
// 模糊
wrapper.like(Product::getName, "手机")
// 范围
wrapper.between(Product::getPrice, 100, 1000)
// 大于
wrapper.gt(Product::getStock, 0)
// 排序
wrapper.orderByDesc(Product::getCreateTime)
// 逻辑 or
wrapper.eq(Product::getStatus, 1).or().eq(Product::getStatus, 2)
// 带条件的 eq(第一个参数为 true 才生效,配合前端可选参数)
wrapper.eq(keyword != null, Product::getCategoryId, categoryId)六、分页插件配置
MyBatis-Plus 分页需要先注册拦截器:
java
package com.mall.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;
}
}七、写复杂 SQL(XML)
单表查询用 MP,多表 join / 复杂统计用 XML:
java
// mapper/ProductMapper.java
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
// 商品列表联查分类名
IPage<ProductVO> selectProductPage(IPage<Product> page, @Param("keyword") String keyword);
}xml
<!-- resources/mapper/ProductMapper.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.mall.mapper.ProductMapper">
<select id="selectProductPage" resultType="com.mall.vo.ProductVO">
SELECT p.id, p.name, p.price, p.stock, p.image,
c.name AS categoryName
FROM product p
LEFT JOIN category c ON p.category_id = c.id
<where>
<if test="keyword != null and keyword != ''">
AND p.name LIKE CONCAT('%', #{keyword}, '%')
</if>
</where>
ORDER BY p.id DESC
</select>
</mapper>需要在 application.yml 里告诉 MP 去哪里找 XML:
yaml
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml八、验收
- [ ] 启动后控制台能看到 MP 打印的 SQL
- [ ]
/api/product/list?keyword=手机能按关键词查到商品 - [ ] 分页字段(total/records)正确
- [ ] 逻辑删除:删掉的记录查询时自动过滤
本章核心
MP 让你"单表 CRUD 不写 SQL"。但SQL 本身必须会——第 7 部分会讲透。框架帮你写,你要能看懂它写了什么。