使用SpringBoot+MyBatisPlus实现增删改查

MyBatisPlus教程

一 什么是MyBatisPlus

MyBatis-Plus(简称 MP)是一款基于 MyBatis 的增强工具,旨在简化 MyBatis 的开发流程,提供更高效、更便捷的数据库操作能力。它在 MyBatis 的基础上只做增强不做改变,既保留了 MyBatis 的原生功能,又通过封装常用操作减少了重复代码,让开发者更专注于业务逻辑。

核心特性

  1. 无侵入性:完全基于 MyBatis 开发,不改变其原有功能,兼容所有 MyBatis 原生特性。
  2. CRUD 自动生成:通过继承 BaseMapperIService,无需编写 XML 或 SQL,即可自动获得单表的增删改查(CRUD)操作。
  3. 条件构造器:提供 QueryWrapper/UpdateWrapper 等工具类,通过链式调用快速构建复杂 SQL 条件(如 WHERE、ORDER BY、GROUP BY 等),无需手动拼接 SQL。
  4. 分页插件:内置分页功能,支持多种数据库(MySQL、Oracle、SQL Server 等),只需简单配置即可实现分页查询。
  5. 代码生成器:通过配置可自动生成 Entity、Mapper、Service、Controller 等代码,减少重复开发。
  6. 逻辑删除:通过注解轻松实现逻辑删除(而非物理删除,即通过字段标记数据状态,如 deleted=1 表示删除)。
  7. 乐观锁:提供乐观锁插件,解决并发更新冲突问题(通过版本号字段控制)。
  8. 多种数据库支持:兼容主流关系型数据库,且支持自定义数据库方言。

优势

  • 简化开发:省去大量重复的 SQL 编写和 Mapper 接口方法定义,提高开发效率。
  • 降低学习成本:对 MyBatis 用户友好,只需了解 MP 的增强 API 即可快速上手。
  • 灵活扩展:支持自定义 SQL、XML 映射文件,可在自动生成的基础上扩展复杂业务逻辑。

适用场景

  • 基于 MyBatis 的 Spring/Spring Boot 项目,需要简化数据库操作。
  • 单表操作频繁,希望减少 CRUD 代码量的场景。
  • 需要快速实现分页、条件查询、逻辑删除等常见功能的项目。

二 环境搭建

image

1 创建 Maven 项目并添加依赖

创建一个 Maven 项目,项目名为MyBatisPlus-Demo,在 pom.xml 中添加以下依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- SpringBoot父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.4</version>
        <relativePath/>
    </parent>

    <groupId>com.yqd</groupId>
    <artifactId>MyBatisPlus-Demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>MyBatisPlus-Demo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- SpringWeb -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MyBatisPlus -->
        <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>5.1.37</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Lombok(简化实体类) -->
        <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2 配置数据库连接

src/main/resources/application.yml中配置数据库信息:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root  # 替换为你的数据库用户名
    password: 123456  # 替换为你的数据库密码

# MyBatisPlus配置
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml  # mapper.xml存放路径
  type-aliases-package: com.yqd.entity  # 实体类包路径
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印SQL日志(可选)

3 导入数据库

-- 创建数据库并设置字符集
CREATE DATABASE IF NOT EXISTS springbootdata;
CHARACTER SET utf8;
COLLATE utf8_unicode_ci;

-- 使用该数据库
USE springbootdata;

-- 创建书籍表(如果不存在)
CREATE TABLE IF NOT EXISTS books (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(200) NOT NULL,
    author VARCHAR(100) NOT NULL,
    press VARCHAR(100),
    status VARCHAR(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

三 代码实现

1 创建实体类(Entity)

对应books表创建实体类Book.java

package com.yqd.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data  // Lombok注解,自动生成getter/setter/toString等
@TableName("books")  // 对应数据库表名
public class Book {
    @TableId(type = IdType.AUTO)  // 主键自增
    private Long id;
    private String name;  // 书名
    private String author;  // 作者
    private String press;  // 出版社
    private String status;  // 状态(例如:在架/借出)
}

2 创建 Mapper 接口

继承 MyBatisPlus 的BaseMapper,自动获得基础 CRUD 方法:

package com.yqd.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yqd.entity.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper  // 标记为MyBatis的Mapper接口
public interface BookMapper extends BaseMapper<Book> {
    // 无需手动编写CRUD方法,BaseMapper已提供
}

3 创建 Service 层

3.1 Service 接口

package com.yqd.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.yqd.entity.Book;

public interface BookService extends IService<Book> {
    // 继承IService,获得更多增强CRUD方法
}

3.2 Service 实现类

package com.yqd.service.impl;

import com.yqd.entity.Book;
import com.yqd.mapper.BookMapper;
import com.yqd.service.BookService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

@Service  // 标记为服务层组件
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
    // 无需手动实现,ServiceImpl已实现基础方法
}

4 创建 Controller 层(API 接口)

实现增删改查的 HTTP 接口:

package com.yqd.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yqd.entity.Book;
import com.yqd.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/books")  // 基础路径
public class BookController {

    @Autowired
    private BookService bookService;

    // 1. 新增书籍
    @PostMapping
    public boolean addBook(@RequestBody Book book) {
        return bookService.save(book);
    }

    // 2. 删除书籍(根据ID)
    @DeleteMapping("/{id}")
    public boolean deleteBook(@PathVariable Long id) {
        return bookService.removeById(id);
    }

    // 3. 更新书籍
    @PutMapping
    public boolean updateBook(@RequestBody Book book) {
        return bookService.updateById(book);
    }

    // 4. 查询单本书籍(根据ID)
    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return bookService.getById(id);
    }

    // 5. 查询所有书籍
    @GetMapping
    public List<Book> getAllBooks() {
        return bookService.list();
    }

    // 6. 条件查询(例如:按作者查询)
    @GetMapping("/byAuthor")
    public List<Book> getBooksByAuthor(@RequestParam String author) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author", author);  // 等价于 WHERE author = ?
        return bookService.list(queryWrapper);
    }

    // 7. 分页查询
    @GetMapping("/page")
    public Page<Book> getBooksByPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize
    ) {
        Page<Book> page = new Page<>(pageNum, pageSize);
        return bookService.page(page);
    }

    // 8. 批量新增书籍
    @PostMapping("/batch")
    public boolean addBooksBatch(@RequestBody List<Book> books) {
        return bookService.saveBatch(books);
    }
}

5 配置 MyBatisPlus 分页插件

创建配置类,启用分页功能:

package com.yqd.config;

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());  // 添加分页拦截器
        return interceptor;
    }
}

6 启动类

package com.yqd;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(value = {"com.yqd.mapper"})
public class MyBatisPlusDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisPlusDemoApplication.class, args);
    }
}

四 系统测试

4.1 测试环境准备

  • 启动 SpringBoot 项目,确保服务运行在 http://localhost:8080
  • 数据库已初始化 springbootdata 库和 books
  • 安装 Postman(或使用其他 API 测试工具,如 curl、Apifox 等)

4.2 测试步骤及示例

1. 新增书籍(单条)

  • 请求方式POST

  • 请求地址http://localhost:8080/books

  • 请求头Content-Type: application/json

  • 请求体(JSON)

    {
      "name": "红楼梦",
      "author": "曹雪芹",
      "press": "人民文学出版社",
      "status": "在架"
    }
    
  • 预期响应true(表示新增成功)

2. 批量新增书籍

  • 请求方式POST

  • 请求地址http://localhost:8080/books/batch(需提前在 Controller 中添加批量接口,见前文)

  • 请求头Content-Type: application/json

  • 请求体(JSON 数组)

    [
      {
        "name": "三国演义",
        "author": "罗贯中",
        "press": "中华书局",
        "status": "在架"
      },
      {
        "name": "水浒传",
        "author": "施耐庵",
        "press": "人民文学出版社",
        "status": "借出"
      },
      {
        "name": "西游记",
        "author": "吴承恩",
        "press": "中华书局",
        "status": "在架"
      }
    ]
    
  • 预期响应true(表示批量新增成功)

3. 查询所有书籍

  • 请求方式GET

  • 请求地址http://localhost:8080/books

  • 预期响应

    :返回包含所有书籍的 JSON 数组,例如:

    [
      {
        "id": 1,
        "name": "红楼梦",
        "author": "曹雪芹",
        "press": "人民文学出版社",
        "status": "在架"
      },
      {
        "id": 2,
        "name": "三国演义",
        "author": "罗贯中",
        "press": "中华书局",
        "status": "在架"
      }
    ]
    

4. 查询单本书籍(按 ID)

  • 请求方式GET

  • 请求地址http://localhost:8080/books/1(假设 ID=1 的书籍存在)

  • 预期响应

    :返回 ID=1 的书籍详情:

    {
      "id": 1,
      "name": "红楼梦",
      "author": "曹雪芹",
      "press": "人民文学出版社",
      "status": "在架"
    }
    

5. 条件查询(按作者)

  • 请求方式GET

  • 请求地址http://localhost:8080/books/byAuthor?author=罗贯中

  • 预期响应

    :返回所有作者为 “罗贯中” 的书籍:

    [
      {
        "id": 2,
        "name": "三国演义",
        "author": "罗贯中",
        "press": "中华书局",
        "status": "在架"
      }
    ]
    

6. 分页查询

  • 请求方式GET

  • 请求地址http://localhost:8080/books/page?pageNum=1&pageSize=2(第 1 页,每页 2 条)

  • 预期响应

    :返回分页结果(包含总条数、当前页数据等):

    {
      "records": [
        {
          "id": 1,
          "name": "红楼梦",
          "author": "曹雪芹",
          "press": "人民文学出版社",
          "status": "在架"
        },
        {
          "id": 2,
          "name": "三国演义",
          "author": "罗贯中",
          "press": "中华书局",
          "status": "在架"
        }
      ],
      "total": 3,  // 总条数
      "size": 2,   // 每页条数
      "current": 1, // 当前页
      "pages": 2    // 总页数
    }
    

7. 更新书籍

  • 请求方式PUT

  • 请求地址http://localhost:8080/books

  • 请求头Content-Type: application/json

  • 请求体(JSON):(修改 ID=1 的书籍状态为 “借出”)

    {
      "id": 1,
      "name": "红楼梦",
      "author": "曹雪芹",
      "press": "人民文学出版社",
      "status": "借出"
    }
    
  • 预期响应true(表示更新成功)

  • 验证:调用 “查询单本书籍(ID=1)” 接口,确认status已改为 “借出”。

8. 删除书籍

  • 请求方式DELETE
  • 请求地址http://localhost:8080/books/3(删除 ID=3 的书籍)
  • 预期响应true(表示删除成功)
  • 验证:调用 “查询所有书籍” 接口,确认 ID=3 的书籍已不存在。

4.3 测试注意事项

  1. 依赖顺序:部分接口依赖前置操作(例如 “更新” 和 “删除” 需要先有数据,需先执行 “新增”)。
  2. 参数正确性
    • 新增 / 更新时,nameauthor为非空字段,若为空会返回false(需在后端添加校验优化,此处仅为基础测试)。
    • 分页查询的pageNumpageSize需为正整数。
  3. 错误场景测试
    • 查询不存在的 ID(如http://localhost:8080/books/999),预期返回null
    • 删除不存在的 ID,预期返回false
posted @ 2025-10-16 20:39  碧水云天4  阅读(56)  评论(0)    收藏  举报