Spring Boot 遇上 MyBatis-Plus:高效开发的奇妙之旅

一、引言

在 Java 企业级开发中,数据持久层的选择至关重要,它直接影响到系统的性能、可维护性以及开发效率。MyBatis 作为一款优秀的持久层框架,以其灵活的 SQL 映射和强大的 SQL 生成能力,在 Java 开发领域中占据着重要的地位 。然而,MyBatis 在使用过程中,开发者往往需要编写大量重复的 SQL 语句和 XML 配置文件,这无疑增加了开发的工作量和复杂度。

MyBatis-Plus 应运而生,它是 MyBatis 的一个增强工具,在 MyBatis 的基础上进行了功能扩展,既保留了 MyBatis 的所有特性,又极大地简化了开发流程。MyBatis-Plus 提供了丰富的通用 CRUD 操作,内置的代码生成器可以自动生成实体类、Mapper 接口、Service 层和 Controller 层代码,大大减少了开发者的重复劳动,使开发者能够将更多的精力集中在业务逻辑的实现上。

而 Spring Boot 作为当前最流行的 Java 开发框架之一,以其快速开发、自动配置和便捷的部署等特性,深受开发者的喜爱。它通过约定大于配置的方式,大大减少了项目的配置工作量,使得开发人员能够快速搭建一个生产级别的应用程序。

将 MyBatis-Plus 与 Spring Boot 进行整合,能够充分发挥两者的优势,为 Java 开发带来诸多好处。一方面,Spring Boot 的自动配置特性可以快速集成 MyBatis-Plus,减少繁琐的配置过程;另一方面,MyBatis-Plus 的强大功能可以为 Spring Boot 项目提供高效的数据持久化解决方案。这种整合不仅能够提高开发效率,减少代码量,还能提升系统的性能和可维护性,适用于各种规模的 Java 项目开发。

接下来,本文将详细介绍 MyBatis-Plus 的核心概念、功能特性,以及如何在 Spring Boot 项目中进行整合和实战应用,帮助读者快速掌握这一强大的技术组合,提升自己的开发技能。

二、MyBatis-Plus 基础讲解

2.1 是什么

MyBatis-Plus,简称为 MP,是一个在 MyBatis 基础上进行增强的工具 。它并不是对 MyBatis 的替代,而是在保留 MyBatis 所有强大功能和灵活性的基础上,为开发者提供了一系列便捷的功能和特性,旨在简化数据库访问层的开发工作,提高开发效率。

MyBatis-Plus 的设计理念是 "只做增强不做改变",这意味着它不会改变 MyBatis 原有的工作方式和核心逻辑。开发者可以继续使用 MyBatis 的 XML 映射文件、注解等功能,同时享受到 MyBatis-Plus 带来的增强特性,如通用的 CRUD 操作、强大的条件构造器、代码生成器等。这种设计使得 MyBatis-Plus 能够与现有的 MyBatis 项目无缝集成,无需对原有代码进行大规模修改,降低了引入新框架的风险和成本。

2.2 优势

MyBatis-Plus 具有诸多显著优势,使其在 Java 持久层框架中脱颖而出:

  • 无侵入性:正如前面提到的,它只做增强不做改变,引入 MyBatis-Plus 不会对现有工程产生任何负面影响,开发人员可以放心地将其集成到项目中,而不用担心与现有代码产生冲突。
  • 强大的 CRUD 操作:内置了通用的 Mapper 和 Service,通过简单的配置,就能实现单表大部分常见的增(Create)、删(Delete)、改(Update)、查(Read)操作。这大大减少了开发人员编写重复 SQL 语句的工作量,例如在一个用户管理模块中,使用 MyBatis-Plus 可以轻松实现用户信息的插入、删除、修改和查询,而无需编写大量的 SQL 代码。
  • 支持 Lambda 调用:通过 Lambda 表达式,开发人员可以更加方便、直观地编写各类查询条件,避免了因字段名拼写错误而导致的错误。例如,使用 LambdaQueryWrapper 进行查询时,可以这样写:LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getName, "张三").ge(User::getAge, 18);,这种方式不仅简洁明了,而且可读性强。
  • 自动分页功能:内置了分页插件,开发人员无需手动编写分页 SQL 语句,只需简单配置,就能实现分页查询,并且支持多种数据库的分页操作。在实际应用中,比如在展示商品列表时,使用 MyBatis-Plus 的分页功能可以轻松实现商品的分页展示,提高用户体验。
  • 代码生成器:提供了代码生成器,可以快速生成 Mapper、Model、Service、Controller 层代码,减少了大量重复的代码编写工作,提高了开发效率。在项目初始化阶段,使用代码生成器可以快速搭建起基础的代码结构,让开发人员能够更快地投入到业务逻辑的开发中。
  • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种常见数据库,具有很强的通用性,适用于各种不同数据库环境的项目开发。

2.3 核心功能

2.3.1 注解

MyBatis-Plus 提供了一系列注解,方便开发人员进行实体类与数据库表之间的映射以及其他配置:

  • @TableName:用于指定实体类对应的数据库表名。当实体类名与数据库表名不一致时,通过该注解进行映射。例如:
java 复制代码
@TableName("user_table")
public class User {
// 实体类属性
}
  • @TableId:指定表的主键字段,并可设置主键的生成策略。例如:
java 复制代码
@TableId(value = "id", type = IdType.AUTO)
private Long id;

其中,value属性指定数据库中的主键字段名,type属性指定主键的生成策略,如IdType.AUTO表示自动增长,IdType.UUID表示使用 UUID 作为主键等。

  • @TableField:用于指定表中的普通字段(非主键字段),还可以设置字段的填充策略、是否为数据库字段等。例如:
java 复制代码
@TableField("username")
private String userName;

@TableField(fill = FieldFill.INSERT)
private Date createTime;

上述代码中,第一个注解指定userName属性对应数据库中的username字段;第二个注解表示createTime字段在插入数据时会自动填充。

2.3.2 CRUD 操作

MyBatis-Plus 通过内置的通用 Mapper 和通用 Service,实现了单表大部分 CRUD 操作。开发人员只需让 Mapper 接口继承BaseMapper<T>,Service 接口继承IService<T>,Service 实现类继承ServiceImpl<BaseMapper<T>, T>,就可以直接使用这些通用的 CRUD 方法。以下是一些常见的 CRUD 操作示例:

  • 插入操作:使用insert(T entity)方法将实体对象插入数据库。
java 复制代码
User user = new User();
user.setName("李四");
user.setAge(20);
userMapper.insert(user);
  • 删除操作:可以根据主键删除,如deleteById(Serializable id);也可以根据条件删除,如delete(Wrapper<T> wrapper)。

// 根据主键删除

java 复制代码
userMapper.deleteById(1L);

// 根据条件删除
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 18);
userMapper.delete(wrapper);
  • 更新操作:根据主键更新实体对象,使用updateById(T entity)方法;也可以根据条件更新,如update(T entity, Wrapper<T> wrapper)。
java 复制代码
User user = new User();
user.setId(1L);
user.setAge(21);
userMapper.updateById(user);

// 根据条件更新
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 1).set("age", 22);
userMapper.update(null, updateWrapper);
  • 查询操作:根据主键查询,使用selectById(Serializable id);查询单个对象,使用selectOne(Wrapper<T> wrapper);查询列表,使用selectList(Wrapper<T> wrapper)等。
java 复制代码
// 根据主键查询
User user = userMapper.selectById(1L);

// 查询单个对象
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "李四");
User singleUser = userMapper.selectOne(wrapper);

// 查询列表
QueryWrapper<User> listWrapper = new QueryWrapper<>();
listWrapper.gt("age", 18);
List<User> userList = userMapper.selectList(listWrapper);
2.3.3 条件构造器

MyBatis-Plus 的条件构造器是其一大特色功能,它帮助开发人员轻松构建复杂的查询条件。条件构造器主要包括QueryWrapper和LambdaQueryWrapper,LambdaQueryWrapper基于 Lambda 表达式,能有效避免字段名硬编码的问题,提高代码的可读性和维护性。以下是一些使用条件构造器的示例:

  • 基本条件查询:使用eq(等于)、ne(不等于)、gt(大于)、ge(大于等于)、lt(小于)、le(小于等于)等方法构建基本条件。
java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三").ge("age", 18);
List<User> userList = userMapper.selectList(wrapper);

上述代码查询出名字为 "张三" 且年龄大于等于 18 岁的用户列表。

  • 模糊查询:使用like(左右模糊)、likeLeft(左模糊)、likeRight(右模糊)方法进行模糊查询。
java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "张");
List<User> userList = userMapper.selectList(wrapper);

该代码查询出名字中包含 "张" 字的用户列表。

  • 逻辑组合查询:使用and(与)、or(或)方法进行逻辑组合。
java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 18).or().like("name", "李");
List<User> userList = userMapper.selectList(wrapper);

此代码查询出年龄为 18 岁或者名字中包含 "李" 字的用户列表。

三、Spring Boot 项目搭建

3.1 环境准备

在搭建 Spring Boot 项目之前,需要确保开发环境中已安装以下工具和软件:

  • JDK:Java Development Kit,是 Java 开发的基础环境。Spring Boot 要求 JDK 版本为 8 或以上,建议使用较新的版本,如 JDK 11 或 JDK 17,以获得更好的性能和功能支持。可以从 Oracle 官方网站或 OpenJDK 官网下载并安装 JDK,安装完成后,需要配置JAVA_HOME环境变量,将 JDK 的安装路径添加到系统的PATH环境变量中,以便在命令行中能够正确执行java和javac命令。例如,在 Windows 系统中,如果 JDK 安装在C:\Program Files\Java\jdk-11目录下,需要在系统环境变量中添加JAVA_HOME=C:\Program Files\Java\jdk-11,并在PATH变量中添加%JAVA_HOME%\bin。
  • Maven:是一个项目管理和构建工具,用于管理项目的依赖和构建过程。可以从 Maven 官方网站下载 Maven 的压缩包,解压到指定目录后,配置MAVEN_HOME环境变量为 Maven 的解压路径,并将%MAVEN_HOME%\bin添加到系统的PATH环境变量中。通过在命令行中执行mvn -v命令,可以验证 Maven 是否安装成功,如果成功安装,会输出 Maven 的版本信息。
  • 集成开发环境(IDE):推荐使用 IntelliJ IDEA,它是一款功能强大的 Java 开发工具,对 Spring Boot 项目的开发提供了良好的支持,包括代码自动补全、智能提示、项目模板创建等功能。也可以使用 Eclipse 或 Spring Tool Suite(STS)等其他 IDE,根据个人喜好和习惯进行选择。

3.2 创建项目

使用 Spring Initializr 可以快速创建一个 Spring Boot 项目,以下以 IntelliJ IDEA 为例介绍创建步骤:

  1. 打开 IntelliJ IDEA,在欢迎界面点击 "Create New Project"(如果已经打开了项目,可以通过 "File" -> "New" -> "Project" 来创建新项目)。
  1. 在弹出的 "New Project" 对话框中,左侧选择 "Spring Initializr",右侧可以选择使用 Maven 或 Gradle 构建项目,这里选择 Maven。点击 "Next"。
  1. 在 "Project Metadata" 页面,填写项目的基本信息:
    • Group:通常是公司或组织的反向域名,例如com.example。
    • Artifact:项目的名称,例如mybatisplus - springboot - demo。
    • Name:项目在本地的名称,默认与 Artifact 相同,可以自定义。
    • Location:项目在本地磁盘的存储路径,可以点击 "Browse" 选择其他路径。
    • Package name:项目的包名,默认根据 Group 和 Artifact 生成,保持默认即可。
    • Java Version:选择项目使用的 Java 版本,确保与安装的 JDK 版本一致,这里选择合适的版本,如 11。
  1. 点击 "Next" 后,进入 "Dependencies" 页面,在搜索框中搜索并添加项目所需的依赖。这里需要添加 "Spring Web" 依赖,用于创建 Web 应用;添加 "MySQL Driver" 依赖,用于连接 MySQL 数据库;添加 "MyBatis - Plus Boot Starter" 依赖,用于集成 MyBatis - Plus。搜索并勾选这些依赖后,点击 "Finish"。
  1. IDEA 会根据选择的配置和依赖,从 Maven 仓库下载相关的依赖包,并创建项目的基本结构。等待下载完成后,一个 Spring Boot 项目就创建好了。

3.3 添加依赖

在创建好的 Spring Boot 项目中,pom.xml文件用于管理项目的依赖。打开pom.xml文件,可以看到 Spring Initializr 已经自动添加了一些基础依赖,如 Spring Boot 的核心依赖、Spring Web 依赖等。接下来,手动添加 MyBatis - Plus 和 MySQL 驱动的依赖:

java 复制代码
<dependencies>

    <!-- Spring Boot 核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- Spring Web 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis - Plus 依赖 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>最新版本号</version> <!-- 请根据实际情况替换为最新版本 -->
    </dependency>

    <!-- MySQL 驱动依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency

    <!-- Spring Boot 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

添加完依赖后,Maven 会自动下载这些依赖包及其相关的依赖项。在 IDEA 中,可以通过点击右侧的 "Maven" 面板中的 "Reload All Maven Projects" 按钮,来手动触发依赖的下载和更新。如果在下载过程中遇到网络问题,可以检查网络连接,或者更换 Maven 的镜像源,例如使用阿里云的镜像源,以提高下载速度。在pom.xml文件中添加阿里云镜像源的配置如下:

java 复制代码
<settings>
    <mirrors>
        <mirror>
        <id>aliyunmaven</id>
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
        <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
</settings>

通过以上步骤,完成了 Spring Boot 项目的搭建,并添加了 MyBatis - Plus 和 MySQL 驱动的依赖,为后续的开发做好了准备。

四、MyBatis-Plus 与 Spring Boot 整合步骤

4.1 配置数据库连接

在src/main/resources目录下的application.yml文件中配置数据库连接信息。以 MySQL 数据库为例,配置如下:

java 复制代码
spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=Asia/Shanghai
        username: your_username
        password: your_password

其中,driver - class - name指定数据库驱动类;url指定数据库的连接地址,your_database_name需要替换为实际的数据库名,useSSL=false表示不使用 SSL 连接,serverTimezone=Asia/Shanghai设置服务器时区为上海时间;username和password分别为数据库的用户名和密码 。通过这些配置,Spring Boot 能够正确连接到 MySQL 数据库,为后续 MyBatis - Plus 进行数据操作提供基础。

4.2 创建实体类

根据数据库表结构创建对应的实体类,使用 MyBatis-Plus 提供的注解来映射实体类与数据库表及字段之间的关系。例如,假设数据库中有一张user表,表结构如下:

java 复制代码
CREATE TABLE user (

    id BIGINT AUTO_INCREMENT PRIMARY KEY,

    name VARCHAR(50),

    age INT,

    email VARCHAR(100)

);

对应的实体类User可以这样创建:

java 复制代码
package com.example.demo.entity;

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

@Data
@TableName("user")
public class User {

    @TableId

    private Long id;

    private String name;

    private Integer age;

    private String email;

}

在上述代码中,@Data是 Lombok 注解,用于自动生成 Getter、Setter、ToString 等方法,简化代码编写。@TableName("user")指定该实体类对应数据库中的user表。@TableId注解表示该字段是表的主键,这里如果不指定主键生成策略,MyBatis-Plus 会使用默认策略 。通过这些注解,清晰地建立了实体类与数据库表之间的映射关系,方便后续的数据操作。

4.3 创建 Mapper 接口

创建继承自BaseMapper的接口,BaseMapper是 MyBatis-Plus 提供的基础 Mapper 接口,它为我们提供了一系列通用的 CRUD 方法。例如,为User实体类创建 Mapper 接口:

java 复制代码
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> {
    // 可以在此处添加自定义的SQL方法
}

在这个接口中,通过继承BaseMapper<User>,UserMapper接口自动拥有了诸如insert(插入)、deleteById(根据主键删除)、updateById(根据主键更新)、selectById(根据主键查询)、selectList(查询列表)等通用的 CRUD 方法。如果有复杂的查询需求,还可以在该接口中自定义 SQL 方法,并在对应的 XML 文件中实现(如果使用 XML 方式)。@Mapper注解用于将该接口标记为 MyBatis 的 Mapper,让 Spring 能够识别并将其纳入到 Spring 容器的管理中 。

4.4 创建 Service 层

创建服务接口和实现类,通常服务接口继承自IService,服务实现类继承自ServiceImpl。IService是 MyBatis-Plus 提供的服务层接口,定义了一些常用的业务方法,ServiceImpl是IService的基础实现类。

首先创建服务接口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> {
    // 可以在此处添加自定义的业务方法
}

然后创建服务实现类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 {
    // 可以在此处实现自定义的业务方法,如果没有自定义方法,继承ServiceImpl后即可直接使用            IService中的通用方法
}

在服务实现类中,通过继承ServiceImpl<UserMapper, User>,不仅获得了IService接口中定义的通用业务方法,如save(保存)、removeById(根据主键删除)、updateById(根据主键更新)、list(查询列表)等,还可以根据业务需求在该类中实现自定义的业务方法。@Service注解将该类标记为服务层组件,使其被 Spring 容器管理 。

4.5 创建 Controller 层

创建控制器类,用于接收前端请求并调用 Service 层的方法进行业务处理,然后将结果返回给前端。例如,创建UserController:

java 复制代码
package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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("/add")
public boolean addUser(@RequestBody User user) {
    return userService.save(user);
}

// 根据ID删除用户
@DeleteMapping("/delete/{id}")
public boolean deleteUser(@PathVariable Long id) {
    return userService.removeById(id);
}

// 根据ID更新用户
@PutMapping("/update")
public boolean updateUser(@RequestBody User user) {
    return userService.updateById(user);
}

// 根据ID查询用户
@GetMapping("/get/{id}")
public User getUserById(@PathVariable Long id) {
    return userService.getById(id);
}

// 查询所有用户

@GetMapping("/list")
public List<User> listUser() {
    return userService.list();
}

// 分页查询用户
@GetMapping("/page")
public Page<User> pageUser(int current, int size) {
    Page<User> page = new Page<>(current, size);
    return userService.page(page);
}

// 条件查询用户
@GetMapping("/query")
public List<User> queryUser(String name, Integer age) {

    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.like(name != null, "name", name);
    wrapper.eq(age != null, "age", age);
    return userService.list(wrapper);
}

}

在UserController中,通过@Autowired注解注入UserService,然后定义了一系列 RESTful 风格的接口方法来处理不同的用户操作请求。例如,addUser方法用于添加用户,调用userService.save(user)方法将用户信息保存到数据库;deleteUser方法根据用户 ID 删除用户,调用userService.removeById(id)方法;updateUser方法根据用户 ID 更新用户信息,调用userService.updateById(user)方法;getUserById方法根据用户 ID 查询用户信息,调用userService.getById(id)方法;listUser方法查询所有用户信息,调用userService.list()方法;pageUser方法实现分页查询用户信息,创建Page对象并调用userService.page(page)方法;queryUser方法实现条件查询用户信息,使用QueryWrapper构建查询条件并调用userService.list(wrapper)方法 。@RestController注解表示该类是一个 RESTful 风格的控制器,返回的数据会自动转换为 JSON 格式。@RequestMapping("/user")注解定义了该控制器的基础路径,所有方法的路径都是在这个基础路径上进行扩展。

4.6 配置 Mapper 扫描

在 Spring Boot 启动类上添加@MapperScan注解,用于扫描 Mapper 接口所在的包,让 Spring 能够找到并加载这些 Mapper 接口。例如,在启动类MyApplication中添加注解:

java 复制代码
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 MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

@MapperScan("com.example.demo.mapper")指定了 Mapper 接口所在的包路径,Spring 在启动时会扫描该包及其子包下的所有 Mapper 接口,并将它们注册到 Spring 容器中,这样在其他组件中就可以通过依赖注入的方式使用这些 Mapper 接口进行数据库操作 。通过这种方式,简化了 Mapper 接口的注册过程,避免了在每个 Mapper 接口上都添加@Mapper注解,提高了开发效率和代码的简洁性。

五、整合实战案例

5.1 案例背景

为了更直观地展示 MyBatis-Plus 与 Spring Boot 整合的实际应用,我们以一个简单的图书管理系统为例。在这个系统中,主要涉及图书信息的管理,包括图书的添加、删除、修改、查询等操作。用户可以通过系统查询图书的详细信息,管理员则可以对图书信息进行全面的管理,确保系统中图书数据的准确性和完整性。

5.2 数据库设计

在数据库中,我们创建一张book表来存储图书信息,建表语句如下:

java 复制代码
CREATE TABLE book (

    id BIGINT AUTO_INCREMENT PRIMARY KEY,

    title VARCHAR(255) NOT NULL,

    author VARCHAR(100),

    publish_date DATE,

    price DECIMAL(10, 2)

);

在这个表结构中,id是图书的唯一标识,采用自增长的方式生成;title字段存储图书的标题,是必填字段;author字段记录图书的作者;publish_date字段表示图书的出版日期;price字段存储图书的价格,精确到小数点后两位。

5.3 代码实现

  1. 创建实体类:根据数据库表结构创建对应的实体类Book。
java 复制代码
package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;

@Data
@TableName("book")
public class Book {

    @TableId

    private Long id;
    
    private String title;

    private String author;

    private Date publishDate;

    private Double price;

}

在实体类中,使用@Data注解自动生成 Getter、Setter 等方法,@TableName("book")指定该实体类对应数据库中的book表,@TableId注解标识id为主键。

  1. 创建 Mapper 接口:创建继承自BaseMapper的BookMapper接口。
复制代码
java 复制代码
package com.example.demo.mapper;

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

@Mapper
public interface BookMapper extends BaseMapper<Book> {
    // 可添加自定义SQL方法
}

通过继承BaseMapper<Book>,BookMapper接口自动拥有了通用的 CRUD 方法,@Mapper注解将该接口标记为 MyBatis 的 Mapper,以便 Spring 能够识别并管理。

  1. 创建 Service 层:创建服务接口BookService和实现类BookServiceImpl。
java 复制代码
// BookService接口

package com.example.demo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.Book;

public interface BookService extends IService<Book> {
    // 可添加自定义业务方法
}
java 复制代码
// BookServiceImpl实现类
package com.example.demo.service.impl;

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

@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
    // 可实现自定义业务方法
}

BookService接口继承自IService<Book>,定义了一些常用的业务方法,BookServiceImpl实现类继承自ServiceImpl<BookMapper, Book>,并实现了BookService接口。通过这种方式,BookServiceImpl不仅获得了IService接口中的通用业务方法,还可以根据业务需求实现自定义的业务方法。

  1. 创建 Controller 层:创建BookController用于接收前端请求并调用 Service 层方法。
java 复制代码
package com.example.demo.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Book;
import com.example.demo.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/book")
public class BookController {

@Autowired
private BookService bookService;

// 添加图书
@PostMapping("/add")
public boolean addBook(@RequestBody Book book) {
    return bookService.save(book);
}

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

// 根据ID更新图书
@PutMapping("/update")
public boolean updateBook(@RequestBody Book book) {
    return bookService.updateById(book);
}

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

// 查询所有图书
@GetMapping("/list")
public List<Book> listBook() {
    return bookService.list();
}

// 分页查询图书
@GetMapping("/page")
public Page<Book> pageBook(int current, int size) {
    Page<Book> page = new Page<>(current, size);
    return bookService.page(page);
}

 // 条件查询图书
@GetMapping("/query")
public List<Book> queryBook(String title, String author) {
    QueryWrapper<Book> wrapper = new QueryWrapper<>();
    wrapper.like(title != null, "title", title);
    wrapper.like(author != null, "author", author);
    return bookService.list(wrapper);
}

}

在BookController中,通过@Autowired注解注入BookService,并定义了一系列 RESTful 风格的接口方法来处理不同的图书操作请求。例如,addBook方法用于添加图书,调用bookService.save(book)方法;deleteBook方法根据图书 ID 删除图书,调用bookService.removeById(id)方法;updateBook方法根据图书 ID 更新图书信息,调用bookService.updateById(book)方法;getBookById方法根据图书 ID 查询图书信息,调用bookService.getById(id)方法;listBook方法查询所有图书信息,调用bookService.list()方法;pageBook方法实现分页查询图书信息,创建Page对象并调用bookService.page(page)方法;queryBook方法实现条件查询图书信息,使用QueryWrapper构建查询条件并调用bookService.list(wrapper)方法。@RestController注解表示该类是一个 RESTful 风格的控制器,返回的数据会自动转换为 JSON 格式。@RequestMapping("/book")注解定义了该控制器的基础路径,所有方法的路径都是在这个基础路径上进行扩展。

5.4 测试运行

  1. 使用 Postman 测试
    • 添加图书 :发送 POST 请求到http://localhost:8080/book/add,请求体中传入图书信息的 JSON 数据,如{"title":"Java核心技术","author":"Cay S. Horstmann","publishDate":"2023-10-01","price":79.00},如果添加成功,会返回true。
    • 根据 ID 更新图书 :发送 PUT 请求到http://localhost:8080/book/update,请求体中传入更新后的图书信息的 JSON 数据,如{"id":1,"title":"Java核心技术(第12版)","author":"Cay S. Horstmann","publishDate":"2023-10-01","price":89.00},如果更新成功,会返回true。
  1. 使用浏览器测试(对于 GET 请求)

通过以上测试,可以验证 MyBatis-Plus 与 Spring Boot 整合后的图书管理系统功能是否正常实现,确保各个接口能够正确地处理请求并返回预期的结果 。

六、常见问题及解决方法

6.1 依赖冲突

在整合 MyBatis-Plus 与 Spring Boot 的过程中,依赖冲突是较为常见的问题。这通常是由于项目中引入的多个依赖包中,包含了相同库的不同版本,导致在项目运行时,不同依赖对同一库的版本需求产生冲突。依赖冲突可能会引发各种异常,如NoSuchMethodError(方法未找到错误)、ClassNotFoundException(类未找到错误)等,严重影响项目的正常运行 。

当出现依赖冲突时,可以通过以下方法进行排查和解决:

  • 使用 Maven Helper 插件:在 IDEA 中安装 Maven Helper 插件,安装完成后,打开项目的pom.xml文件,切换到 "Dependency Analyzer" 选项卡,该插件会以图形化的方式展示项目的依赖树,并标记出冲突的依赖。通过分析依赖树,可以清晰地看到哪些依赖包存在版本冲突,以及冲突的具体依赖路径 。
  • 在命令行中查看依赖信息:在项目的根目录下执行mvn dependency:tree命令,该命令会在控制台输出项目的依赖树信息,通过分析依赖树,可以找出冲突的依赖。例如,如果输出中显示有多个不同版本的mybatis依赖,就可能存在依赖冲突 。
  • 解决依赖冲突的方法:确定冲突的依赖后,可以通过以下方式解决。如果某个依赖引入的库版本较低,可以尝试升级该依赖到最新版本,看是否能解决冲突;如果是某个依赖引入了不需要的库,可以在该依赖中使用<exclusions>标签排除冲突的库。例如,如果mybatis-plus-boot-starter和mybatis-spring-boot-starter中都引入了mybatis依赖,且版本冲突,可以在mybatis-spring-boot-starter依赖中排除mybatis依赖,如下所示:
java 复制代码
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
    <exclusions>
        <exclusion>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这样,mybatis-spring-boot-starter就不会引入mybatis依赖,从而避免与mybatis-plus-boot-starter中的mybatis依赖产生冲突 。

6.2 配置错误

常见的配置错误包括mapper-locations路径配置错误、type-aliases-package配置错误等。

  • mapper-locations 路径配置错误:如果在application.yml或application.properties文件中配置的mapper-locations路径不正确,MyBatis-Plus 将无法找到 Mapper XML 文件,从而导致Invalid bound statement (not found)错误。例如,在application.yml中配置mapper-locations时,路径格式必须正确,假设 Mapper XML 文件存放在src/main/resources/mapper目录下,配置如下:
java 复制代码
mybatis-plus:
mapper-locations: classpath:/mapper/*.xml

如果写成classpath:mapper/*.xml(缺少/),就可能导致找不到 Mapper XML 文件。

  • type-aliases-package 配置错误:type-aliases-package用于指定实体类的包路径,MyBatis-Plus 会自动扫描该包下的实体类并为其创建别名。如果配置的包路径错误,可能会导致在 Mapper XML 文件中使用实体类别名时找不到对应的类。例如,假设实体类存放在com.example.demo.entity包下,配置如下:
java 复制代码
mybatis-plus:
type-aliases-package: com.example.demo.entity

如果配置成了错误的包路径,如com.example.demo.model,就会出现找不到实体类的问题 。

6.3 SQL 语句打印问题

在开发过程中,有时会遇到 SQL 语句无法打印或打印异常的情况。这可能是由于以下原因导致:

  • 日志配置问题:MyBatis-Plus 依赖于日志框架来打印 SQL 语句,如果日志配置不正确,就无法打印 SQL。例如,使用logback作为日志框架时,需要在logback.xml中配置 MyBatis-Plus 的日志级别为DEBUG,才能打印 SQL 语句。配置如下:
java 复制代码
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <logger name="com.baomidou.mybatisplus" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

如果logger的level配置为INFO或更高,就不会打印 SQL 语句。

  • 配置文件中 SQL 打印开关未开启:在application.yml或application.properties文件中,需要配置 MyBatis-Plus 的configuration.log-impl属性来开启 SQL 打印。例如,使用org.apache.ibatis.logging.stdout.StdOutImpl作为日志实现类,配置如下:
java 复制代码
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

如果没有配置该属性,也无法打印 SQL 语句 。

  • 数据库连接参数问题:有时,数据库连接参数的配置可能会影响 SQL 语句的打印。例如,在数据库连接 URL 中,如果设置了useServerPrepStmts=true(默认值为false),可能会导致 SQL 语句无法正确打印。在这种情况下,可以尝试将useServerPrepStmts设置为false,看是否能解决问题 。例如,在application.yml中配置数据库连接 URL 时:
java 复制代码
spring:
    datasource:
    url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=Asia/Shanghai&useServerPrepStmts=false

七、总结与展望

通过以上步骤,我们成功地将 MyBatis-Plus 与 Spring Boot 进行了整合,并通过图书管理系统的实战案例,展示了如何利用这一技术组合实现高效的数据持久层开发。在整合过程中,我们从项目搭建、依赖添加、配置文件编写,到实体类、Mapper 接口、Service 层和 Controller 层的创建,逐步构建了一个完整的 Web 应用,同时也对整合过程中可能出现的常见问题及解决方法进行了探讨 。

MyBatis-Plus 与 Spring Boot 的整合,为 Java 开发者提供了一种高效、便捷的开发方式。Spring Boot 的自动配置和快速开发特性,与 MyBatis-Plus 强大的 CRUD 操作、灵活的条件构造器以及代码生成器等功能相结合,不仅大大减少了开发过程中的代码量,提高了开发效率,还提升了系统的可维护性和扩展性。在实际项目中,这种整合能够帮助开发团队快速搭建稳定可靠的数据访问层,将更多的时间和精力投入到业务逻辑的实现和优化上 。

展望未来,随着技术的不断发展,MyBatis-Plus 和 Spring Boot 也将持续演进,带来更多强大的功能和更便捷的开发体验。例如,MyBatis-Plus 可能会进一步优化其性能,提供更多智能化的 SQL 生成和优化策略;Spring Boot 也可能会在微服务、云原生等领域提供更好的支持和集成 。对于开发者来说,持续关注这些技术的发展动态,深入学习和掌握它们的新特性,将有助于在开发中充分发挥它们的优势,打造出更优质、高效的应用程序 。

希望本文能帮助读者对 MyBatis-Plus 与 Spring Boot 的整合有更深入的理解和认识,鼓励大家在实际项目中积极应用这一技术组合,不断探索和实践,提升自己的开发技能和项目开发水平。

相关推荐
代码丰几秒前
Zero Code Studio:LangChain4j 工具调用 + LangGraph4j 工作流双模式的 AI 网站生成系统
java·人工智能
云烟成雨TD29 分钟前
Spring AI 1.x 系列【28】基于内存和 MySQL 的多轮对话实现案例
java·人工智能·spring
Lyyaoo.31 分钟前
【JAVA基础面经】String、StringBuffer、StringBuilder
java·开发语言
TeamDev37 分钟前
JxBrowser 8.18.2 版本发布啦!
java·前端·跨平台·桌面应用·web ui·jxbrowser·浏览器控件
晴天sir41 分钟前
Redis 在业务中的几种典型用法
java·数据库·redis
WJX_KOI1 小时前
MemOS —— 为大语言模型 (LLMs) 和智能体打造的记忆操作系统。
java·人工智能·语言模型
_日拱一卒1 小时前
LeetCode:矩阵置零
java·数据结构·线性代数·算法·leetcode·职场和发展·矩阵
weixin_408099671 小时前
【实战教程】懒人精灵如何实现 OCR 文字识别?接口调用完整指南(附可运行示例)
java·前端·人工智能·后端·ocr·api·懒人精灵
珍朱(珠)奶茶1 小时前
Spring Boot3整合Jxls工具包实现模版excel导出文件
spring boot·后端·excel
花千树-0101 小时前
Java Agent 集成 MCP 工具协议:让 AI 真正驱动企业系统
java·ai·langchain·ai agent·mcp·harness·j-langchain