• MybatisPlus 扩展功能 代码生成 逻辑删除 通用枚举 字段类型处理器 配置加密


    MybatisPlus 核心功能 条件构造器 自定义SQL Service接口 静态工具_软工菜鸡的博客-CSDN博客

    3.扩展功能

    3.1.代码生成

    在使用MybatisPlus以后,基础的MapperServicePO代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成POMapperService等相关代码。只不过代码生成器同样要编码使用,也很麻烦。

    这里推荐大家使用一款MybatisPlus的插件,它可以基于图形化界面完成MybatisPlus的代码生成,非常简单。

    3.1.1.安装插件

    Idea的plugins市场中搜索并安装MyBatisPlus插件:

    然后重启你的Idea即可使用。

    3.1.2.使用

    刚好数据库中还有一张address表尚未生成对应的实体和mapper等基础代码。我们利用插件生成一下。

    首先需要配置数据库地址,在Idea顶部菜单中,找到other,选择Config Database

    在弹出的窗口中填写数据库连接的基本信息:

    点击OK保存。

    然后再次点击Idea顶部菜单中的other,然后选择Code Generator:

    在弹出的表单中填写信息:

    最终,代码自动生成到指定的位置了:

    3.2.逻辑删除

    对于一些比较重要的数据,我们往往会采用逻辑删除的方案,即:

    • 在表中添加一个字段标记数据是否被删除
    • 删除数据时把标记置为true
    • 查询时过滤掉标记为true的数据

    一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。为了解决这个问题,MybatisPlus就添加了对逻辑删除的支持。

    注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除

    :::

    例如,我们给address表添加一个逻辑删除字段:

    1. alter table address
    2. add deleted bit default b'0' null comment '逻辑删除';

    然后给Address实体添加deleted字段:

    接下来,我们要在application.yml中配置逻辑删除字段:

    1. mybatis-plus:
    2. global-config:
    3. db-config:
    4. logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
    5. logic-delete-value: 1 # 逻辑已删除值(默认为 1)
    6. logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    测试:

    首先,我们执行一个删除操作:

    1. @Test
    2. void testDeleteByLogic() {
    3. // 删除方法与以前没有区别
    4. addressService.removeById(59L);
    5. }

    方法与普通删除一模一样,但是底层的SQL逻辑变了:

    查询一下试试:

    1. @Test
    2. void testQuery() {
    3. List<Address> list = addressService.list();
    4. list.forEach(System.out::println);
    5. }

    会发现id为59的确实没有查询出来,而且SQL中也对逻辑删除字段做了判断:

    综上, 开启了逻辑删除功能以后,我们就可以像普通删除一样做CRUD,基本不用考虑代码逻辑问题。还是非常方便的。

    注意

    逻辑删除本身也有自己的问题,比如:

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

    因此,不太推荐用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。

    3.3.通用枚举

    User类中有一个用户状态字段:

    像这种字段我们一般会定义一个枚举,做业务判断的时候就可以直接基于枚举做比较。但是我们数据库采用的是int类型,对应的PO也是Integer。因此业务操作时必须手动把枚举Integer转换,非常麻烦。

    因此,MybatisPlus提供了一个处理枚举的类型转换器,可以帮我们枚举类型与数据库类型自动转换

    3.3.1.定义枚举

    我们定义一个用户状态的枚举:

    代码如下:

    1. package com.itheima.mp.enums;
    2. import com.baomidou.mybatisplus.annotation.EnumValue;
    3. import lombok.Getter;
    4. @Getter
    5. public enum UserStatus {
    6. NORMAL(1, "正常"),
    7. FREEZE(2, "冻结")
    8. ;
    9. private final int value;
    10. private final String desc;
    11. UserStatus(int value, String desc) {
    12. this.value = value;
    13. this.desc = desc;
    14. }
    15. }

    然后把User类中的status字段改为UserStatus 类型:

    要让MybatisPlus处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus,枚举中的哪个字段的值作为数据库值

    MybatisPlus提供了@EnumValue注解来标记枚举属性

    3.3.2.配置枚举处理器

    在application.yaml文件中添加配置:

    1. mybatis-plus:
    2. configuration:
    3. default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

    3.3.3.测试

    1. @Test
    2. void testService() {
    3. List<User> list = userService.list();
    4. list.forEach(System.out::println);
    5. }

    最终,查询出的User类的status字段会是枚举类型

    3.4.字段类型处理器

    数据库的user表中有一个info字段,是JSON类型:

    格式像这样:

    {"age": 20, "intro": "佛系青年", "gender": "male"}

    而目前User实体类中却是String类型:

    这样以来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。

    而一旦我们info改为对象类型,就需要在写入数据库(Json类型)时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。

    因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

    选用Jackson的理由:他是JSON处理器最常用的对象

    接下来,我们就来看看这个处理器该如何使用。

    3.4.1.定义实体

    首先,我们定义一个单独实体类来与info字段的属性匹配:

    代码如下:

    1. package com.itheima.mp.domain.po;
    2. import lombok.Data;
    3. @Data
    4. public class UserInfo {
    5. private Integer age;
    6. private String intro;
    7. private String gender;
    8. }

    3.4.2.使用类型处理器

    接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:

    第一次测试info没查出来,是因为对象嵌套没配resultMap,要加autoResultMap

    第二次测试可以发现,所有数据都正确封装到UserInfo当中了:

    3.5.配置加密

    目前我们配置文件中的很多参数都是明文,如果开发人员发生流动,很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。

    我们以数据库的用户名和密码为例。

    3.5.1.生成秘钥

    首先,我们利用AES工具生成一个随机秘钥,然后对用户名、密码加密:

    1. package com.itheima.mp;
    2. import com.baomidou.mybatisplus.core.toolkit.AES;
    3. import org.junit.jupiter.api.Test;
    4. class MpDemoApplicationTests {
    5. @Test
    6. void contextLoads() {
    7. // 生成 16 位随机 AES 密钥
    8. String randomKey = AES.generateRandomKey();
    9. System.out.println("randomKey = " + randomKey);
    10. // 利用密钥对用户名加密
    11. String username = AES.encrypt("root", randomKey);
    12. System.out.println("username = " + username);
    13. // 利用密钥对用户名加密
    14. String password = AES.encrypt("MySQL123", randomKey);
    15. System.out.println("password = " + password);
    16. }
    17. }

    打印结果如下:

    1. randomKey = 6234633a66fb399f
    2. username = px2bAbnUfiY8K/IgsKvscg==
    3. password = FGvCSEaOuga3ulDAsxw68Q==

    3.5.2.修改配置

    修改application.yaml文件,把jdbc的用户名、密码修改为刚刚加密生成的密文

    1. spring:
    2. datasource:
    3. url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    4. driver-class-name: com.mysql.cj.jdbc.Driver
    5. username: mpw:QWWVnk1Oal3258x5rVhaeQ== # 密文要以 mpw:开头
    6. password: mpw:EUFmeH3cNAzdRGdOQcabWg== # 密文要以 mpw:开头

    3.5.3.测试

    在启动项目的时候,需要把刚才生成的秘钥添加到启动参数中,像这样:

    --mpw.key=6234633a66fb399f

    单元测试的时候不能添加启动参数,所以要在测试类的注解上配置

    然后随意运行一个单元测试,可以发现数据库查询正常。

  • 相关阅读:
    c#数组排列系列2
    Docker:运行web应用实例演示
    从 Wepy 到 UniApp 变形记
    【Java后端】美团提前批一面和二面面经!
    亚洲小姐全球总冠军吴丹,《猎枭生死线》荧幕初吻超越柳岩徐冬冬
    Linux SSH命令实战教程,提升你的服务器管理基本功!
    AI大模型安装
    一文读懂Python异常
    小项目中怎么防止Vue的闪现画面效果
    FreeRTOS 任务的创建与删除
  • 原文地址:https://blog.csdn.net/m0_67184231/article/details/132689497