前言
当我们写项目的时候,要对隐私数据进行加密和解密操作,可以不用每次都手动去写加密解密的代码,可以用Mybatis的TypeHandler来解决。
TypeHandler
具体意思就是,当我们处理某些特定字段时,可以在这个类里面实现一些方法,让Mybatis遇到这些特定字段可以自动运行处理。(不过使用之前要在application.properties文件里面加一个配置:mybatis.type-handlers-package=org.example.cqqtest.dao.handler)也就是你自己类型处理器路径
java">@MappedTypes(Encrypt.class)//指定该类型处理器处理的Java类
@MappedJdbcTypes(value = {JdbcType.VARCHAR})//指定该类型处理器处理的JDBC类型为VARCHAR
public class EncryptTypeHandler extends BaseTypeHandler<Encrypt> {
private static final byte[] keys = "1234567890abcdef".getBytes();
/**
*
* @param ps 预编译语句
* @param i 索引
* @param parameter 要加密的数据
* @param jdbcType 数据类型
* @throws SQLException
*/
//加密
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
if(parameter == null|| parameter.getValue() == null){
ps.setString(i, null);
return;
}
AES aes = SecureUtil.aes(keys);;
ps.setString(i, aes.encryptHex(parameter.getValue()));
}
//解密
@Override
public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
System.out.println("获取值得到的加密数据"+rs.getString(columnName));
return decrypt(rs.getString(columnName));
}
@Override
public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
System.out.println("获取值得到的加密数据"+rs.getString(columnIndex));
return decrypt(rs.getString(columnIndex));
}
@Override
public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
System.out.println("获取值得到的加密数据"+cs.getString(columnIndex));
return decrypt(cs.getString(columnIndex));
}
private Encrypt decrypt(String value){
if(!StringUtils.hasText(value)){
return null;
}
return new Encrypt(SecureUtil.aes(keys).decryptStr(value));
}
}
Encrypt
在@MappedTypes(Encrypt.class)这个注解中,括号里面的就是指定处理器要处理的Java类,当有的属性是Encrypt类型的时候,就会自动加密解密。
java">@Data
public class Encrypt {
private String value;
public Encrypt(String value) {
this.value = value;
}
}
加密
以插入数据为例,手机号是要加密的数据,代码就可以这样写。
java">@Data
public class FindUserDo {
private int id;
private String password;
private Encrypt phone;
private String sex;
}
java">
public AddUserDto addUser(AddUserParam user) {
AddUserDo adduserDo = new AddUserDo();
adduserDo.setName(user.getName());
adduserDo.setPassword(DigestUtil.sha256Hex(user.getPassword()));
adduserDo.setPhone(new Encrypt(user.getPhone()));
adduserDo.setSex(user.getSex());
userMapper.insertUser(adduserDo);
AddUserDto addUserDto = new AddUserDto();
addUserDto.setId(adduserDo.getId());
return addUserDto;
}
解密
java"> public FindUserDto getUser(int id) {
FindUserDo findUserDo = userMapper.selectUser(id);
FindUserDto findUserDto = new FindUserDto();
findUserDto.setId(findUserDo.getId());
//解密手机号
findUserDto.setPhone(findUserDo.getPhone().getValue());
findUserDto.setName(findUserDo.getName());
findUserDto.setSex(findUserDo.getSex());
return findUserDto;
}
效果展示
最后,我们可以用postman来进行测试,看看效果