当前位置: 首页 > news >正文

使用BaseTypeHandler双向转换器进行加密解密

White graces:个人主页

🙉专栏推荐:Java入门知识🙉

🐹今日诗词:日暮酒醒人已远,满天风雨下西楼🐹


⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏

⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏


BaseTypeHandler

  • 作用:数据库类型与 Java 类型间的双向转换器
  • 作用范围:位于 JDBC 驱动层与 DAO 映射层之间
  • 典型场景:String类型转换成varchar类型

这时候就有大聪明询问, JDBC操作数据库不是可以自动映射成相应的类型吗, 为什么还需要

BaseTypeHandler呢?

维度默认映射BaseTypeHandler转换
本质MyBatis内置的自动化类型匹配机制用户可扩展的自定义类型转换基类
触发条件基于Java类型与JDBC类型的预定义匹配规则显式声明绑定特定类型
实现层级框架原生支持(无需编码)需继承BaseTypeHandler并实现核心方法
覆盖范围基础类型(String、Integer、Date等)支持任意复杂类型(JSON、枚举、加密数据等)

很明显BaseTypeHandler有更高的自由度, 我们可以在转换的过程进行一些操作
比如敏感数据先 自动加密在存储, 获取数据的时候又可以 自动解密
传统方法:  需要手动调用加密方法, 加密后再存储, 解密时也需要手动调用解密方法

转换器方法: BaseTypeHandler检测到了要转换的类型       
               在类型转换的过程中自动对数据进行解密和解密, 省去了手动调用的过程

比如现在有三个数据:  姓名(String)  邮箱(String)  手机号(String)

它们都是String类型, 由于手机号比较敏感, 我们需要对手机号先加密再存储

这时候就可以借助BaseTypeHandler双向转换器, 在DAO层进行自动加密解密

步骤一: 

将手机号的String类型向上封装一层, 加密时使用Encrypt类型, 就不会影响其他String类型了

public class Encrypt {

    // 将手机号的String类型向上封装一层, 加密时使用Encrypt类型, 就不会影响其他String类型了
    @Getter
    private final String values;

    public Encrypt(String values) {
        this.values = values;
    }

}

步骤二: 继承BaseTypeHandler, 重写接口, 添加类型映射过程中额外的操作(如捕捉到相应的类型自动进行加密解密)

@MappedTypes(Encrypt.class)            // 转换前的类型
@MappedJdbcTypes(JdbcType.VARCHAR)     // 转换后要存储在数据库的类型
public class EncrptBaseTypeHandler extends BaseTypeHandler<Encrypt> {

    // 设置加密密钥
    private static final byte[] KEY = "12345678abcdefgh".getBytes(StandardCharsets.UTF_8);

    // 设置转换后的值, 将转换后的值映射到数据库中
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null || parameter.getValues() == null) {
            ps.setString(i, null);
            return;
        }
        // 加密
        ps.setBytes(i, SecureUtil.aes(KEY).encrypt(parameter.getValues()));
    }

    // 获取数据的值, 并转换成Java类型, 这个过程可以添加自动解密的步骤
    @Override
    public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return decrpt(rs.getString(columnName));
    }

    // 获取数据的值, 并转换成Java类型
    @Override
    public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return decrpt(rs.getString(columnIndex));
    }

    // 获取数据的值, 并转换成Java类型
    @Override
    public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return decrpt(cs.getString(columnIndex));
    }

    // 解密: 将数据库加密的String类型解密成原本的Encrypt类型, 最后再转换成无加密的String的类型
    private static Encrypt decrpt(String encryptMessage) {
        if (encryptMessage == null) {
            return null;
        }
        return new Encrypt(SecureUtil.aes(KEY).decryptStr(encryptMessage));
    }

}

美图分享

✨🎆谢谢你的阅读和耐心!祝愿你在编程的道路上取得更多的成功与喜悦!"🎆✨🎄

⭐️点赞收藏加关注,学习知识不迷路⭐️

🎉✔️💪🎉✔️💪🎉✔️💪🎉✔️💪🎉

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️

相关文章:

  • Spring中事务的传播行为有哪些?
  • RocketMQ事务消息是如何实现的?
  • DeepSeek赋能智慧文旅:新一代解决方案,重构文旅发展的底层逻辑
  • 【回溯算法2】
  • LangChain 技术入门指南:探索语言模型的无限可能
  • Java集合类归纳+思维导图
  • MicroPython使用ESP32和acs712模块测量电流
  • BFS与Flood Fill:算法原理、实现细节与复杂度分析
  • 在 Spring Boot 中使用 `@Autowired` 和 `@Bean` 注解
  • 一周学会Flask3 Python Web开发-response响应格式
  • 第4章:在LangChain中如何实现响应式流(Response Streaming)
  • 数据结构系列一:初识集合框架+复杂度
  • Py2学习笔记
  • Golang学习笔记_36——装饰器模式
  • 臻识相机,华夏相机,芊熠车牌识别相机加密解密
  • 【C++复习专题】—— 类和对象,包含类的引入、访问限定符、类的6个默认成员函数等
  • 通过例子学 rust 个人精简版 5-all
  • 【C语言】指针(5)
  • 小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统,不需要降级 v1.0.91 (2025)
  • C++ unordered_map和unordered_set的使用,哈希表的实现
  • 网站建设客户在哪里找/百度免费下载安装百度
  • 工业园区管委会网站建设方案/网店推广实训系统
  • 香港股市的做空网站/信息流优化师简历怎么写
  • 什么网站可以做软件有哪些/网络推广策划方案模板
  • 建设政府网站的成本/宁波seo推荐推广平台
  • 做h5页面的网站/新媒体seo指的是什么