MyBatis Plus 项目的创建和使用

1. 快速上手

1.1. 项目的创建和配置

首先,创建一个 Spring Boot 工程,添加 MyBatis Plus 和 MySQL 对应的依赖,然后,和 MyBatis 一样,需要在 yml 文件中配置数据库连接信息

XML 复制代码
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
  <version>3.5.9</version>
</dependency>

创建好项目之后,需要根据数据库中的字段来写相应的实体类

java 复制代码
@Data
public class UserInfo {
    private Integer id;
    private String userName;
    private String password;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

MybatisPlus 提供了一个基础的 BaseMapper 接口,已经实现了单表的增删查改操作,自定义的 Mapper 只需要继承这个 BaseMapper,就不用自己实现相应的单表增删查改操作了

为了让 Spring 扫描到这个类,也是需要加上 @Mapper注解的,或者在启动类上加上@MapperScan注解,参数就写包的路径

java 复制代码
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

1.2. 增删查改的简单演示

之后就可以进行增删查改的单元测试了

查询:

java 复制代码
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    //查询
    @Test
    void testSelect(){
        System.out.println(userInfoMapper.selectById(1));
    }
}

和使用 Mybatis 时的结果是一样的

那么就有一个问题,Mapper 中不写 sql 语句是怎么知道要操作哪张表的,其实就是继承的BaseMapper<UserInfo>中传入的泛型参数,会将 Java 中类的命名规范改为数据库中的命名规范,类中的属性也是按照规范映射到数据库中表的字段的,那么就会有一个问题,如果说类名或者属性名没有按照规范来定义,还能知道操作的是哪张表吗

把类名修改以后就报错了,报错信息为数据库中找不到这个表,如果命名规范的话是可以把UserInfo转化为表名user_info

这时候使用 @TableName来指定一下具体要操作哪张表就可以了

同理,属性名如果命名不规范也是不能自动转化成功的

把规范的驼峰命名方式修改一下就又报错了,这时候,就要使用@TableField注解来指定对应的表的字段

然后来看 insert 方法

java 复制代码
@Test
void testInsert(){
    UserInfo userinfo = new UserInfo();
    userinfo.setUserName("java");
    userinfo.setPassword("java");
    userInfoMapper.insert(userinfo);
}

虽然说插入成功了,但是数据好像不太对,这里的 id 并没有按照自增的方式来增加,而且设置为了一个新的 id,原因就是没有指定数据库中的主键

通过@TableId注解可以设置 id 的一些属性,这里传入参数(type = IdType.AUTO)表示自增

再来看修改和删除操作

java 复制代码
@Test
void testUpdate(){
    UserInfo userinfo = new UserInfo();
    userinfo.setId(3);
    userinfo.setPassword("00000");
    userInfoMapper.updateById(userinfo);
}
java 复制代码
@Test
void testDelete(){
    userInfoMapper.deleteById(3);
}

这里演示的都是通过 id 来进行操作的,这里的 id 必须是对应实体类所映射表的主键

1.3. 日志打印

和 Mybatis 一样,也可以进行配置打印日志,来观察对应的 sql 语句

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

2. 条件构造器

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。

  1. AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。
  2. QueryWrapper :专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 andor 逻辑。
  3. UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。
  4. LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。
  5. LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

2.1. QueryWrapper

java 复制代码
@Test
void testQueryWrapper() {
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.select("user_name", "password")
    .eq("delete_flag", 0)
    .like("user_name", "min");
    userInfoMapper.selectList(queryWrapper).forEach(System.out::println);
}

eq 就构造了一个相等条件,like 构造了一个模糊查询的条件,除此之外还有其他的一些模糊查询的构造

这就相当于下面的这条 sql 语句

部分方法名的表示含义:

|-----|---------------------------------------|
| 方法名 | 表示 |
| lt | "less than"的缩写,表示小于. |
| le | "less than or equal to"的缩写,表示小于等于 |
| ge | "greater than or equal to"的缩写,表示大于等于. |
| gt | "greater than"的缩写,表示大于. |
| eq | "equals"的缩写,表示等于. |
| ne | "not equals"的缩写,表示不等于 |

如果要使用 delete 的话也是可以使用 QueryWrapper 来构造一个判断条件,然后再调用 delete 方法

2.2. UpdateWrapper

来看一下还用 QueryWrapper 来构造条件进行更新:

java 复制代码
@Test
void testQueryWrapper2() {
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.lt("id", 2);
    UserInfo userInfo = new UserInfo();
    userInfo.setDeleteFlag(1);
    userInfoMapper.update(userInfo, queryWrapper);
}

还是先用 QueryWrapper 构造出判断条件,然后和要更新的对象传入 update 方法中,这样就有些麻烦了,来看使用 UpdateWrapper 来进行简化

java 复制代码
@Test
void testUpdateWrapper() {
    UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
    updateWrapper.set("delete_flag", 0)
    .lt("id", 2);
    userInfoMapper.update(updateWrapper);
}

这里直接就可以构造出要更新的内容和判断条件,然后直接传入 update 方法中

再来看批量修改的方式:

java 复制代码
@Test
void testUpdateWrapper1() {
    UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
    updateWrapper.set("delete_flag", 1)
    .in("id", List.of(1, 2, 3));
    userInfoMapper.update(updateWrapper);
}

这里通过 in 方法来构造 sql 语句中的 in

再来看涉及到表达式的 sql 语句怎么构造

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

可以直接通过 setSql 方法来设置 sql 语句

2.3. LambdaQueryWrapper

在上面的示例中,传入的参数都是字符串,也就是硬编码字段名,如果发生修改的话,不方便维护,写起来容易出错,就可以使用 LambdaQueryWrapper 来通过 lambda 表达式的方式来引用类的属性

java 复制代码
@Test
void testLambdaQueryWrapper(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
    .select(UserInfo :: getId,UserInfo :: getUserName,UserInfo :: getPassword)
    .eq(UserInfo::getId ,2);
    System.out.println(userInfoMapper.selectOne(queryWrapper));
}

直接使用就不用调用 lambda 方法了

java 复制代码
@Test
void testLambdaQueryWrapper() {
    LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper
    .select(UserInfo::getId, UserInfo::getUserName, UserInfo::getPassword)
    .eq(UserInfo::getId, 2);
    System.out.println(userInfoMapper.selectOne(lambdaQueryWrapper));
}

通过这样的方式就避免了字符串容易写错的问题

2.4. LambdaUpdateWrapper

与之对应的,还有 LambdaUpdateWrapper,使用方法也是类似的

java 复制代码
@Test
void testLambdaUpdateWrapper(){
    UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
    updateWrapper.lambda()
    .set(UserInfo::getDeleteFlag, 0)
    .in(UserInfo::getId, List.of(1, 2, 3));
    userInfoMapper.update(updateWrapper);
}

也是直接使用,就不用调用 lambda 方法了

java 复制代码
@Test
void testLambdaUpdateWrapper() {
    LambdaUpdateWrapper<UserInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
    lambdaUpdateWrapper
    .set(UserInfo::getDeleteFlag, 1)
    .in(UserInfo::getId, List.of(1, 2, 3));
    userInfoMapper.update(lambdaUpdateWrapper);
}

3. 自定义 sql

Mybatis plus 提供的方法可能不能满足一些其他需求,这是就可以自定义 sql,第一种实现方式还是之前 Mybatis 的写法,直接把 sql 语句写在注解里,或者是使用 XML 的方式

除此之外,Mybatis plus 也提供了另一种构造自定义 sql 的方式,来看官方文档中的介绍

java 复制代码
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    @Select("select * from user_info ${ew.customSqlSegment}")
    List<UserInfo> selectByCustom(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
}

通过 ${ew.customSqlSegment} 引入了 Wrapper 对象生成的 SQL 片段,来实现自定义 sql,然后调用方法,传入一个 Wrapper 对象

XML 方式也是一样的,把注解中的 sql 语句写到 XML 中就可以了

再来看上面 sql 表达式的例子

来自定义一下上面的 sql 语句

复制代码
@Update("update user_info set age = age + #{age} ${ew.customSqlSegment}")
Integer updateByCustom(@Param("age") Integer age,@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
java 复制代码
@Test
void updateByCustom() {
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.in("in",List.of(1,2,3));
    userInfoMapper.updateByCustom(10,queryWrapper);
}

主页

相关推荐
辰哥单片机设计28 分钟前
JW01三合一传感器详解(STM32)
数据库·mongodb
小刘同学++30 分钟前
Qt使用 SQLite 数据库的基本方法
数据库·qt·sqlite
施嘉伟3 小时前
Oracle 11g RAC ASM磁盘组剔盘、加盘实施过程
数据库·oracle
橘猫云计算机设计4 小时前
springboot基于hadoop的酷狗音乐爬虫大数据分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·hadoop·spring boot·爬虫·python·数据分析·毕业设计
卓怡学长5 小时前
w304基于HTML5的民谣网站的设计与实现
java·前端·数据库·spring boot·spring·html5
冰^5 小时前
MySQL VS SQL Server:优缺点全解析
数据库·数据仓库·redis·sql·mysql·json·数据库开发
电商数据girl5 小时前
产品经理对于电商接口的梳理||电商接口文档梳理与接入
大数据·数据库·python·自动化·产品经理
Spring小子6 小时前
黑马点评商户查询缓存--缓存更新策略
java·数据库·redis·后端
溜溜刘@♞7 小时前
数据库之mysql优化
数据库·mysql
uwvwko8 小时前
ctfhow——web入门214~218(时间盲注开始)
前端·数据库·mysql·ctf