自定义一个MyBaits脱敏插件
用于对查询结果中的敏感数据进行脱敏处理。这个插件将拦截ResultSetHandler
对象的处理结果,对某些敏感字段进行脱敏。
插件实现步骤
- 创建脱敏插件类。
- 注册插件。
1. 创建脱敏插件类
首先,我们创建一个自定义插件类 DataMaskingInterceptor
,它会拦截查询结果并对特定字段进行脱敏处理。
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class DataMaskingInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 执行查询操作Object result = invocation.proceed();if (result instanceof List) {List<?> resultList = (List<?>) result;for (Object obj : resultList) {if (obj instanceof Map) {Map<String, Object> map = (Map<String, Object>) obj;maskSensitiveData(map);} else {// 使用反射对对象进行脱敏处理maskSensitiveData(obj);}}}return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {// 可以读取配置属性}// 脱敏方法private void maskSensitiveData(Map<String, Object> map) {for (String key : map.keySet()) {if (key.equalsIgnoreCase("phoneNumber")) {map.put(key, maskPhoneNumber((String) map.get(key)));} else if (key.equalsIgnoreCase("email")) {map.put(key, maskEmail((String) map.get(key)));}}}private void maskSensitiveData(Object obj) {// 使用反射对对象的敏感字段进行脱敏处理Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {field.setAccessible(true);try {if (field.getName().equalsIgnoreCase("phoneNumber")) {field.set(obj, maskPhoneNumber((String) field.get(obj)));} else if (field.getName().equalsIgnoreCase("email")) {field.set(obj, maskEmail((String) field.get(obj)));}} catch (IllegalAccessException e) {e.printStackTrace();}}}private String maskPhoneNumber(String phoneNumber) {if (phoneNumber != null && phoneNumber.length() >= 7) {return phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7);}return phoneNumber;}private String maskEmail(String email) {if (email != null && email.contains("@")) {int atIndex = email.indexOf("@");return email.substring(0, 2) + "****" + email.substring(atIndex);}return email;}
}
2. 注册插件
将插件注册到MyBatis的配置中。在Spring Boot项目中,可以在配置类中进行注册:
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyBatisConfig {@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);// 注册自定义插件sqlSessionFactoryBean.setPlugins(new Interceptor[]{new DataMaskingInterceptor()});return sqlSessionFactoryBean.getObject();}
}
结果测试
假设有一个User
类:
public class User {private String phoneNumber;private String email;// 其他字段及getter/setter
}
以及对应的Mapper:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface UserMapper extends BaseMapper<User> {
}
当我们执行查询操作时,结果中的phoneNumber
和email
字段将会被脱敏处理:
@Autowired
private UserMapper userMapper;public List<User> getUsers() {return userMapper.selectList(null);
}
查询结果中的phoneNumber
和email
字段将会被插件自动脱敏,如下所示:
phoneNumber
:123****7890
email
:ex****@example.com
通过这种方式,我们可以利用MyBatis的插件机制轻松实现数据脱敏功能。