MybatisPlus

1.Mybatis介绍

在日常开发中应该能发现,单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。

因此,目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是MybatisPlus。

官方网站如下:

当然,MybatisPlus不仅仅可以简化单表操作,而且还对Mybatis的功能有很多的增强。

==Mybatis——-基础使用==

1.1 pom.xml引入依赖

MybatisPlus提供了starter,实现了自动Mybatis以及MybatisPlus的自动装配功能,坐标如下:

image-20240425162339464

如图所示,由于这个starter包含对mybatis的自动装配,因此完全可以替换掉Mybatis的starter

1.2 定义Mapper层

为了简化单表CRUD,MybatisPlus提供了一个基础的BaseMapper接口,其中已经实现了单表的CRUD:

我们直接==实现BaseMapper接口==即可

image-20240425173015132

1.3 对比

我们可以看出这样直接调用简单的CRUD方法即可,就不用自己去mapper层写方法和对应xml文件了。==只需要继承BaseMapper就能省去所有的单表CRUD==。

image-20240425173132151

1.4 底层实现原理

刚才①引入依赖和②mapper层继承BaseMapper接口就可以进行CRUD,那MP怎么知道是哪张表?表中有哪些字段?

这也是因为UserMapper在继承BaseMapper的时候指定了一个泛型和数据库对应的实体类

image-20240425174306575

MybatisPlus就是根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • MybatisPlus会把PO实体的类名驼峰转下划线作为表名
  • MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型
  • MybatisPlus会把名为id的字段作为主键

image-20240425174818635

但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供一些注解便于我们声明表信息

2.常见注解==解决po和mysql字段映射==

==如果不按照约定的话,需要使用以下三种注解来解决:==

MybatisPlus中比较常用的几个注解如下:

@TableName:用来指定表名

@TableId:用来指定表中的主键字段信息

@TableField:用来指定表中的普通字段信息

image-20240425175502493

其中,具体的细节如图所示:==使用查看==

image-20240425175807030

2.1 @TableName

  • 描述:表名注解,标识实体类对应的表
  • 使用位置:实体类

所有属性:

image-20240425180531600

2.2 @TableId

  • 描述:主键注解,标识实体类中的主键字段
  • 使用位置:实体类的主键字段

image-20240425180555143

其中type=IdType.xxxx取值范围:

image-20240425180718677

2.3 @TableField

描述:普通字段注解

image-20240425180842453

3.yml常见配置

在application.yml文件配置:

image-20240425171943982

==Mybatis——-核心功能==

刚才都是以id为条件的简单CRUD,一些复杂的SQL语句就需要用到一些高级功能。

1.条件构造器==提供复杂where语句==

修改、删除、查询的SQL语句都需要指定where条件

因此BaseMapper中提供的相关方法除了以id作为where条件以外,还支持更加复杂的where条件。

image-20240425181511109

参数中的Wrapper就是条件构造的抽象类,其下有很多默认实现,继承关系如图:

image-20240425181331409

其中,Wrapper的子类AbstractWrapper提供了where中包含的所有条件构造方法:

image-20240425181538417

而QueryWrapper在AbstractWrapper的基础上拓展了一个select方法,允许指定查询字段:

image-20240425181553298

而UpdateWrapper在AbstractWrapper的基础上拓展了一个set方法,允许指定SQL中的SET部分:

image-20240425181601512

1.1 QueryWrapper

==主要对where语句的条件进行设置==

对于查询:

1
2
3
select id,username,info,balance
from user
where name like "%o%" AND balance >= 1000

image-20240426152253324

对于修改:

1
2
3
update 
set balance=2000
where username='Jack'

image-20240426152523969

1.2 UpdateWrapper

==弥补BaseMapper中update()只能写 set Xxx==,提出的updatewrapper可以写成set balance=balance-xx这种形式

以更新多个id为例:

1
2
3
update user
set balance=balance-200
where id in(1,2,3)

这个set的赋值结果是基于字段现有值,这时候需要使用UpdateWrapper中的==setSql功能:==

image-20240426153602036

1.3 LambdaQueryWrapper

==1.1和1.2会在构造条件时候写死字段名称==,现在1.3就可以通过变量的getter方法结合反射获取

image-20240426154148926

2.自定义SQL

1.2中演示了一个修改余额-200的时候将sql维护应该放在持久层,而不是业务层:
image-20240426154345876

==利用Wrapper生成查询条件,然后再结合mapper自定义xml文件编写sql==

2.1 原位置变化

以刚才案例为例:

image-20240426154550302

2.2 Mapper层方法定义

image-20240426154750747

2.3 写sql语句

方式一:直接在mapper的方法上写@Select方法

方式二:在mapper.xml文件中写动态sql

和以往的区别就是:==where语句直接用${ew.customSqlSegment}替换==

image-20240426154956395

总结如下

与以往的变化就是我传入参数和where判断条件,mapper方法加一个@Param(“ew”)标志,然后sql里面就直接用${ew.customSqlSegment}替换

3.Service接口

通用接口为==Iservice==,默认实现为==ServiceImpl==。其中封装方法可以分为:

  • save:新增
  • remove:删除
  • update:更新
  • get:查询单个结果
  • list:查询集合结果
  • count:计数
  • page:分页查询

3.1 五大类方法解释

3.1.1 新增(save)

image-20240426155746820

3.1.2 删除(remove)

image-20240426155808475

3.1.3 修改(update)

image-20240426155852795

3.1.4 查询

3.4.1 查询一条(get)

image-20240426155954622

3.4.2 查询多条(list)

image-20240426160001166

3.4.3 计数(count)

image-20240426160025902

3.1.5调用mapper层自定义sql

通过getBaseMapper获取Mapper,然后就mapper.自定义sql()

image-20240426160126219

3.6 基本用法

现在的变化就是,==拿现成的直接用==:

image-20240426160527425

具体操作就是:

image-20240426160603797

1
--保证自定义mapper继承basemapper 【底层使用时候直接还是调用basemapper的方法】

3.7 快速搭建(直接看)

==1.业务简单的话直接调用mp方法;==

==2.业务复杂的话就跟原来方式一样,controller调用service方法,然后在mapper层写具体sql==

3.7.1 简单业务-直接调用mp方法

image-20240426170341983

3.7.2 复杂业务-原始模式优化

image-20240426171113039

之后调用mapper层的sql:

image-20240426170626547

3.8 Lambda查询[添加属性]

就是在基本的方法上(属性,最新值)再多使用一个属性(==判断条件==,属性,最新值)

这样就可以把动态sql里面标签这种麻烦的操作放在serviceImpl类上进行操作

image-20240426175243646

3.9 批量新增

三种方案:

image-20240427230857329

最推荐第三种我们在yml配置文件中添加&rewriteBatchedStatements=true

==Mybatis——-扩展功能==

1.代码生成

在使用MybatisPlus以后,基础的MapperServicePO代码相对固定,重复编写也比较麻烦

==为了方便生成基本固定的代码==

1.1 下载插件

image-20240428181825670

1.2 配置数据库

image-20240428182003520

1.3 配置信息生成代码

image-20240428182342159

1.4查看代码

image-20240428182458664

2.静态工具—-Db

有一种可能就是有AService用来查询用户和BService用来查询地址,他们都实现了Iservice可以实现一些简单的CRUD。现在需要查询用户和对应的地址,就可能AService调用BService,然后BService也要调用AService就会导致@Autowired时候循环依赖

MybatisPlus提供一个静态工具类:==Db==,==就是用来解决多个service层互相调用导致的循环依赖==,其中一些静态方法与IService中的方法签名基本一致,也可以帮助我们实现CRUD的功能

image-20240428183527812

在使用的时候,就可以直接像平时书写习惯直接调用

3.逻辑删除

多表查询时删除A表的数据同时也会删除B数据,但是B里面有一些比较重要的数据我们不想删除。因此,我们采用==逻辑删除==的方案:

可以考虑在表中添加一个字段flag(标记数据是否被删除),这样我们在删除数据的时候还需要将flag设置为true,如果在查询数据的时候还需要添加一个and flag=xxx的条件。这样的话就会让之前的查询和删除逻辑都要跟着变化,非常麻烦。

因此,MybatisPlus就添加了对逻辑删除的支持。

只有MybatisPlus生成的SQL语句才支持自动的逻辑删除【就是直接拿来用的哪些CRUD方法】

自定义SQL就需要自己手动处理逻辑删除

3.1 配置逻辑删除

我们对于Address表添加一个字段deleted用于判断是否删除:

image-20240429170953086

3.2 底层实现

我们在使用MybatisPlus自己的CRUD方法时候支持自动逻辑删除:

image-20240429121132491

具体的两个语法操作:

1.删除的时候我们就会将delete更改为一个update语句拼接一个deleted=false未被删除的判断

image-20240429171532251

2.查询的时候我们就会在where语句拼接一个deleted=false未被删除的判断

image-20240429171544562

3.3 注意事项

开启逻辑删除功能之后,可以像普通删除一样做CRUD,基本不用考虑代码逻辑功能问题。

但是,逻辑删除本身也有缺点:

  • 会导致数据库表垃圾数据越来越多,从而影响查询效率
  • sql中全都需要对逻辑删除字段做判断,影响查询效率

==因此,不太建议采用逻辑删除功能,如果数据不能删除,可以采用数据迁移到其他表的办法==

4.枚举处理器(字段有多个值)

对某个字段(0是正常,1是不正常)判断时候如果写==1这样很不美观,并且如果0和1的含义修改了要修改很多地方,因此我们可以使用枚举(很像c语言的参数宏定义)来处理

针对于之前案例User类的status属性,就可以这样修改:

image-20240429163735826

在原始的mybatis底层帮我们把Java中的类型和数据库的类型一一对应,但是对于枚举类型和Json类型无法解决。因此mybatisplus针对枚举和Json类型提出了新的处理器:

image-20240429164303308

4.1 配置枚举处理器

image-20240429164034948

4.2 定义枚举类

这样就可以将1和2分别代表正常和冻结,我们在使用的时候只需要调用UserStatus.NORMAL就可以对比了

此外,@EnumValue可以保证我们可以按照value的类型和数据库一一对应;而@JsonValue可以保证我们输出给前端的时候可以将描述词/对应值返回(而不是返回NORMAL/FORZEN这种类型)

image-20240429165234689

4.3 修改PO和VO类型

主要是将类型Integer改为UserStatus枚举类

image-20240429165517353

4.4 修改具体逻辑位置

原来位置是用数字比对,可读性太差,现在就可以优雅地使用枚举类

image-20240429165653581

5.Json类型处理器(字段是Json类型)

如果实体类有一个属性是Json类型,那么Java中的Json类型和数据库中的匹配就有问题:
就跟4枚举处理器里面将的,MybatisPlus在Myabtis的基础上提供了Json类型处理器

image-20240429172137951

5.1 配置Json类型处理器

image-20240430142629145

因为没有提供在application.yml配置的方式,只能通过给实体类属性添加注解

image-20240430142453316

5.2 测试查看

info字段已经改成了一个Json类型

image-20240430142717732

6.配置加密

目前我们配置文件中很多参数都是明文存储,如果开发人员跑路很容易导致敏感信息泄露。

MyBatisPlus从3.3.2版本开始提供了一个==基于AES算法的加密工具==,帮助我们对配置中的敏感信息做加密处理。

6.1 生成秘钥

以数据库的账户密码为例:

image-20240430143223630

6.2 配置秘钥

在application.yml文件中修改:

image-20240430143508047

6.3 测试

测试类:在测试类的注解上配置:

image-20240430143859062

启动项目:

image-20240430144043661

==Mybatis——-插件功能==

其实MybatisPlus提供了多个插件,而我们重点关注分页插件

image-20240430164735500

1.分页插件

1.1 配置分页功能

image-20240430152339416

1.2 测试简单分页

image-20240430152253190

1.3 测试复杂分页

针对于1.2的话其实就是更针对业务逻辑:

image-20240430164354320

==Mybatis——-使用操作==

1.可以创建好数据库表

2.根据mybatis插件生成:

​ po(可以添加注解保证数据库和Java实体类对应,对于枚举和Json类型都有新推出的处理器解决),

​ service(extends IService),

​ serviceImpl( extends ServiceImpl<XxxMapper, Xxx> implements IAddressService), [引入mapper方法:①注入xxxMapper ②直接getBaseMapper]

​ controller,

​ mapper(extends BaseMapper)

3.按照原有的设计思路写代码:

​ 3.1 简单的就直接调用service的CRUD方法【service接口默认也有实现类ServiceImpl<XXXMapper,实体类>,这样也说明底层还是直接调用BaseMapper方法】

​ 3.2 复杂的话,①xml文件按照原来的动态sql书写

​ 3.3 复杂的话,②使用xxxMapper.条件构造器[创建复杂where语句]

​ 3.4 复杂的话,③使用lambdaQuery()/lambdaUpdate()添加一些where语句 –新特性【好用】

【只不过在书写过程中有很多好用的扩展功能】

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 1.Mybatis介绍
  2. 2. ==Mybatis——-基础使用==
    1. 2.1. 1.1 pom.xml引入依赖
    2. 2.2. 1.2 定义Mapper层
    3. 2.3. 1.3 对比
    4. 2.4. 1.4 底层实现原理
  3. 3. 2.常见注解==解决po和mysql字段映射==
    1. 3.1. 2.1 @TableName
    2. 3.2. 2.2 @TableId
    3. 3.3. 2.3 @TableField
  4. 4. 3.yml常见配置
  5. 5. ==Mybatis——-核心功能==
  6. 6. 1.条件构造器==提供复杂where语句==
    1. 6.1. 1.1 QueryWrapper
    2. 6.2. 1.2 UpdateWrapper
    3. 6.3. 1.3 LambdaQueryWrapper
  7. 7. 2.自定义SQL
    1. 7.1. 2.1 原位置变化
    2. 7.2. 2.2 Mapper层方法定义
    3. 7.3. 2.3 写sql语句
  8. 8. 3.Service接口
    1. 8.1. 3.1 五大类方法解释
      1. 8.1.1. 3.1.1 新增(save)
      2. 8.1.2. 3.1.2 删除(remove)
      3. 8.1.3. 3.1.3 修改(update)
      4. 8.1.4. 3.1.4 查询
        1. 8.1.4.1. 3.4.1 查询一条(get)
        2. 8.1.4.2. 3.4.2 查询多条(list)
        3. 8.1.4.3. 3.4.3 计数(count)
      5. 8.1.5. 3.1.5调用mapper层自定义sql
    2. 8.2. 3.6 基本用法
    3. 8.3. 3.7 快速搭建(直接看)
      1. 8.3.1. 3.7.1 简单业务-直接调用mp方法
      2. 8.3.2. 3.7.2 复杂业务-原始模式优化
    4. 8.4. 3.8 Lambda查询[添加属性]
    5. 8.5. 3.9 批量新增
  9. 9. ==Mybatis——-扩展功能==
  10. 10. 1.代码生成
    1. 10.1. 1.1 下载插件
    2. 10.2. 1.2 配置数据库
    3. 10.3. 1.3 配置信息生成代码
    4. 10.4. 1.4查看代码
  11. 11. 2.静态工具—-Db
  12. 12. 3.逻辑删除
    1. 12.1. 3.1 配置逻辑删除
    2. 12.2. 3.2 底层实现
    3. 12.3. 3.3 注意事项
  13. 13. 4.枚举处理器(字段有多个值)
    1. 13.1. 4.1 配置枚举处理器
    2. 13.2. 4.2 定义枚举类
    3. 13.3. 4.3 修改PO和VO类型
    4. 13.4. 4.4 修改具体逻辑位置
  14. 14. 5.Json类型处理器(字段是Json类型)
    1. 14.1. 5.1 配置Json类型处理器
    2. 14.2. 5.2 测试查看
  15. 15. 6.配置加密
    1. 15.1. 6.1 生成秘钥
    2. 15.2. 6.2 配置秘钥
    3. 15.3. 6.3 测试
  16. 16. ==Mybatis——-插件功能==
  17. 17. 1.分页插件
    1. 17.1. 1.1 配置分页功能
    2. 17.2. 1.2 测试简单分页
    3. 17.3. 1.3 测试复杂分页
  18. 18. ==Mybatis——-使用操作==
,