当前位置: 首页 > news >正文

MyBatis-Plus 全方位使用指南:从基础 CRUD 到复杂查询

在 Java 后端开发中,数据库操作是核心环节之一。MyBatis 作为常用的 ORM 框架,虽灵活但需编写大量 XML 配置和 SQL 语句。而 MyBatis-Plus(简称 MP)作为 MyBatis 的增强工具,在保留 MyBatis 特性的基础上,大幅简化开发流程,提升效率。本文将从 MyBatis-Plus 介绍、快速上手、复杂操作等方面,带你全面掌握其使用方法。

一、MyBatis-Plus 简介

MyBatis-Plus 是一款基于 MyBatis 的增强工具,秉持 “只做增强,不做改变” 的理念,旨在简化开发、提高效率,已连续 5 年获得开源中国年度最佳开源项目殊荣,在 Github 上累计拥有 16K Star。

1.1 核心特性

  • 润物无声:引入后不会对现有工程产生影响,集成过程顺滑自然,无需修改原有 MyBatis 相关代码。
  • 效率至上:仅需简单配置,就能快速实现单表 CRUD 操作,省去大量重复编码工作,节省开发时间。
  • 丰富功能:提供代码生成、自动分页、逻辑删除、自动填充、拦截器等实用功能,满足多样化开发需求。
  • 广泛兼容:支持 PostgreSQL、MySQL、MariaDB、Oracle、SQL Server 等多种数据库,只要能通过 MyBatis 进行增删改查且支持标准 SQL 的数据库,基本都能适配。

1.2 官网地址

MyBatis-Plus 官方网站:MyBatis-Plus 🚀 为简化开发而生,官网提供了详细的文档和示例,是学习和使用 MyBatis-Plus 的重要参考。

二、MyBatis-Plus 快速上手

使用 MyBatis-Plus 操作数据库,主要分为准备工作、编码、测试三个步骤,下面将逐步详细介绍。

2.1 准备工作

2.1.1 数据准备

首先创建数据库和用户表,并插入测试数据。这里我们继续使用 MyBatis 学习阶段的数据库表结构,SQL 语句如下:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据库
USE mybatis_test;-- 创建用户表
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;-- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
2.1.2 项目准备
  1. 创建 Spring Boot 工程:可通过 Spring Initializr 快速创建,选择合适的 Spring Boot 版本、Group、Artifact 等信息。
  2. 引入依赖:根据 Spring Boot 版本不同,引入对应的 MyBatis-Plus 和 MySQL 依赖。
    • Spring Boot 2 版本依赖
    <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version>
    </dependency>
    <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
    </dependency>
    

         2. Spring Boot 3 版本依赖:

    <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version>
    </dependency>
    <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
    </dependency>
    
  3. 配置数据库连接信息:可选择 application.yml 或 application.properties 文件进行配置。
    • application.yml 配置:
    # 数据库连接配置
    spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
    

         2. application.properties 配置:

    # 驱动类名称
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    # 数据库连接的url
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    # 连接数据库的用户名
    spring.datasource.username=root
    # 连接数据库的密码
    spring.datasource.password=root
    

2.2 编码

2.2.1 创建实体类

创建与数据库表user_info对应的实体类UserInfo,使用 Lombok 的@Data注解简化 getter、setter 等方法的编写,实体类属性名与表中字段名一一对应:

import lombok.Data;
import java.util.Date;@Data
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
2.2.2 编写 Mapper 接口

MyBatis-Plus 提供了基础的BaseMapper接口,该接口已实现单表的 CRUD 操作。自定义的 Mapper 接口只需继承BaseMapper,并指定泛型为对应的实体类,即可直接使用 CRUD 方法,无需自己编写实现。同时,可在接口上添加@Mapper注解,或在启动类上添加@MapperScan注解扫描 Mapper 文件夹,两种方式二选一。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplusdemo.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

2.3 CRUD 单元测试

在 Spring Boot 工程的 test 目录下,编写单元测试类,注入UserInfoMapper实例,对基本的 CRUD 功能进行测试。

import com.example.mybatisplusdemo.entity.UserInfo;
import com.example.mybatisplusdemo.mapper.UserInfoMapper;
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
class MybatisPlusDemoApplicationTests {@Autowiredprivate UserInfoMapper userInfoMapper;// 新增测试@Testvoid testInsert() {UserInfo user = new UserInfo();user.setUsername("bite");user.setPassword("123456");user.setAge(11);user.setGender(0);user.setPhone("18610001234");userInfoMapper.insert(user);}// 根据ID查询测试@Testvoid testSelectById() {UserInfo user = userInfoMapper.selectById(1);System.out.println("user: " + user);}// 批量查询测试@Testvoid testSelectByIds() {List<UserInfo> users = userInfoMapper.selectBatchIds(List.of(1, 2, 3, 4));users.forEach(System.out::println);}// 根据ID更新测试@Testvoid testUpdateById() {UserInfo user = new UserInfo();user.setId(1);user.setPassword("4444444");userInfoMapper.updateById(user);}// 根据ID删除测试@Testvoid testDelete() {userInfoMapper.deleteById(5);}
}

运行测试方法后,从控制台输出结果可以看到,数据的 CRUD 操作全部执行成功,数据库中的数据也会相应地发生变化。

三、MyBatis-Plus 复杂操作

在实际开发中,除了基础的 CRUD 操作,还会涉及到一些复杂的数据库操作,MyBatis-Plus 也提供了相应的解决方案,如常见注解、条件构造器、自定义 SQL 等。

3.1 常见注解

MyBatis-Plus 默认会根据实体类推断数据库表的信息,默认规则如下:

  1. 表名:实体类的驼峰表示法转换为蛇形表示法(下划线分割),例如UserInfo对应表名user_info
  2. 字段:实体类的属性名转换为蛇形表示法作为字段名,例如deleteFlag对应字段名delete_flag
  3. 主键:默认为id

当实体类和数据库表不遵循上述默认规则时,可通过以下注解进行标识。

3.1.1 @TableName

该注解用于指定实体类对应的数据库表名。例如,若将实体类名UserInfo改为Userinfo,默认情况下 MyBatis-Plus 会查找表名userinfo,而实际数据库表名为user_info,此时就需要使用@TableName注解指定表名:

import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;@Data
@TableName("user_info")
public class Userinfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
3.1.2 @TableField

该注解用于指定实体类属性对应的数据库表字段名。例如,若将实体类属性deleteFlag改为deleteflag,默认情况下 MyBatis-Plus 会查找字段名deleteflag,而实际数据库字段名为delete_flag,此时可使用@TableField注解指定字段名:

import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import java.util.Date;@Data
@TableName("user_info")
public class Userinfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;@TableField("delete_flag")private Integer deleteflag;private Date createTime;private Date updateTime;
}
3.1.3 @TableId

该注解用于指定实体类属性对应的数据库表主键。例如,若将实体类属性id改为userId,默认情况下 MyBatis-Plus 无法识别主键,此时可使用@TableId注解指定主键:

import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date;@Data
@TableName("user_info")
public class Userinfo {@TableId("id")private Integer userId;private String username;private String password;private Integer age;private Integer gender;private String phone;@TableField("delete_flag")private Integer deleteflag;private Date createTime;private Date updateTime;
}

若属性名和字段名一致,直接添加@TableId注解即可。

3.2 打印日志

为了方便调试,查看 MyBatis-Plus 执行的 SQL 语句、参数和执行结果,可在配置文件中配置日志打印。以 application.yml 为例:

mybatis-plus:configuration:# 配置打印 MyBatis 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置完成后,运行测试方法,控制台会输出详细的 SQL 执行日志。

3.3 条件构造器

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件,支持链式调用,无需编写繁琐的 SQL 语句,同时能减少 SQL 注入的风险。主要的 Wrapper 类及其功能如下:

条件构造器类功能描述
AbstractWrapper抽象基类,提供所有 Wrapper 类共有的方法和属性,是其他 Wrapper 类的父类
QueryWrapper用于构造查询条件,在 AbstractWrapper 基础上拓展 select 方法,可指定查询字段
UpdateWrapper用于构造更新条件,可在更新数据时指定条件,也可直接设置更新字段
LambdaQueryWrapper基于 Lambda 表达式的查询条件构造器,通过 Lambda 表达式引用实体类属性,避免硬编码字段名
LambdaUpdateWrapper基于 Lambda 表达式的更新条件构造器,支持 Lambda 表达式指定更新字段和条件,避免硬编码字段名
3.3.1 QueryWrapper

QueryWrapper 不仅可用于查询操作,还可用于修改、删除操作,用于构建相应的条件。

  1. 查询操作:例如查询age = 18username包含 “min” 的用户信息,并只查询idusernamepasswordage字段:
@Test
void testQueryWrapper() {QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>().select("id", "username", "password", "age").eq("age", 18).like("username", "min");List<UserInfo> userInfos = userInfoMapper.selectList(userInfoQueryWrapper);userInfos.forEach(System.out::println);
}

需要注意的是,默认情况下 MyBatis-Plus 会根据@TableField生成别名,当指定 QueryWrapper 的 select 属性后,查询结果可能因字段名不匹配无法正确映射。解决办法有:自定义 SQL、保持实体类名和字段名一致、不指定 select 字段、使用 LambdaQueryWrapper。

    2. 更新操作:例如将age < 20的用户delete_flag设为 1:

@Test
void testUpdateByQueryWrapper() {QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>().lt("age", 20);UserInfo userInfo = new UserInfo();userInfo.setDeleteFlag(1);userInfoMapper.update(userInfo, userInfoQueryWrapper);
}

其中,lt是 “less than” 的缩写,表示 “小于”,类似的还有le(小于等于)、ge(大于等于)、gt(大于)、eq(等于)、ne(不等于)等方法。

    3. 删除操作:例如删除age = 18的用户信息:

@Test
void testDeleteByQueryWrapper() {QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>().eq("age", 18);userInfoMapper.delete(userInfoQueryWrapper);
}
3.3.2 UpdateWrapper

使用 UpdateWrapper 可在不创建实体对象的情况下,直接设置更新字段和条件,更加灵活。

  1. 基础更新:例如将id在 1、2、3 范围内的用户delete_flag设为 0,age设为 5:
@Test
void testUpdateByUpdateWrapper() {UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>().set("delete_flag", 0).set("age", 5).in("id", List.of(1, 2, 3));userInfoMapper.update(null, updateWrapper);
}

      2. 基于 SQL 更新:例如将id在 1、2、3 范围内的用户age增加 10:

@Test
void testUpdateBySQLUpdateWrapper() {UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>().setSql("age = age + 10").in("id", List.of(1, 2, 3));userInfoMapper.update(null, updateWrapper);
}
3.3.3 LambdaQueryWrapper

QueryWrapper 和 UpdateWrapper 存在硬编码字段名的问题,若字段名发生变更,可能因测试不到位引发错误。LambdaQueryWrapper 基于 Lambda 表达式,通过引用实体类属性构建查询条件,避免硬编码字段名,提高代码可读性和可维护性。例如查询userId = 1的用户usernamepasswordage信息:

@Test
void testLambdaQueryWrapper() {LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<UserInfo>().select(UserInfo::getUsername, UserInfo::getPassword, UserInfo::getAge).eq(UserInfo::getUserId, 1);List<UserInfo> userInfos = userInfoMapper.selectList(lambdaQueryWrapper);userInfos.forEach(System.out::println);
}
3.3.4 LambdaUpdateWrapper

LambdaUpdateWrapper 用法与 LambdaQueryWrapper 类似,基于 Lambda 表达式构建更新条件和更新字段,避免硬编码字段名。例如将userId在 1、2、3 范围内的用户delete_flag设为 0,age设为 5:

@Test
void testLambdaUpdateByUpdateWrapper() {LambdaUpdateWrapper<UserInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<UserInfo>().set(UserInfo::getDeleteFlag, 0).set(UserInfo::getAge, 5).in(UserInfo::getUserId, List.of(1, 2, 3));userInfoMapper.update(null, lambdaUpdateWrapper);
}

3.4 自定义 SQL

当 MyBatis-Plus 提供的操作无法满足实际开发需求时,可使用自定义 SQL 功能,结合 Wrapper 构造查询条件,编写符合业务需求的 SQL 语句。需要注意的是,使用该功能要求 MyBatis-Plus 版本不低于 3.0.7。

3.4.1 注解方式自定义 SQL

例如查询username = "admin"的用户idusernamepasswordage信息,通过注解方式实现:

  1. 在 Mapper 接口中定义方法,使用@Select注解编写 SQL 语句,通过${ew.customSqlSegment}引用 Wrapper 生成的 SQL 片段,参数需使用@Param(Constants.WRAPPER)指定为 Wrapper 对象:
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.mybatisplusdemo.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Param;
import java.util.List;@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {@Select("select id, username, password, age FROM user_info ${ew.customSqlSegment}")List<UserInfo> queryUserByCustom(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
}

     2.  编写测试方法

@Test
void testQueryUserByCustom() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().eq("username", "admin");List<UserInfo> userInfos = userInfoMapper.queryUserByCustom(queryWrapper);userInfos.forEach(System.out::println);
}
3.4.2 XML 方式自定义 SQL

MyBatis-Plus 兼容 MyBatis 的 XML 配置方式,也可通过 XML 编写自定义 SQL。例如实现上述相同的查询功能:

  1. 在配置文件中指定 Mapper XML 文件的路径,以 application.yml 为例:
mybatis-plus:mapper-locations: "classpath*:/mapper/**.xml" # Mapper XML文件路径

        2. 在 Mapper 接口中定义方法

    import com.baomidou.mybatisplus.core.conditions.Wrapper;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.baomidou.mybatisplus.core.toolkit.Constants;
    import com.example.mybatisplusdemo.entity.UserInfo;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import java.util.List;@Mapper
    public interface UserInfoMapper extends BaseMapper<UserInfo> {List<UserInfo> queryUserByCustom2(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
    }
    

        3. 在 resources/mapper 目录下创建对应的 XML 文件(如 UserInfoMapper.xml),编写 SQL 语句:

    <?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.example.mybatisplusdemo.mapper.UserInfoMapper"><select id="queryUserByCustom2" resultType="com.example.mybatisplusdemo.entity.UserInfo">select id, username, password, age FROM user_info ${ew.customSqlSegment}</select>
    </mapper>
    

       4. 编写测试方法

    @Test
    void testQueryUserByCustom2() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().eq("username", "admin");List<UserInfo> userInfos = userInfoMapper.queryUserByCustom2(queryWrapper);userInfos.forEach(System.out::println);
    }
    
    3.4.3 自定义更新 SQL

    除了查询操作,自定义 SQL 也可用于更新操作。例如将id在 1、2、3 范围内的用户age增加指定数值:

    1. 在 Mapper 接口中定义方法:
    import com.baomidou.mybatisplus.core.conditions.Wrapper;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.example.mybatisplusdemo.entity.UserInfo;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Update;@Mapper
    public interface UserInfoMapper extends BaseMapper<UserInfo> {@Update("UPDATE user_info SET age = age + #{addAge} ${ew.customSqlSegment}")void updateUserByCustom(@Param("addAge") int addAge, @Param("ew") Wrapper<UserInfo> wrapper);
    }
    

         2. 编写测试方法:

    @Test
    void updateUserByCustom() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().in("id", List.of(1, 2, 3));userInfoMapper.updateUserByCustom(10, queryWrapper);
    }
    

    四、总结

    MyBatis-Plus 作为 MyBatis 的增强工具,极大地简化了数据库操作的开发流程。通过本文的介绍,我们了解到:

    1. MyBatis-Plus 在 MyBatis 基础上只做增强不做改变,能以更少的代码实现数据库表的 CRUD 操作,显著提升开发效率。
    2. 快速上手 MyBatis-Plus 需完成数据准备、项目准备、编码、测试等步骤,其中继承BaseMapper接口是实现基础 CRUD 的关键。
    3. 面对复杂操作,MyBatis-Plus 提供了常见注解(@TableName@TableField@TableId)解决实体类与数据库表的映射问题,通过条件构造器(QueryWrapper、UpdateWrapper、LambdaQueryWrapper、LambdaUpdateWrapper)构建复杂查询条件,还支持自定义 SQL 满足特殊业务需求。

    在实际开发中,合理运用 MyBatis-Plus 的这些功能,能有效减少重复编码,降低开发难度,让开发者更专注于业务逻辑的实现。如果你还未使用过 MyBatis-Plus,不妨在项目中尝试一下,相信它会给你带来意想不到的开发体验!

    http://www.dtcms.com/a/474495.html

    相关文章:

  1. avalonia的hello示例及mvvm实现
  2. 天津网站建设优化如何建网站费用多少
  3. 网站建设泉州效率网络企业网站建设基本原则
  4. 41.Shell Case选择 While循环
  5. 基于单片机的智能水箱温度液位控制系统设计
  6. 数字化转型—AI+制造业的十大应用场景
  7. Java-集合练习
  8. 新民正规网站建设价格咨询广州app开发价格表
  9. 适合用struts2做的网站钦州教育论坛网站建设
  10. 关于节约化建设网站的表态发言企业推广方式力荐隐迅推
  11. 北京备案网站莱芜58同城网
  12. JavaSE面向对象(中)
  13. 保健品网站源代码代理平台什么意思
  14. 做网站签了合同后不想做了办公室装修公司哪里好
  15. 网站建设和网络优化网站建设对网络营销有哪些影响
  16. wordpress导入网站文章西安seo专员
  17. 大学城网站开发公司深圳企业网页设计公司
  18. commons-configuration2(配置管理库)
  19. 处理Git错误:“invalid object [hash]”和“unable to read tree [hash]”
  20. MySQL数据库 常用命令整理
  21. 前端开发 - 实时智能回复
  22. 对电子商务网站建设与维护的总结wordpress多选展示表单
  23. 从零起步学习MySQL || 第二章:DDL语句定义及常见用法示例
  24. Oracle REST Data Services是什么?
  25. [吾爱大神原创工具] windows 多窗口同步软件(键+鼠) 20251011 更新
  26. TDengine 数学函数 COS 用户手册
  27. qfd 网站开发wordpress 上传主题 ftp
  28. 算法与数据结构——排序算法大全
  29. 吕口-反射薄利多销AI入口算法系统方案
  30. Python全方位指南:定义、应用与零基础入门实战