iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >mybatis类型转换器如何实现数据加解密
  • 566
分享到

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

2024-04-02 19:04:59 566人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录mybatis类型转换器数据加解密背景需求mybatis 类型转换器数据加解密类型转换使用方法mybatis密码解密mybatis的配置properties的配置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算法,此处对加解密结果做一下缓存,因为一些数据是一样的,如果每次都去加密,也是会消耗一定的时间


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

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

--结束END--

本文标题: mybatis类型转换器如何实现数据加解密

本文链接: https://www.lsjlt.com/news/136433.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作