自定义一个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 {
@Override
public 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;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public 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 {
@Bean
public 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的插件机制轻松实现数据脱敏功能。