04. Springboot integrates Mybatis-flex (2)

1 Introduction

The previous article "Springboot integrates Mybatis-flex (1)" mentioned the preliminary integration and basic use of Mybatis Flex and Spring Boot. Today we will explore the use of other features of Mybatis Flex.

2. Data filling

Data filling means that when Entity data is inserted or updated, some default data settings will be made for the fields. This is very useful. For example, when an entity is inserted, some data insertion time, data insertion user ID will be set, current tenant information will be set in a multi-tenant scenario, etc.

MyBatis-Flex provides two ways to help developers fill data.

  • Operate through the @Table annotated onInsert and onUpdate configuration. 
  • Operate through the @Column annotated onInsertValue and onUpdateValue configuration. 

2.1. @Table’s onInsert filling

The @Table annotation applied to the entity class provides the onInsert filling attribute, which receives an InsertListener listener.

/**
 * 数据库表信息注解。
 *
 * @author Michael Yang
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Table {

    /**
     * 显式指定表名称。
     */
    String value();

    /**
     * 数据库的 schema(模式)。
     */
    String schema() default "";

    /**
     * 默认为 驼峰属性 转换为 下划线字段。
     */
    boolean camelToUnderline() default true;

    /**
     * 默认使用哪个数据源,若系统找不到该指定的数据源时,默认使用第一个数据源。
     */
    String dataSource() default "";

    /**
     * 监听 entity 的 insert 行为。
     */
    Class<? extends InsertListener>[] onInsert() default {};

    /**
     * 监听 entity 的 update 行为。
     */
    Class<? extends UpdateListener>[] onUpdate() default {};

    /**
     * 监听 entity 的查询数据的 set 行为,用户主动 set 不会触发。
     */
    Class<? extends SetListener>[] onSet() default {};

    /**
     * 在某些场景下,我们需要手动编写 Mapper,可以通过这个注解来关闭 APT 的 Mapper 生成。
     */
    boolean mapperGenerateEnable() default true;

}

2.1.1. Usage examples

Use the previous example code to make adjustments. There is a field extension in the t_user table. We use this field to perform filling tests.

1) Add the @Table annotation to the User entity class and specify OnInsert to fill the listener.

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(value = "t_user", onInsert = UserEntityOnInsertListener.class)
public class User implements Serializable { 
    ...
}

2) Create the listener UserEntityOnInsertListener.

UserEntityOnInsertListener implements the InsertListener interface and implements the onInsert method.

package org.shamee.demo.listener;

import com.mybatisflex.annotation.InsertListener;
import org.shamee.demo.entity.User;

public class UserEntityOnInsertListener implements InsertListener {

    /**
     * 重写该方法,自动填充extension字段
     * @param entity 实体类
     */
    @Override
    public void onInsert(Object entity) {
        User user = (User) entity;
        user.setExtension("我是通过@Table注解的OnInsert监听器填充内容");
    }
}

3) Controller layer method.

/**
 * 新增
 * @return
 */
@GetMapping("insert")
public Boolean insert(){
    User user = User.builder().userId("zhangsan").userName("张三").atk(100).battleNum(200).build();
    userService.insert(user);
    return Boolean.TRUE;
}

4) Check the data filling after running.

It should be noted that during onInsert monitoring, inserting data through the xml mapper of mybatis or inserting data through Db + Row will not trigger the onInsert behavior. Only inserting data through UserMapper will trigger it.

The onUpdate attribute of the @Table annotation is consistent with onInsert, and onUpdate is applied to the update scenario.

2.2. @Column’s onInsertValue filling

The @Column annotation applied to the field provides the onInsertValue attribute, which can set a default value for the field. In insert, the content of onInsertValue configuration will directly participate in SQL splicing instead of setting the Statement parameters of JDBC. Developers need to pay attention to the content of onInsertValue, otherwise SQL errors may occur.

What is the difference between @Table annotation and @Column annotation filling?

The onInsert annotated with @Table is mainly used to set data at the Java application level. 

The onInsertValue annotated with @Column sets data at the database level.

2.2.1. Usage examples

1) Add the @Column annotation to the User entity class extension field.

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

2) Controller layer method.

/**
 * 新增
 * @return
 */
@GetMapping("insert")
public Boolean insert(){
    User user = User.builder().userId("zhangsan").userName("张三").atk(100).battleNum(200).build();
    userService.insert(user);
    return Boolean.TRUE;
}

3) Check the data filling after running.

3. Data desensitization

Data desensitization refers to the deformation of certain sensitive information through desensitization rules to achieve reliable protection of sensitive private data. When customer security data or some commercially sensitive data is involved, the real data must be transformed and provided for use without violating system rules. Personal information such as ID number, mobile phone number, card number, customer number, etc. must be modified. Data desensitization.

Mybatis Flex provides the @ColumnMask() annotation and has the following built-in desensitization rules:

And supports custom rules.

3.1. Usage examples

The userName field of the t_user table is desensitized to Chinese names, using the built-in Chinese name desensitization rules.

/**
 * @Table 注解自动映射实体类和表字段
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(value = "t_user")
public class User implements Serializable {
    ...
    
    @Column(value = "userName")
    @ColumnMask(Masks.CHINESE_NAME)
    private String userName;
    
    ...
}

Through interface query, you can see that the userName field has been desensitized.

4. Multiple data sources

MyBaits-Flex has built-in multi-data source support^1.0.6 with complete functions. It does not require third-party plug-ins or dependencies. It can be used out of the box. It supports any data source including druid, hikaricp, dbcp2, and beecp. Use Mybatis- Flex multiple data source configuration is as follows:

mybatis-flex:
  datasource:
    ds1:
      url: jdbc:mysql://127.0.0.1:3306/db
      username: root
      password: 123456
    ds2:
      url: jdbc:mysql://127.0.0.1:3306/db2
      username: root
      password: 123456

Among them, ds1 and ds2 are user-defined data source names, and are used as follows:

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

But usually we will use Spring Boot's multi-data source configuration method directly.

5. Separation of reading and writing

The read-write separation function of MyBatis-Flex is implemented based on the multi-data source function. The function of separation of reading and writing requires that the current environment must be multiple databases (can also be understood as multiple data sources). The principle is: let the master database (master) handle transactional operations, such as: add, delete, modify (INSERT, DELETE, UPDATE), and query (SELECT) operations are processed from the database (slave).

For example, data source configuration:

mybatis-flex:
  datasource:
    master:
      type: druid
      url: jdbc:mysql://127.0.0.1:3306/master-db
      username: root
      password: 123456
    slave1:
      type: com.your.datasource.type2
      url: jdbc:mysql://127.0.0.1:3306/slave1
      username: root
      password: 123456
    slave2:
      type: com.your.datasource.type2
      url: jdbc:mysql://127.0.0.1:3306/slave2
      username: root
      password: 123456
    other:
      type: com.your.datasource.type2
      url: jdbc:mysql://127.0.0.1:3306/other
      username: root
      password: 123456

In the above configuration, there are a total of 4 data sources, namely master, slave1, slave2, and other. Our requirement is: when adding, deleting or modifying, use the master data source, and when querying, randomly and automatically use the slave1 and slave2 data sources for load balancing.

Then, our sharding strategy code is as follows:

public class MyStrategy implements DataSourceShardingStrategy {

    public String doSharding(String currentDataSourceKey
        , Object mapper, Method mapperMethod, Object[] methodArgs){

        // 不管 other 数据源的情况
        if ("other".equals(currentDataSourceKey)){
            return currentDataSourceKey;
        }

        // 如果 mapper 的方法属于 增删改,使用 master 数据源
        if (StringUtil.startWithAny(mapperMethod.getName(),
            "insert", "delete", "update")){
            return "master";
        }

        //其他场景,使用 slave1 或者 slave2 进行负载均衡
        return "slave*";
    }
}

6. More features

In addition, there are more features such as SQL auditing, SQL printing, data source encryption, dynamic table names and other features. The official website is also very detailed. Many of the articles in this article are excerpted from the official website, just combined with some of my own hands-on demos. , easy for you to understand and master. More features can be found at: Quick Start-MyBatis-Flex official website

Guess you like

Origin blog.csdn.net/p793049488/article/details/133463275