Skip to content

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 部分会讲透。框架帮你写,你要能看懂它写了什么。

基于 MIT 协议发布,可自由学习与修改