博主

昨天 10:47在线

初音萌 💫 随笔
歌曲封面 未知作品

鄂ICP备2023028426号

MIKU ☁️ MOE © 2025

网站已运行 72 天 6 小时 49 分

Powered by Typecho & Sunny

3 online · 21 ms

Title

使用Mybatis实现数据库操作自动加解密

miku_moe

·

数据

·

Article

本文记录Springboot + Mybatis 架构下实现 Mysql 保存数据自动加密与查询和自动解密
本文代码均为示例代码

方案1:基于注解

基本思路

  1. 定义策略,基于Mybatis的类BaseTypeHandler
  2. 定义字段注解,配置策略
  3. 在需要加解密的实体字段上添加注解即可实现
    说明:简单易用,但使用了反射获取注解可能对性能有一定影响
    注意:此方案不会被加密的参数覆盖原始值,所以加密后访问对象依旧是原始值(数据库正常加密)
♾️ java 代码:
// 以下为策略类核心代码
public class SqlAutoHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 此处实现字段加密
        ps.setString(i, AesUtil.encrypt(parameter));
    }
    @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));
    }
}
♾️ java 代码:
// 配置字段注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@TableField(typeHandler = SqlAutoHandler.class)
public @interface IndexLucene {
}
♾️ java 代码:
// 使用示例
@Data
public class User {
    private Long id;
    @IndexLucene
    private Long phone;
}
// 实体类添加注解后调用xml查询即可实现自动加解密

方案2:基于策略

基本思路

  1. 不使用注解,手动配置实体类加解密属性字段
  2. 借助Mybatis数据持久化前置处理器实现加密MetaObjectHandler
  3. 使用拦截器和@Intercepts注解实现查询解密
    说明:新增对象时需要对应增加实体类加密字段类
    注意:此方案加密会对原始值覆盖后保存或修改,后续调用加密字段值为加密后的值
♾️ java 代码:
@Component
public class BeforeMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 对指定字段进行加密,从请求参数读取操作实体类,再从配置中检查对应实体类需要操作的字段名进行加密处理
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        // 同上
    }
}
♾️ java 代码:
@Component
@Intercepts({@Signature(
    type = Executor.class,
    method = "query",
    args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
), @Signature(
    type = Executor.class,
    method = "query",
    args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
)})
public class SqlInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 此处同时也可实现SQL语句替换,例如自定义函数转换
        
        // SQL执行获取查询结果
        Object object = invocation.proceed();
        if (object instanceof Collection) {
            Collection<?> collection = (Collection)object;
            Iterator<?> iterator = collection.iterator();
            // 通过响应实体类型获取对应实体类需要解密的字段名,此处有多种方式实现,此处忽略
            while(iterator.hasNext()) {
                Object item = iterator.next();
                decrypt(item);
            }
        } else if (object instanceof Serializable) {
            // 同上需要读取策略
            decrypt(object);
        }
        return object;
    }
}
现在已有 52 次阅读,0 条评论,0 人点赞
Author:miku_moe
作者
使用Mybatis实现数据库操作自动加解密
当前文章累计共 3291 字,阅读大概需要 2 分钟。
随机图片接口收集
2025年2月24日 · 0评论
建站记录
2025年2月16日 · 2评论
使用Mybatis实现数据库操作自动加解密
2025年2月27日 · 0评论
Comment:共0条
发表
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主