mybatis拦截器数据库加密敏感字段及审计功能,数据脱敏,逻辑删除等---通用mapper

 

一、数据加密

  1. 涉及注解

    1. EncryptFiled 加密注解

    2. DecryptFiled 解密注解

  2. mapper需要继承 CrudMapper(com.gitee.cashzhang27.test.boot.crypt.mapper.util.CrudMapper)

  3. 仅拦截通用mapper指定方法包括:("insert", "insertSelective","delete", "deleteByPrimaryKey","updateByPrimaryKey", "updateByPrimaryKeySelective","select", "selectOne", "selectByPrimaryKey", "selectByIds", "selectAll")

  4. 使用方式

在实体类字段上加上述两个注解,注意:要有 get set 方法

二、审计功能

  1. 涉及注解

    1. CreateTime

    2. CreateUser

    3. ModifiedTime

    4. ModifiedUser

三、逻辑删除

  1. 涉及注解

    1. LogicDelete

  1. 见上述 2345

四、数据脱敏

  1. 涉及注解

    1. Desensitize

    2. DesensitizeFiled

  2. 使用方式

    在需要脱敏字段加 DesensitizeFiled 注解

    参数枚举

    1. 默认或不填 转为 6个*

    2. FULL_NAME 姓名 保留最后一位

    3. ID_CARD 身份证号 保留前4位和后4位

    4. BANK_CARD 银行卡号 保留前4位和后4位

    5. MOBILE_PHONE 手机号 保留前3位后4位

在Controller方法上加 Desensitize 注解

   @Desensitize(clazz = User.class)
   @GetMapping("/selectByPrimaryKey/{id}")
   public User selectByPrimaryKey(@PathVariable("id") String id) {
     return userMapper.selectByPrimaryKey(id);
   }
 ​
   @Desensitize(clazz = User.class)
   @GetMapping("/selectWrapEntityByPrimaryKey/{id}")
   public ObjectRestResponse selectWrapEntityByPrimaryKey(@PathVariable("id") String id) {
     return ObjectRestResponse.ok(userMapper.selectByPrimaryKey(id));
   }

五、租户与部门隔离

  1. 参数为实体类class 例如

  2. 涉及注解

    1. Tenant

    2. Depart

  3. 使用方式 同上

六、实体类Demo


 import static com.gitee.cashzhang27.test.boot.crypt.mapper.entity.enums.DesensitizeType.BANK_CARD;
 import static com.gitee.cashzhang27.test.boot.crypt.mapper.entity.enums.DesensitizeType.FULL_NAME;
 import static com.gitee.cashzhang27.test.boot.crypt.mapper.entity.enums.DesensitizeType.ID_CARD;
 import static com.gitee.cashzhang27.test.boot.crypt.mapper.entity.enums.DesensitizeType.MOBILE_PHONE;
 ​
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.CreateTime;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.CreateUser;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.DecryptFiled;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.Depart;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.DesensitizeFiled;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.EncryptFiled;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.LogicDelete;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.ModifiedTime;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.ModifiedUser;
 import com.gitee.cashzhang27.test.boot.crypt.mapper.annotation.Tenant;
 import java.io.Serializable;
 import java.time.LocalDateTime;
 import javax.persistence.Column;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 ​
 /**
  * @author Cash Zhang
  * @version v1.0
  * @since 2019/07/09 15:17
  */
 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
 @Table(name = "tb_user")
 public class User implements Serializable {
 ​
   private static final long serialVersionUID = -7491215402569546437L;
 ​
   /**
    * 用户ID
    */
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "select replace(uuid(), '-', '')")
   private String id;
 ​
   /**
    * 昵称
    */
   private String nickName;
   /**
    * 性别
    */
   private String gender;
   /**
    * 姓名
    */
   @DesensitizeFiled(type = FULL_NAME)
   private String fullName;
   /**
    * 身份证号
    */
   @EncryptFiled
   @DecryptFiled
   @DesensitizeFiled(type = ID_CARD)
   private String idCard;
   /**
    * 银行卡号
    */
   @EncryptFiled
   @DecryptFiled
   @DesensitizeFiled(type = BANK_CARD)
   private String bankCard;
   /**
    * 手机号
    */
   @EncryptFiled
   @DecryptFiled
   @DesensitizeFiled(type = MOBILE_PHONE)
   private String mobilePhone;
   /**
    * 部门ID
    */
   @Depart
   private String departId;
   /**
    * 租户ID
    */
   @Tenant
   private String tenantId;
   /**
    * 是否删除
    */
   @LogicDelete
   @Column(name = "is_deleted")
   private Integer deleted;
   /**
    * 创建人
    */
   @CreateUser
   private String userCreate;
   /**
    * 创建时间
    */
   @CreateTime
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   @JsonDeserialize(using = LocalDateTimeDeserializer.class)
   @JsonSerialize(using = LocalDateTimeSerializer.class)
   private LocalDateTime gmtCreate;
   /**
    * 修改人
    */
   @ModifiedUser
   private String userModified;
   /**
    * 修改时间
    */
   @ModifiedTime
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   @JsonDeserialize(using = LocalDateTimeDeserializer.class)
   @JsonSerialize(using = LocalDateTimeSerializer.class)
   private LocalDateTime gmtModified;
 ​
 }
 ​

七、测试用例及源码

https://gitee.com/cashzhang27/test-java/tree/master/test-boot/test-boot-crypt

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis 是一款开源的 ORM 框架,它提供了插件机制,也允许我们自定义插件,在插入、更新、删除、查询等操作过程中拦截执行 SQL 的过程。如果需要拦截指定的表,可以通过使用 Mybatis 提供的 InterceptorChain 拦截链和 Interceptor 拦截器接口来实现。 首先,我们需要创建一个实现了 Interceptor 接口的拦截器类,在该类中通过对拦截的 SQL 语句进行解析,判断是否是针对指定的表进行的操作。如果是,再进行相应的逻辑处理。 ``` java public class CustomInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 获取当前执行的 SQL 语句 MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameter = null; if(invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } BoundSql boundSql = mappedStatement.getBoundSql(parameter); String sql = boundSql.getSql(); // 判断 SQL 语句是否是针对指定的表进行的操作 if(sql.contains("table_name")) { // 进行相应的逻辑处理 ... } // 继续执行后续的拦截器或者目标方法 Object result = invocation.proceed(); return result; } } ``` 其次,我们需要在 Mybatis 的配置文件中设置拦截器链,并配置拦截器处理的范围。通过在 environments 标签下的 interceptor 标签中添加我们自定义的拦截器类,即可将其添加到拦截器链中,使其生效。 ``` xml <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="org.sqlite.JDBC" /> <property name="url" value="jdbc:sqlite://test.db" /> </dataSource> <!-- 添加自定义拦截器 --> <interceptors> <interceptor class="com.example.CustomInterceptor" /> </interceptors> </environment> </environments> ``` 通过以上步骤,就可以实现拦截指定的表的操作,并在拦截器中进行相应的逻辑处理,从而实现特定场景下的定制化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值