项目开发过程中,经常遇到敏感信息加密存储,如身份证号、手机号等,常规操作为存、取数据时对字段值进行单独加、解密处理,不利于维护且扩展性差,今天我们通过继承mybatis-plus(mybatis同样适用)提供的BaseTypeHandler类来统一解决此类问题。
一、导入依赖(基于springboot),加密算法使用hutool包提供的AES,自行导入其他加密包也可。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
二、添加数据库加解密handler,指明加解密字段类型
package com.camp.article.handler;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Description 数据库字段加解密handler
* @Author Huicong She
* @Date 2022/8/5 11:36
*/
//表示该处理器处理的数据类型
@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptHandler extends BaseTypeHandler<String> {
/**
* 线上运行后勿修改,会影响已加密数据解密
*/
private static final byte[] KEYS = "shc987654321camp".getBytes(StandardCharsets.UTF_8);
/**
* 设置参数
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
if (StringUtils.isEmpty(parameter)) {
ps.setString(i, null);
return;
}
AES aes = SecureUtil.aes(KEYS);
String encrypt = aes.encryptHex(parameter);
ps.setString(i, encrypt);
}
/**
* 获取值
*/
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return decrypt(rs.getString(columnName));
}
/**
* 获取值
*/
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return decrypt(rs.getString(columnIndex));
}
/**
* 获取值
*/
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return decrypt(cs.getString(columnIndex));
}
public String decrypt(String value) {
if (null == value) {
return null;
}
return SecureUtil.aes(KEYS).decryptStr(value);
}
}
三、指明自定义类型包处理器路径
#自定义类型处理器包路径
mybatis-plus.type-handlers-package: com.camp.article.handler
四、在需要加密存储的数据库表字段上添加typeHandler,指定使用的处理器
@TableName
@Data
@NoArgsConstructor
public class Article {
@TableId(type=IdType.AUTO)
private Integer id;
@TableField(typeHandler = EncryptHandler.class)
private String name;
private Integer age;
}
五、完成~测试验证(简单验证,直接在controller层调用mapper)
@RestController
@RequestMapping("/article")
public class ArticleController {
@Autowired
private ArticleMapper mapper;
@GetMapping
public List<Article> getArticle(){
return mapper.selectList(null);
}
@PostMapping
public void addArticle(@RequestBody Article article){
mapper.insert(article);
}
}
通过postman调用添加:
数据库数据如下,已成功加密存储:
通过get方法验证查询解密: