欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mybatis類(lèi)型轉(zhuǎn)換器如何實(shí)現(xiàn)數(shù)據(jù)加解密

 更新時(shí)間:2021年09月23日 10:05:21   作者:userwyh  
這篇文章主要介紹了mybatis類(lèi)型轉(zhuǎn)換器如何實(shí)現(xiàn)數(shù)據(jù)加解密,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

mybatis類(lèi)型轉(zhuǎn)換器數(shù)據(jù)加解密

背景需求

對(duì)表中的某些字段進(jìn)行加密,查詢(xún)之后對(duì)字段進(jìn)行解密,業(yè)務(wù)代碼無(wú)需關(guān)注加解密環(huán)節(jié)。

mybatis 攔截器 vs 類(lèi)型轉(zhuǎn)換器

mybatis的攔截器能實(shí)現(xiàn)上面的需求,但是會(huì)攔截所有的sql語(yǔ)句,如果項(xiàng)目中只是部分sql涉及到加解密操作,還是比較犧牲大局的。實(shí)現(xiàn)起來(lái)也比較麻煩,特別是單參數(shù)查詢(xún)的時(shí)候,比如參數(shù)名稱(chēng)name,此時(shí)需要對(duì)name進(jìn)行加密就相對(duì)困難。如果是多參數(shù),因?yàn)榈讓訒?huì)將參數(shù)封裝成Map,可以根據(jù)是否含有指定的key進(jìn)行加密。

mybatis類(lèi)型轉(zhuǎn)換器也可以實(shí)現(xiàn)上面的需求,方案為修改xml里面的配置,指定類(lèi)型轉(zhuǎn)換器,并在轉(zhuǎn)換器里面實(shí)現(xiàn)數(shù)據(jù)的加解密。

mybatis 類(lèi)型轉(zhuǎn)換器

java有java的數(shù)據(jù)類(lèi)型,數(shù)據(jù)庫(kù)有數(shù)據(jù)庫(kù)的數(shù)據(jù)類(lèi)型,那么我們?cè)谕鶖?shù)據(jù)庫(kù)中插入數(shù)據(jù)的時(shí)候是如何把java類(lèi)型當(dāng)做數(shù)據(jù)庫(kù)類(lèi)型插入數(shù)據(jù)庫(kù),在從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)的時(shí)候又是如何把數(shù)據(jù)庫(kù)類(lèi)型當(dāng)做java類(lèi)型來(lái)處理呢?這中間必然要經(jīng)過(guò)一個(gè)類(lèi)型轉(zhuǎn)換。

mybatis提供了TypeHandler接口,抽象類(lèi)BaseTypeHandler實(shí)現(xiàn)TypeHandler接口,String,Integer,Long等常見(jiàn)的數(shù)據(jù)類(lèi)型轉(zhuǎn)換都是基于繼承BaseTypeHandler實(shí)現(xiàn),BaseTypeHandler提供了基本的判空等操作。因此我們可以繼承BaseTypeHandler或者實(shí)現(xiàn)TypeHandler接口完成自定義類(lèi)型轉(zhuǎn)換,一般建議繼承BaseTypeHandler來(lái)編碼。

數(shù)據(jù)加解密類(lèi)型轉(zhuǎn)換

假設(shè)加解密采用AES算法,此處對(duì)加解密結(jié)果做一下緩存,因?yàn)橐恍?shù)據(jù)是一樣的,如果每次都去加密,也是會(huì)消耗一定的時(shí)間

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

使用方法

針對(duì)sql語(yǔ)句,在xml配置文件中,對(duì)需要加密的字段加上

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

針對(duì)查詢(xún)結(jié)果,在xml配置文件中,在resultMap里面對(duì)需要解密的字段加上

<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工廠(chǎng)
	 */
	private final static SqlSessionFactory sqlSessionFactory;
 
	/**
	 * 日志類(lèi)
	 */
	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;
	} 
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot多數(shù)據(jù)庫(kù)連接(mysql+oracle)的實(shí)現(xiàn)

    SpringBoot多數(shù)據(jù)庫(kù)連接(mysql+oracle)的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot多數(shù)據(jù)庫(kù)連接(mysql+oracle)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java異常處理的12條軍規(guī)總結(jié)

    Java異常處理的12條軍規(guī)總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java異常處理的12條軍規(guī),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 簡(jiǎn)單探索 Java 中的惰性計(jì)算

    簡(jiǎn)單探索 Java 中的惰性計(jì)算

    這篇文章主要介紹了簡(jiǎn)單探索 Java 中的惰性計(jì)算,惰性計(jì)算(盡可能延遲表達(dá)式求值)是許多函數(shù)式編程語(yǔ)言的特性。惰性集合在需要時(shí)提供其元素,無(wú)需預(yù)先計(jì)算它們,這帶來(lái)了一些好處。,需要的朋友可以參考下
    2019-06-06
  • 關(guān)于Java中如何實(shí)現(xiàn)文件的讀寫(xiě)操作

    關(guān)于Java中如何實(shí)現(xiàn)文件的讀寫(xiě)操作

    在Java中,可以使用File和FileInputStream、FileOutputStream、BufferedReader、PrintWriter等類(lèi)來(lái)進(jìn)行文件讀寫(xiě)操作,需要的朋友可以參考下
    2023-05-05
  • java實(shí)現(xiàn)開(kāi)根號(hào)的運(yùn)算方式

    java實(shí)現(xiàn)開(kāi)根號(hào)的運(yùn)算方式

    這篇文章主要介紹了java實(shí)現(xiàn)開(kāi)根號(hào)的運(yùn)算方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java模擬ajax訪(fǎng)問(wèn)另一個(gè)項(xiàng)目的controller代碼實(shí)例

    java模擬ajax訪(fǎng)問(wèn)另一個(gè)項(xiàng)目的controller代碼實(shí)例

    今天小編就為大家分享一篇關(guān)于java模擬ajax訪(fǎng)問(wèn)另一個(gè)項(xiàng)目的controller代碼實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • SpringMVC?bean實(shí)現(xiàn)加載控制方法詳解

    SpringMVC?bean實(shí)現(xiàn)加載控制方法詳解

    SpringMVC是一種基于Java,實(shí)現(xiàn)了Web?MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類(lèi)型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡?qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開(kāi)發(fā),SpringMVC也是要簡(jiǎn)化我們?nèi)粘eb開(kāi)發(fā)
    2022-08-08
  • springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解

    springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解

    這篇文章主要為大家介紹了springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Java判斷IP地址為內(nèi)網(wǎng)IP還是公網(wǎng)IP的方法

    Java判斷IP地址為內(nèi)網(wǎng)IP還是公網(wǎng)IP的方法

    這篇文章主要介紹了Java判斷IP地址為內(nèi)網(wǎng)IP還是公網(wǎng)IP的方法,針對(duì)tcp/ip協(xié)議中保留的三個(gè)私有地址進(jìn)行判斷分析,是比較實(shí)用的技巧,需要的朋友可以參考下
    2015-01-01
  • java中的static{}塊的實(shí)例詳解

    java中的static{}塊的實(shí)例詳解

    這篇文章主要介紹了java中的static{}塊的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例來(lái)幫助大家理解該如何使用static塊,需要的朋友可以參考下
    2017-08-08

最新評(píng)論