🙉专栏推荐: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)); } }
美图分享
✨🎆谢谢你的阅读和耐心!祝愿你在编程的道路上取得更多的成功与喜悦!"🎆✨🎄
⭐️点赞收藏加关注,学习知识不迷路⭐️
🎉✔️💪🎉✔️💪🎉✔️💪🎉✔️💪🎉
👍😏⛳️点赞☀️收藏⭐️关注😏👍
👍😏⛳️点赞☀️收藏⭐️关注😏👍
👍😏⛳️点赞☀️收藏⭐️关注😏👍
🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️🙆♂️