MybatisPlus配置自定义TypeHandler查询不生效
问题描述
我们在使用mybatis plus操作数据库的时候,经常会遇到在新增、修改、查询时,对某个字段进行自定义的一些操作,这样就不用在业务代码中写很多重复的逻辑,代码更加简洁。
这次我碰到一个需求,需要将数据库表中的手机号字段的数据进行加密,然后查询的时候进行解密。我直接想到了使用自定义TypeHandler在字段映射的时候进行拦截处理。
问题处理
我的代码是这样的:
▼java复制代码/** * 字段数据加解密类型处理器 */ public class FieldCipherTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String field, JdbcType jdbcType) throws SQLException { ps.setString(i, SM4Util.encryptData_ECB(field)); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String cipherText = rs.getString(columnName); return cipherText == null ? null : SM4Util.decryptData_ECB(cipherText); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String cipherText = rs.getString(columnIndex); return cipherText == null ? null : SM4Util.decryptData_ECB(cipherText); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String cipherText = cs.getString(columnIndex); return cipherText == null ? null : SM4Util.decryptData_ECB(cipherText); } }
▼java复制代码@Data @TableName("t_user") public class User implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.ASSIGN_UUID) private String id; @TableField(typeHandler = FieldCipherTypeHandler.class) private String phone; }
▼java复制代码public User getUserById(String userId){ User data = baseMapper.selectById(userId); } public User updateById(User user){ this.updateById(user); }
然后进行测试,但是我发现,修改的时候能正常将明文手机号转成密文并存储到表中,查询的时候并未进行解密操作,查出来的手机号还是密文。
我配置了自定义类型转换器,但是查询的时候并未走我配置的转换器,在debug跟踪BaseTypeHandler.getResult(ResultSet rs, String columnName)看到还是走的StringTypeHandler ,说明查询的时候这个配置并未生效。
原因分析
selectById默认不解析ResultMap
MyBatis-Plus 的selectById默认使用自动映射(auto-mapping),可能跳过TypeHandler处理。- 缺少
@TableName(autoResultMap = true)
如果实体类没有显式声明autoResultMap,查询时可能不会使用自定义TypeHandler。 TypeHandler未正确绑定到查询结果映射
MyBatis 在查询时需要明确知道哪些字段需要特殊处理。
问题解决
在实体类的**@TableName**注解中加上配置:**autoResultMap = true **配置
▼java复制代码@Data @TableName(value = "t_user",autoResultMap = true) public class User implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.ASSIGN_UUID) private String id; @TableField(typeHandler = FieldCipherTypeHandler.class) private String phone; }
再次测试查询,配置生效,手机号被解密成了明文。
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
