MyBatisPlus扩展功能

2024/1/15 MyBatisPlus框架

# 1、逻辑删除

  • application.yml
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
1
2
3
4
5
6
  • 实体类字段使用@TableLogic注解
@TableLogic
private Integer deleted;
1
2
  • insert自动设置逻辑删除字段

  • 字段在数据库定义默认值(推荐)
  • insert 前自己 set 值
  • 使用自动填充功能
  • 删除接口自动填充功能失效

  • 使用 deleteById 方法(推荐)
  • 使用 update 方法并: UpdateWrapper.set(column, value)(推荐)

# 2、通用枚举

  • 单值枚举,可以省略@EnumValue注解,会自动对应上
// 枚举类
public enum SexEnum {
    MALE,
    FEMALE,
    UNKNOWN
}

// 实体类
@Data
@TableName(value = "student")
public class StudentPO {

    @TableId(value = "id",type = IdType.ASSIGN_UUID)
    private Long id;

    private String name;

    private Integer age;

    private String email;

    private SexEnum sex;

    private String version;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  • 键值类枚举

在需要存储数据库的属性上添加@EnumValue注解,在需要前端展示的属性上添加@JsonValue注解。

@AllArgsConstructor
@Getter
public enum SexEnum {

    MAN(1, "男"),
    WOMAN(2, "女");

    @EnumValue
    private Integer key;

    @JsonValue
    private String display;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 3、字段类型处理器

@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
    private Long id;

    ...

    /**
     * 注意!! 必须开启映射注解
     *
     * @TableName(autoResultMap = true)
     *
     * 以下两种类型处理器,二选一 也可以同时存在
     *
     * 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    // @TableField(typeHandler = FastjsonTypeHandler.class)
    private OtherInfo otherInfo;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 4、自动填充功能

描述
DEFAULT 默认不处理
INSERT 插入时填充字段
UPDATE 更新时填充字段
INSERT_UPDATE 插入和更新时填充字段
  • 实体类设置自动填充
public class BasePO {

    // 注意!这里需要标记为填充字段
    @TableField(value="create_time",fill = FieldFill.INSERT)
    private LocalDateTime createTime;

}
1
2
3
4
5
6
7
  • 自定义实现类
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        // 或者
        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
        // 或者
        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 5、SQL注入器

public interface ISqlInjector {

    /**
     * <p>
     * 检查SQL是否注入(已经注入过不再注入)
     * </p>
     *
     * @param builderAssistant mapper 信息
     * @param mapperClass      mapper 接口的 class 对象
     */
    void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass);
}
1
2
3
4
5
6
7
8
9
10
11
12

# 6、执行SQL分析打印

该功能依赖 p6spy 组件,完美的输出打印 SQL 及执行时长 3.1.0 以上版本

springboot 集成方式

  • 引入依赖
<dependency>
    <groupId>com.github.gavlyukovskiy</groupId>
    <artifactId>p6spy-spring-boot-starter</artifactId>
    <version>1.9.0</version>
</dependency>
1
2
3
4
5
  • application.yml配置开启
decorator:
  datasource:
    p6spy:
      # 全部可用参数参照该类:com.p6spy.engine.spy.appender.CustomLineFormat
      log-format: "\ntime:%(executionTime) || sql:%(sql)\n"
      # 自定义日志类的作用仅仅是改变了打印的颜色,如果不需要可以不加
      logging: custom
      custom-appender-class: com.example.testinit.config.StdoutLogger
1
2
3
4
5
6
7
8

# 7、数据安全

  • application.yml
# 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )
spring:
  datasource:
    url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoM
    password: mpw:Hzy5iliJbwDHhjLs1L0j6w==
    username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==
1
2
3
4
5
6
  • 使用
// Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
--mpw.key=d1104d7c3b616f0b
1
2
  • SQL 注入安全保护说明
Wrappers.query()
// 开启自动检查 SQL 注入
.checkSqlInjection().orderByDesc("任意前端传入字段")// 手动校验方式
SqlInjectionUtils.check("任意前端传入字段")
1
2
3
4
5
6

# 8、多数据源

  • 引入依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.6.1</version>
</dependency>
1
2
3
4
5
  • 配置多数据源
spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx) # 内置加密,使用请查看详细文档
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver
       #......省略
       #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 使用 @DS 切换数据源
@Service
@DS("slave")
public class UserServiceImpl implements UserService {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
  
  @Override
  @DS("slave_1")
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17