布景:在大部门的系统中,出于用户的隐私平安考虑,城市对数据库内容停止加密,那么在编写营业代码逻辑时加密也不太现实。于是通用的加解密插件就应运而生,本文将接纳mybatis的拦截器做为根底停止实现。

思绪:我们能够通过mybatis的拦截器停止参数的加密息争密

Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

// 拦截施行办法ParameterHandler (getParameterObject, setParameters)

// 拦截参数处置器ResultSetHandler (handleResultSets, handleOutputParameters)

// 拦截成果集处置器StatementHandler (PRepare, parameterize, batch, update, query)

// 拦截sql构建处置器

两个注解,一个用于实体类(SensitiveData),一个用于实体类的字段(SensitiveField)重写mysql的拦截器Interceptor,对数据停止加密息争密

加密:(拦截参数处置器)@Intercepts({@Signature(tyPE = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)})public Object intercept(Invocation invocation) throws Throwable { //@Signature 指定了 type= parameterHandler 后,那里的 invocation.getTarget() 即是parameterHandler //若指定ResultSetHandler ,那里则能强转为ResultSetHandler ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); log.info("============parameterHandler ==={}", parameterHandler); // 获取参数对像,即 mapper 中 paramsType 的实例 Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject"); log.info("============parameterField ==={}", parameterField); parameterField.setAccessible(true); // 取出实例 Object parameterObject = parameterField.get(parameterHandler); log.info("============parameterObject ==={}", parameterObject); if (!Objects.isNull(parameterObject)) { Class<?> parameterObjectClass = parameterObject.getClass(); log.info("============parameterObjectClass ==={}", parameterObjectClass); //校验该实例的类能否被@SensitiveData所注解 SensitiveData sensitiveData = AnnotationUtil.getAnnotation(parameterObjectClass, SensitiveData.class); log.info("============sensitiveData ==={}", sensitiveData); if (Objects.nonNull(sensitiveData)) { Field[] declaredFields = parameterObjectClass.getDeclaredFields(); aesEncrypt.encrypt(declaredFields, parameterObject); } } log.info("==========proceed==-{}---", invocation.proceed()); return invocation.proceed();}如何使用MyBatis进行数据存储的加密、解密  第1张

解密@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class)})public Object intercept(Invocation invocation) throws Throwable { // 获取成果 Object resultObj = invocation.proceed(); log.info("=====resultObj==={}", resultObj); if (Objects.isNull(resultObj)) { return null; } // 判断能否是list if (resultObj instanceof List) { for (Object resultList : (List) resultObj) { aesUtil.decrypt(resultList); } } else { Class<?> aClass = resultObj.getClass(); SensitiveData annotation = AnnotationUtil.getAnnotation(aClass, SensitiveData.class); if (Objects.nonNull(annotation)) { aesUtil.decrypt(resultObj); } } return resultObj;}如何使用MyBatis进行数据存储的加密、解密  第2张

如何使用MyBatis进行数据存储的加密、解密  第3张

成果:

存储:

如何使用MyBatis进行数据存储的加密、解密  第4张

查询:

如何使用MyBatis进行数据存储的加密、解密  第5张

我是Tz ,想把我碰到的问题都分享给你,想看更多出色内容,请存眷我的微信公家号zhuangtian~~