• 04. Springboot集成Mybatis-flex(二)


    1、前言

    上一篇文章《Springboot集成Mybatis-flex(一)》提到Mybatis Flex和Spring Boot的初步集成和基础使用。今天我们再来探索Mybatis Flex其他特性的使用。

    2、数据填充

    数据填充指的是,当 Entity 数据被插入 或者 更新的时候,会为字段进行一些默认的数据设置。这个非常有用,比如当某个 entity 被插入时候 会设置一些数据插入的时间、数据插入的用户 id,多租户的场景下设置当前租户信息等等。

    MyBatis-Flex 提供了两种方式,帮助开发者进行数据填充。

    • 通过 @Table 注解的 onInsert  和 onUpdate配置进行操作。 
    • 通过 @Column  注解的 onInsertValue  和 onUpdateValue配置进行操作。 

    2.1、@Table的onInsert填充

    @Table应用于实体类的注解,提供了onInsert填充属性,而该属性接收一个InsertListener的监听器。

    1. /**
    2. * 数据库表信息注解。
    3. *
    4. * @author Michael Yang
    5. */
    6. @Retention(RetentionPolicy.RUNTIME)
    7. @Target({ElementType.TYPE})
    8. public @interface Table {
    9. /**
    10. * 显式指定表名称。
    11. */
    12. String value();
    13. /**
    14. * 数据库的 schema(模式)。
    15. */
    16. String schema() default "";
    17. /**
    18. * 默认为 驼峰属性 转换为 下划线字段。
    19. */
    20. boolean camelToUnderline() default true;
    21. /**
    22. * 默认使用哪个数据源,若系统找不到该指定的数据源时,默认使用第一个数据源。
    23. */
    24. String dataSource() default "";
    25. /**
    26. * 监听 entity 的 insert 行为。
    27. */
    28. Classextends InsertListener>[] onInsert() default {};
    29. /**
    30. * 监听 entity 的 update 行为。
    31. */
    32. Classextends UpdateListener>[] onUpdate() default {};
    33. /**
    34. * 监听 entity 的查询数据的 set 行为,用户主动 set 不会触发。
    35. */
    36. Classextends SetListener>[] onSet() default {};
    37. /**
    38. * 在某些场景下,我们需要手动编写 Mapper,可以通过这个注解来关闭 APT 的 Mapper 生成。
    39. */
    40. boolean mapperGenerateEnable() default true;
    41. }

    2.1.1、使用示例

    使用前面的示例代码进行调整。t_user表中有字段extension为扩展字段,我们利用该字段进行填充测试。

    1)User实体类添加@Table注解,并指定OnInsert填充监听器。

    1. @Data
    2. @Builder
    3. @NoArgsConstructor
    4. @AllArgsConstructor
    5. @Table(value = "t_user", onInsert = UserEntityOnInsertListener.class)
    6. public class User implements Serializable {
    7. ...
    8. }

    2)创建监听器UserEntityOnInsertListener。

    UserEntityOnInsertListener实现InsertListener接口,并实现onInsert方法。

    1. package org.shamee.demo.listener;
    2. import com.mybatisflex.annotation.InsertListener;
    3. import org.shamee.demo.entity.User;
    4. public class UserEntityOnInsertListener implements InsertListener {
    5. /**
    6. * 重写该方法,自动填充extension字段
    7. * @param entity 实体类
    8. */
    9. @Override
    10. public void onInsert(Object entity) {
    11. User user = (User) entity;
    12. user.setExtension("我是通过@Table注解的OnInsert监听器填充内容");
    13. }
    14. }

    3)controller层方法。

    1. /**
    2. * 新增
    3. * @return
    4. */
    5. @GetMapping("insert")
    6. public Boolean insert(){
    7. User user = User.builder().userId("zhangsan").userName("张三").atk(100).battleNum(200).build();
    8. userService.insert(user);
    9. return Boolean.TRUE;
    10. }

    4)运行后查看数据填充。

    需要注意的是:onInsert 监听中,通过 mybatis 的 xml mapper 插入数据,或者通过 Db + Row 中插入数据,并不会触发 onInsert 行为,只有通过 UserMapper 进行插入数据才会触发。

    @Table注解的onUpdate属性与onInsert一致,onUpdate是应用于更新的场景。

    2.2、@Column的onInsertValue填充

    @Column应用于字段的注解,提供了onInsertValue属性,可以对字段设置默认值。在 insert 中,onInsertValue 配置的内容会直接参与 SQL 拼接,而不是通过 JDBC 的 Statement 参数设置,需要开发者注意 onInsertValue 的内容,否则可能会造成 SQL 错误。

    @Table的注解和@Column注解的填充有什么区别?

    @Table 注解的 onInsert 主要是在 Java 应用层面进行数据设置。 

    @Column 注解的 onInsertValue 则是在数据库层面进行数据设置。

    2.2.1、使用示例

    1)User实体类extension字段添加@Column注解。

    1. @Data
    2. @Builder
    3. @NoArgsConstructor
    4. @AllArgsConstructor
    5. @Table(value = "t_user")
    6. public class User implements Serializable {
    7. /**
    8. * 由于这里会直接拼接成为sql的一部分,因此这里字符串必须添加引号,不然sql执行会出错
    9. */
    10. @Column(onInsertValue = "'我是通过@Column注解的onInsertValue属性填充内容'")
    11. private String extension;
    12. }

    2)controller层方法。

    1. /**
    2. * 新增
    3. * @return
    4. */
    5. @GetMapping("insert")
    6. public Boolean insert(){
    7. User user = User.builder().userId("zhangsan").userName("张三").atk(100).battleNum(200).build();
    8. userService.insert(user);
    9. return Boolean.TRUE;
    10. }

    3)运行后查看数据填充。

    3、数据脱敏

    数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形, 实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供使用, 如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。

    Mybatis Flex提供了 @ColumnMask() 注解,并内置了以下脱敏规则:

    并支持自定义规则。

    3.1、使用示例

    t_user表的userName字段进行中文名脱敏,使用内置的中文名脱敏规则。

    1. /**
    2. * @Table 注解自动映射实体类和表字段
    3. */
    4. @Data
    5. @Builder
    6. @NoArgsConstructor
    7. @AllArgsConstructor
    8. @Table(value = "t_user")
    9. public class User implements Serializable {
    10. ...
    11. @Column(value = "userName")
    12. @ColumnMask(Masks.CHINESE_NAME)
    13. private String userName;
    14. ...
    15. }

    通过接口查询可以看到userName字段已脱敏。

    4、多数据源

    MyBaits-Flex 内置了功能完善的多数据源支持^1.0.6,不需要借助第三方插件或者依赖,开箱即用, 支持包括 druid、hikaricp、dbcp2、beecp 在内的任何数据源,使用Mybatis-Flex多数据源配置如下:

    1. mybatis-flex:
    2. datasource:
    3. ds1:
    4. url: jdbc:mysql://127.0.0.1:3306/db
    5. username: root
    6. password: 123456
    7. ds2:
    8. url: jdbc:mysql://127.0.0.1:3306/db2
    9. username: root
    10. password: 123456

    其中,ds1 和 ds2 是由用户自定义的数据源名称,使用方式如下:

    List rows =  DataSourceKey.use("ds2", () -> Db.selectAll("t_user"));

    但是通常我们会直接使用Spring Boot的多数据源配置方式。

    5、读写分离

    MyBatis-Flex 的读写分离功能是基于多数据源功能来实现的。读写分离的功能,要求当前环境必须是多个数据库(也可理解为多个数据源),其原理是: 让主数据库(master)处理事务性操作,比如:增、删、改(INSERT、DELETE、UPDATE),而从数据库(slave)处理查询(SELECT)操作。

    例如,数据源配置:

    1. mybatis-flex:
    2. datasource:
    3. master:
    4. type: druid
    5. url: jdbc:mysql://127.0.0.1:3306/master-db
    6. username: root
    7. password: 123456
    8. slave1:
    9. type: com.your.datasource.type2
    10. url: jdbc:mysql://127.0.0.1:3306/slave1
    11. username: root
    12. password: 123456
    13. slave2:
    14. type: com.your.datasource.type2
    15. url: jdbc:mysql://127.0.0.1:3306/slave2
    16. username: root
    17. password: 123456
    18. other:
    19. type: com.your.datasource.type2
    20. url: jdbc:mysql://127.0.0.1:3306/other
    21. username: root
    22. password: 123456

    以上配置中,一共有 4 个数据源,分别为 master、slave1、slave2、other。 我们的需求是:在 增删改 时,走 master 数据源,而在查询时,随机自动使用 slave1、slave2 数据源进行负载均衡。

    那么,我们的分片策略代码如下:

    1. public class MyStrategy implements DataSourceShardingStrategy {
    2. public String doSharding(String currentDataSourceKey
    3. , Object mapper, Method mapperMethod, Object[] methodArgs){
    4. // 不管 other 数据源的情况
    5. if ("other".equals(currentDataSourceKey)){
    6. return currentDataSourceKey;
    7. }
    8. // 如果 mapper 的方法属于 增删改,使用 master 数据源
    9. if (StringUtil.startWithAny(mapperMethod.getName(),
    10. "insert", "delete", "update")){
    11. return "master";
    12. }
    13. //其他场景,使用 slave1 或者 slave2 进行负载均衡
    14. return "slave*";
    15. }
    16. }

    6、更多特性

    此外,还有更多的特性如SQL审计,SQL打印,数据源加密,动态表名等特性,官网写的也很详细了,本文中很多也都是摘抄自官网,只是结合一些自己的动手demo,便于自己理解和掌握。更多的特性可见地址:快速开始 - MyBatis-Flex 官方网站

  • 相关阅读:
    Word格式处理控件Aspose.Words for .NET教程——插入段落并调整样式
    (实用)页面在线QQ咨询html代码
    低代码助力生产管理:健康安全环境管理系统
    Hashmap
    高速行驶过程中如何应用目标检测实现提前感知?
    【沐风老师】怎么在3DMAX中使用MAXScript脚本动画编程?
    Hadoop学习总结(搭建Hadoop集群(完全分布式模式))
    Java8实战-总结34
    LVM逻辑卷管理的知识总结和操作说明
    代码随想录算法训练营第三十一天| 455 分发饼干 376 摆动序列 53 最大子数组和
  • 原文地址:https://blog.csdn.net/p793049488/article/details/133463275