mybatis类型转换器如何实现数据加解密

目录
  • mybatis类型转换器数据加解密
    • 背景需求
    • mybatis 类型转换器
    • 数据加解密类型转换
    • 使用方法
  • mybatis密码解密
    • mybatis的配置
    • properties的配置

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算法,此处对加解密结果做一下缓存,因为一些数据是一样的,如果每次都去加密,也是会消耗一定的时间

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配置文件中,对需要加密的字段加上

#{name,jdbcType=VARCHAR,typeHandler=com..........DataSecurityHandler},

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

<result column="name" property="name" jdbcType="VARCHAR" typeHandler="com.*..........DataSecurityHandler"/>

mybatis密码解密

mybatis的配置

properties的配置

代码:


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;
	}
}

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

(0)

相关推荐

  • Mybatis自定义类型转换器的使用技巧

    一般情况下,mybatis自带的类型转换器已经足够用了,但是需求永无止境,自定义类型转换器还是学一下吧,指不定哪天会用上. 举个没啥用的示例 javabean如下: public class User { private Integer id; private Message message; } public class Message { private Integer id; private String address; private String job; } 数据库User表如下:

  • Mybatis实现自定义类型转换器TypeHandler的方法

    先给大家简单介绍下mybatis MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 此文其实是java操作Oracle类型XMLType总结二:使用Mybatis附带的一篇小结. Mybatis实现自定义的转换器,

  • Mybatis的TypeHandler加解密数据实现

    一.背景 在我们数据库中有些时候会保存一些用户的敏感信息,比如: 手机号.银行卡等信息,如果这些信息以明文的方式保存,那么是不安全的.假如: 黑客黑进了数据库,或者离职人员导出了数据,那么就可能导致这些敏感数据的泄漏.因此我们就需要找到一种方法来解决这个问题. 二.解决方案 由于我们系统中使用了Mybatis作为数据库持久层,因此决定使用Mybatis的TypeHandler或Plugin来解决. TypeHandler : 需要我们在某些列上手动指定 typeHandler 来选择使用那个ty

  • MyBatis自定义类型转换器实现加解密

    需求场景:当数据库中保存的部分数据需要加密,页面需要正常显示时.这是就需要我们自定义类型转换器,在Mybatis执行SQL得到结果时,通过自定义类型转换器将CHAR或者VARCHAR2进行加解密处理,Java代码如下: /**自定义typeHandler<br/> * 1 插入数据库, 加密 * 2 查询,解密 * @author Administrator * */ public class CryptTypeHandler implements TypeHandler<CryptTy

  • mybatis类型转换器如何实现数据加解密

    目录 mybatis类型转换器数据加解密 背景需求 mybatis 类型转换器 数据加解密类型转换 使用方法 mybatis密码解密 mybatis的配置 properties的配置 mybatis类型转换器数据加解密 背景需求 对表中的某些字段进行加密,查询之后对字段进行解密,业务代码无需关注加解密环节. mybatis 拦截器 vs 类型转换器 mybatis的拦截器能实现上面的需求,但是会拦截所有的sql语句,如果项目中只是部分sql涉及到加解密操作,还是比较牺牲大局的.实现起来也比较麻烦

  • Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍

    Java中使用OpenSSL生成的RSA公私钥进行数据加解密 RSA是什么:RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准.目前该加密方式广泛用于网上银行.数字签名等场合.RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困

  • T-SQL问题解决集锦 数据加解密全集

    以下代码已经在SQLServer2008上的示例数据库测试通过 问题一:如何为数据进行加密与解密,避免使用者窃取机密数据? 对于一些敏感数据,如密码.卡号,一般不能使用正常数值来存储.否则会有安全隐患.以往的加密解密都有前端应用程序来辅助完成.而数据库一般只能加密不能解密. 从2005开始提供了数据库层面的数据加密与解密.其实现方式主要有以下: 1. 利用CONVERT改变编码方式: 利用该函数把文字或数据转换成VARBINARY.但该方式不具备保护数据的能力,仅避免浏览数据的过程中能直接看到敏

  • SpringBoot接口数据加解密实战记录

    这日,刚撸完2行代码,正准备掏出手机摸鱼放松放松,只见老大朝我走过来,并露出一个”善意“的微笑,兴伟呀,xx项目有于安全问题,需要对接口整体进行加密处理,你这方面比较有经验,就给你安排上了哈,看这周内提测行不...,额,摸摸头上飘摇着而稀疏的长发,感觉我爱了. 和产品.前端同学对外需求后,梳理了相关技术方案, 主要的需求点如下: 尽量少改动,不影响之前的业务逻辑: 考虑到时间紧迫性,可采用对称性加密方式,服务需要对接安卓.IOS.H5三端,另外考虑到H5端存储密钥安全性相对来说会低一些,故分针对

  • Android Rsa数据加解密的介绍与使用示例

    Rsa加密 RSA是目前最有影响力的公钥加密算法,RSA也是第一个既能用于数据加密也能用于数字签名的算法.该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥.公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用. RSA算法原理 1.随机选择两个大质数p和q,p不等于q,计算N=pq: 2.选择一个大于1小于N的自然数e,e必须与(p-1)(q-1)互素. 3.用公式计算出d:

  • postman数据加解密实现APP登入接口模拟请求

    目录 主要使用到的Postman功能 数据加解密 各种参数设置 真正发送的数据: 请求处理脚本[Pro-request Script] 响应处理脚本[Tests] 结果的样子 主要使用到的Postman功能 环境变量:只要新建就好了,操作都是在代码中处理的. 日志查看:菜单位置:View → show postman console ,显示这个窗口视图就可以了 请求时执行的脚本:Pre-request Script 标签页,使用语言javascript, 通常作为加密. 接受返回时执行的脚本:T

  • 如何通过一个注解实现MyBatis字段加解密

    目录 简介 模块 使用方法 配置项说明 开源链接 总结 简介 mybatis-crypto 是一个基于 mybatis 插件机制实现的字段加解密组件,通过一个注解即可对敏感数据进行加解密处理. 支持自定义 Encryptor.特殊字段单独指定 Encryptor 和 key ,满足大部分使用场景. 模块 mybatis-crypto 包括三个模块: mybatis-crypto-core 插件的核心功能模块 mybatis-crypto-spring-boot-starter 提供了 Sprin

  • Spring MVC自定义日期类型转换器实例详解

    Spring MVC自定义日期类型转换器实例详解 WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查询到数据,然后在jsp页面上格式化,最后展示给用户.但是这次不同,这次我纯属操作数据,没有页面.直接从数据库拿数据给它们返数据.它们给我传数据我持久化数据,说到这里一个小问题就默默的来了. 首先把问题还原一下吧(这是一个数据导出功能),下图中用红框圈

  • Python内置方法实现字符串的秘钥加解密(推荐)

    在实际编程开发中,我们会使用到各类的加密算法来对数据和信息进行加密.比如密码中比较常见的MD5加密,以及AES加密等等. 对于密码认证来说,MD5加密是比较适合的,因为其不需要接触到明文的数据,只需要比对MD5加密后的哈希值就能判断数据是否一致:而对于一些在加密后进行解密的数据而言,AES则更加的常用. 在Python中实现AES算法需要借助的第三方库Crypto,其在各个操作系统上的安装方法有些许复杂,所以对于简单的使用有点杀鸡用牛刀的意思.在Mrdoc的开发过程中,我们就遇到了这样的问题.一

随机推荐