我是靠谱客的博主 欣喜西装,这篇文章主要介绍mybatis类型转换器如何实现数据加解密,现在分享给大家,希望可以做个参考。

mybatis类型转换器数据加解密

背景需求

对表中的某些字段进行加密,查询之后对字段进行解密,业务代码无需关注加解密环节。

mybatis 拦截器 vs 类型转换器

mybatis的拦截器能实现上面的需求,但是会拦截所有的sql语句,如果项目中只是部分sql涉及到加解密操作,还是比较牺牲大局的。实现起来也比较麻烦,特别是单参数查询的时候,比如参数名称name,此时需要对name进行加密就相对困难。如果是多参数,因为底层会将参数封装成Map,可以根据是否含有指定的key进行加密。

mybatis类型转换器也可以实现上面的需求,方案为修改xml里面的配置,指定类型转换器,并在转换器里面实现数据的加解密。

mybatis 类型转换器

java有java的数据类型,数据库有数据库的数据类型,那么我们在往数据库中插入数据的时候是如何把java类型当做数据库类型插入数据库,在从数据库读取数据的时候又是如何把数据库类型当做java类型来处理呢?这中间必然要经过一个类型转换。

mybatis提供了TypeHandler接口,抽象类BaseTypeHandler实现TypeHandler接口,String,Integer,Long等常见的数据类型转换都是基于继承BaseTypeHandler实现,BaseTypeHandler提供了基本的判空等操作。因此我们可以继承BaseTypeHandler或者实现TypeHandler接口完成自定义类型转换,一般建议继承BaseTypeHandler来编码。

数据加解密类型转换

假设加解密采用AES算法,此处对加解密结果做一下缓存,因为一些数据是一样的,如果每次都去加密,也是会消耗一定的时间

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class DataSecurityHandler extends BaseTypeHandler { public static final LoadingCache<String, String> ENCRYPT_CACHE = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build(new CacheLoader<String, String>() { public String load(String parameterValue) { return AES.encrypt(parameterValue); } }); public static final LoadingCache<String, String> DECRYPT_CACHE = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build(new CacheLoader<String, String>() { public String load(String parameterValue) { return AES.decrypt(parameterValue); } }); @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object parameter, JdbcType jdbcType) throws SQLException { String parameterValue = (String) parameter; String resultValue = ENCRYPT_CACHE.getUnchecked(StringUtils.trimToEmpty(parameterValue)); preparedStatement.setString(i, resultValue); } @Override public Object getNullableResult(ResultSet resultSet, String s) throws SQLException { return DECRYPT_CACHE.getUnchecked(StringUtils.trimToEmpty(resultSet.getString(s))); } @Override public Object getNullableResult(ResultSet resultSet, int i) throws SQLException { return DECRYPT_CACHE.getUnchecked(StringUtils.trimToEmpty(resultSet.getString(i))); } @Override public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return DECRYPT_CACHE.getUnchecked(StringUtils.trimToEmpty(callableStatement.getString(i))); } }

使用方法

针对sql语句,在xml配置文件中,对需要加密的字段加上

复制代码
1
#{name,jdbcType=VARCHAR,typeHandler=com..........DataSecurityHandler},

针对查询结果,在xml配置文件中,在resultMap里面对需要解密的字段加上

复制代码
1
<result column="name" property="name" jdbcType="VARCHAR" typeHandler="com.*..........DataSecurityHandler"/>

mybatis密码解密

mybatis的配置

properties的配置

代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.finance.entity.batctrl; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Properties; import javax.sql.DataSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.codec.binary.Base64; import org.apache.ibatis.datasource.pooled.PooledDataSource; import org.apache.ibatis.io.Resources; import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.TransactionFactory; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class MyBatisSessionFactory { /** * session工厂 */ private final static SqlSessionFactory sqlSessionFactory; /** * 日志类 */ private static Logger logger = LoggerFactory.getLogger(MyBatisSessionFactory.class); static { String resource = "mybatis-configuration.xml"; //Reader reader = null; InputStream inputStream = null; Properties props = new Properties(); try { //reader = Resources.getResourceAsReader(resource); InputStream in = Resources.getResourceAsStream("batch.properties"); props.load(in); String url= props.getProperty("jdbc.url"); String username= props.getProperty("jdbc.username"); String password= props.getProperty("jdbc.password"); logger.debug("befor url -> "+url); logger.debug("befor username -> "+username); logger.debug("befor decode -> "+password); byte[] b = Base64.decodeBase64(password.getBytes()); String decode = new String(b); props.put("url",url); props.put("username",username); props.put("password",decode); logger.debug("after url -> "+url); logger.debug("after username -> "+username); logger.debug("after decode -> "+decode); inputStream = Resources.getResourceAsStream(resource); } catch (IOException e) { } //sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream ,props ); } public static SqlSessionFactory getSessionFactory() { return sqlSessionFactory; } }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持靠谱客。

最后

以上就是欣喜西装最近收集整理的关于mybatis类型转换器如何实现数据加解密的全部内容,更多相关mybatis类型转换器如何实现数据加解密内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(167)

评论列表共有 0 条评论

立即
投稿
返回
顶部