使用Hibernate实现字段加密解密

解决方法

在实体类的属性中添加以下两个注解:

	@Column(columnDefinition= "varchar(2)", name="chou" )
	@ColumnTransformer( forColumn = "chou",read = "DECODE(chou, '1234')", write = "ENCODE(?, '1234')" )
   public String getChou() {
		return chou;
	}

@Column:来标识实体类中属性与数据表中字段的对应关系,@Column可以标注在属性前或getter方法前,因为我搜的资料都加在get方法所以我也放这里了,其实都可以的
columnDefinition:指定属性在数据库的存储类型,这里设置了字段对应的varchar(2)
name:定义了被标注字段在数据库表中所对应字段的名称,这里使用了chou这个属性
@ColumnTransformer:转换列值,通过实现数据库和实体的内容通过自定的规则转换,如数据库kg->实体g,加密解密
forColumn:指定生效的属性,这里是使用了了chou这个属性
read:读数据的规则,这里直接写了用于加密的DECODE函数,是可行的
write:写数据的规则,注意一定要有个问号用来表示被替换的值,这里的==?==就代表我要加密的数据,“1234”是密钥,可更换为别的

注意事项

  1. 写入时不能通过update的方式存储,这样还是原来的值,我用entitymanager.persist()方法就可以实现写入加密
  2. 取出没发现有什么限制,但是不管怎么取目标属性都是通过ENCODE解密后的结果
  3. 加密除了ENCODE的方法还可以参考meijm0103的文章

顺带一提

加上@Column后出现了遇到了错误

java.sql.SQLException: Value ‘0000-00-00 00:00:00’ can not be represented as java.sql.Timestamp

原因是数据库中的值为空,但是查询得到的数据自动转为了‘0000-00-00 00:00:00’这样的格式,所以在数据库连接的后面加上zeroDateTimeBehavior=convertToNull即可,如果你有不止一个参数,在参数之间加上&即可,是;的转义字符

jdbc:mysql://www.xxttblog.com:3306/xttblog?zeroDateTimeBehavior=convertToNull

参考资料

官方文档
meijm0103的文章Hibernate对字段进行加密,运行时解密
segmentfault里的提问Spring-data-jpa中用@ColumnTransformer注解加密,可是解密后返回的数据为null
kevin_zhuzj的文章java.sql.SQLException: Value ‘0000-00-00 00:00:00’ can not be represented as java.sql.Timestamp

碎碎念

  1. 项目经理要求将一个字段插入时加密,取出时解密
  2. 但是系统已经按照不加密的方式设计好了,所有关于这个字段的操作都是直接取出
  3. 难道要单独写一个SQL用来加密解密吗?那样就要在所有字段保存取出时再添加一个方法,而涉及的地方实在是太多了所以这个方法先作为下下之选
  4. 还有一个类似的方法是在代码中加密完成再存入数据库,取出时再在代码中解密,两者的区别只是在于加密解密由数据库完成或人工完成,同样的麻烦
  5. 最后想到Hibernate能否在进行持久化的时候自动加密解密,最终经过多次尝试终于成功
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值