首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Mybatis-Plus】快速入门 && 常见注解 && 条件构造器 && 自定义sql

【Mybatis-Plus】快速入门 && 常见注解 && 条件构造器 && 自定义sql

原创
作者头像
lirendada
发布2026-07-01 10:53:35
发布2026-07-01 10:53:35
240
举报
文章被收录于专栏:JavaJava

快速上手

一、引入依赖 && 配置

SpringBoot2

代码语言:javascript
复制
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.7</version>
</dependency>

SpringBoot3

代码语言:javascript
复制
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.5</version>
</dependency>

MySQL

代码语言:javascript
复制
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

配置数据库,application.yml 文件:

代码语言:javascript
复制
# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

二、编码

创建实体类 UserInfo:

实体类的属性名与表中的字段名一一对应

代码语言:javascript
复制
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;
}

编写 Mapper 接口类:

MybatisPlus 提供了一个基础的 BaseMapper 接口,已经实现了单表的 CRUD我们自定义的 Mapper只需要继承这个 BaseMapper,就无需自己实现单表 CRUD了,如下所示:

代码语言:javascript
复制
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

也可以在启动类上添加 @MapperScan,扫描 Mapper 文件夹,二选一即可。

复杂操作

一、常见注解

在上面的程序中,MyBatis 是如何知道,我们要操作的是哪张表,表里有哪些字段呢?

我们来看下咱们 Mapper 的代码:

代码语言:javascript
复制
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

UserInfoMapper 在继承 BaseMapper 时,指定了一个泛型,这个 UserInfo 就是与数据库表相对应的实体类。

MyBatis-Plus 会根据这个实体类来推断表的信息。

默认情况下:

  1. 表名:实体类的驼峰表示法 -> 蛇形表示法作为表名。比如 UserInfo -> user_info
  2. 字段:实体类的属性名 -> 蛇形表示法作为字段名。比如 deleteFlag -> delete_flag
  3. 主键:默认为 id

那如果实体类和数据库不是按照上述规则定义的呢?MyBatis-Plus 也给我们提供了一下注解,让我们标识表的信息。

1. @TableName

通过 @TableName 来标识实体类对应的表:

代码语言:javascript
复制
@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;
}

2. @TableField

通过 @TableField 来标识对应的字段名:

代码语言:javascript
复制
@Data
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. @TableId

通过 @TableId 来指定对应的主键:

代码语言:javascript
复制
@Data
public class Userinfo {
    @TableId("id", type = IdType.AUTO)
    private Integer userId;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteflag;
    private Date createTime;
    private Date updateTime;
}
  1. 如果属性名和字段名一致,直接加 @TableId 注解就可以
  2. 如果属性名和字段名不一致,需要在 @TableId 指明对应的字段名

常见的 IdType 类型如下所示:

  1. AUTO
    1. 数据库自增 ID(通常配合 MySQLAUTO_INCREMENT)。
    2. 由数据库生成,插入时不需要自己赋值。
  2. NONE(默认值)
    1. 不设置主键类型,MyBatis-Plus 不会自动处理,走数据库自身策略。
  3. INPUT
    1. 主键由你自己传入(手动 set)。
  4. ASSIGN_ID
    1. MyBatis-Plus 内置的全局唯一 ID 生成器(类似雪花算法),适合分布式系统。
    2. 插入前自动生成。
  5. ASSIGN_UUID
    1. 自动生成一个 UUID 字符串作为主键。

二、打印日志

在配置文件中添加如下内容:

代码语言:javascript
复制
mybatis-plus:
  configuration:  # 配置打印 MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三、条件构造器

条件构造器

MyBatis-Plus 提供了一套强大的条件构造器 Wrapper,用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

以下是主要的 Wrapper 类及其功能:

  • AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。
  • QueryWrapper:用于构造查询条件,在 AbstractWrapper 的基础上拓展了一个select方法,允许指定查询字段。
  • UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。
  • LambdaQueryWrapper:基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。
  • LambdaUpdateWrapper:基于 Lambda 表达式的更新条件构造器,它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

1. QueryWrapper

查询

完成下述SQL查询:

代码语言:javascript
复制
SELECT id,username,password,age FROM user_info WHERE age = 18 AND username LIKE "%min%"

测试代码:

代码语言:javascript
复制
@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 会根据 @TableFiled 生成别名,当指定了 QueryWrapperselect 属性后就仅仅是属性值而没有了别名。查询出来的结果会对应不上。

更新

完成下述SQL查询:

代码语言:javascript
复制
UPDATE user_info SET delete_flag=? WHERE age < 20

测试代码:

代码语言:javascript
复制
@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:"less than or equal to" 的缩写,表示小于等于
  • ge:"greater than or equal to" 的缩写,表示大于等于
  • gt:"greater than" 的缩写,表示大于
  • eq:"equals" 的缩写,表示等于
  • ne:"not equals" 的缩写,表示不等于

删除

完成下述SQL查询:

代码语言:javascript
复制
DELETE FROM user_info WHERE age = 18

测试代码:

代码语言:javascript
复制
@Test
void testDeleteByQueryWrapper(){
    QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>()
        .eq("age",18);
    userInfoMapper.delete(userInfoQueryWrapper);
}

2. UpdateWrapper

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

完成下述SQL查询:

代码语言:javascript
复制
UPDATE user_info SET delete_flag=0, age=5 WHERE id IN (1,2,3)

测试代码:

代码语言:javascript
复制
@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(updateWrapper);
}

完成下述SQL查询:

代码语言:javascript
复制
UPDATE user_info SET age = age+10 WHERE id IN (1,2,3)

测试代码:

代码语言:javascript
复制
@Test
void testUpdateBySQLUpdateWrapper(){
    UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>()
        .setSql("age = age+10")
        .in("id", List.of(1,2,3));
    userInfoMapper.update(updateWrapper);
}

3. LambdaQueryWrapper

QueryWrapperUpdateWrapper 存在一个问题,就是需要写死字段名,如果字段名发生变更,可能会因为测试不到位酿成事故。

MyBatis-Plus 给我们提供了一种基于 Lambda 表达式的条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名,也提高了代码的可读性和可维护性。

接下来我们看下具体使用:

代码语言:javascript
复制
@Test
void testLambdaQueryWrapper(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
    queryWrapper.lambda()
        .select(UserInfo::getUsername, UserInfo::getPassword,UserInfo::getAge)
        .eq(UserInfo::getUserId, 1);
    userInfoMapper.selectList(queryWrapper).forEach(System.out::println);
}

4. LambdaUpdateWrapper

代码语言:javascript
复制
@Test
void testLambdUpdateByUpdateWrapper(){
    UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>();
    updateWrapper.lambda()
        .set(UserInfo::getDeleteFlag, 0)
        .set(UserInfo::getAge, 5)
        .in(UserInfo::getUserId, List.of(1,2,3));
    userInfoMapper.update(updateWrapper);
}

四、自定义SQL

在实际的开发中,MyBatis-Plus 提供的操作可能不能满足我们的实际需求,MyBatis-Plus 也提供了自定义 SQL 的功能,我们可以利用 Wrapper 构造查询条件,再结合 Mapper 编写 SQL

📌 为了使用这一功能,mybatis-plus 版本不低于 3.0.7

代码示例1

完成下述SQL查询:

代码语言:javascript
复制
select id,username,password,age FROM user_info WHERE username = "admin"

Mapper:

代码语言:javascript
复制
@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);
}

测试代码:

代码语言:javascript
复制
@Test
void testQueryUserByCustom(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
        .eq("username","admin");
    userInfoMapper.queryUserByCustom(queryWrapper).forEach(System.out::println);
}

💥注意事项:

  • 参数命名:在自定义 SQL 传递 Wrapper 对象作为参数时,参数名必须为 ew,或者使用注解@Param(Constants.WRAPPER) 明确指定参数为 Wrapper 对象
  • 在SQL语句中,使用 ${ew.customSqlSegment} 来引用 Wrapper 对象生成的 SQL 片段。
  • 不支持基于 entity 的 where 语句:自定义 SQL 时,Wrapper 对象不会基于实体类自动生成 where 子句,你需要手动编写完整的 SQL 语句。

代码示例2

MyBatis-Plus 在 MyBatis 的基础上只做增强不做改变,所以也支持XML的实现方式。

上述功能也可以使用XML的方式完成:

  1. 配置mapper路径
    代码语言:javascript
    复制
    mybatis-plus:
      mapper-locations: "classpath*:/mapper/**.xml"  # Mapper.xml

2. 定义方法

代码语言:javascript
复制
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    List<UserInfo> queryUserByCustom2(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
}

3. 编写XML

代码语言:javascript
复制
<?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.bite.mybatis.plus.mapper.UserInfoMapper">
    <select id="queryUserByCustom2">
        select id,username,password,age FROM user_info ${ew.customSqlSegment}
    </select>
</mapper>

4. 测试

代码语言:javascript
复制
@Test
void testQueryUserByCustom2(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
        .eq("username","admin");
    userInfoMapper.queryUserByCustom2(queryWrapper).forEach(System.out::println);
}

代码示例3

完成下述 SQL 查询:

代码语言:javascript
复制
UPDATE user_info SET age = age+10 WHERE id IN (1,2,3)

Mapper:

代码语言:javascript
复制
@Update("UPDATE user_info SET age = age+ #{addAge} ${ew.customSqlSegment}")
void updateUserByCustom(@Param("addAge") int addAge, @Param("ew") Wrapper<UserInfo> wrapper);

测试代码:

代码语言:javascript
复制
@Test
void updateUserByCustom(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
        .in("id",List.of(1,2,3));
    userInfoMapper.updateUserByCustom(10, queryWrapper);

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 快速上手
    • 一、引入依赖 && 配置
    • 二、编码
  • 复杂操作
    • 一、常见注解
      • 1. @TableName
      • 2. @TableField
      • 3. @TableId
    • 二、打印日志
    • 三、条件构造器
      • 1. QueryWrapper
      • 2. UpdateWrapper
      • 3. LambdaQueryWrapper
      • 4. LambdaUpdateWrapper
    • 四、自定义SQL
      • 代码示例1
      • 代码示例2
      • 代码示例3
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档