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

Mybatis的TypeHandler實(shí)現(xiàn)數(shù)據(jù)加解密詳解

 更新時(shí)間:2024年01月23日 10:05:51   作者:snamc  
這篇文章主要介紹了Mybatis基于TypeHandler實(shí)現(xiàn)敏感數(shù)據(jù)加密詳解,Typehandler是mybatis提供的一個(gè)接口,通過(guò)實(shí)現(xiàn)這個(gè)接口,可以實(shí)現(xiàn)jdbc類型數(shù)據(jù)和java類型數(shù)據(jù)的轉(zhuǎn)換,需要的朋友可以參考下

一、背景

有些項(xiàng)目需要對(duì)一些信息入庫(kù)前進(jìn)行加密處理,為了數(shù)據(jù)安全或者隱私合規(guī),但與此同時(shí)也使數(shù)據(jù)處理變得麻煩,不可避免的會(huì)帶來(lái)重復(fù)冗長(zhǎng)的代碼。如果能在持久層處理好數(shù)據(jù),避免在業(yè)務(wù)層處理,就能合理的規(guī)避這個(gè)問(wèn)題。

二、方案

使用mybatis框架提供的TypeHandler來(lái)實(shí)現(xiàn)在持久層處理數(shù)據(jù)。

TypeHandler簡(jiǎn)介

Typehandler是mybatis提供的一個(gè)接口,通過(guò)實(shí)現(xiàn)這個(gè)接口,可以實(shí)現(xiàn)jdbc類型數(shù)據(jù)和java類型數(shù)據(jù)的轉(zhuǎn)換,我們常看到的varchar轉(zhuǎn)string、bigint轉(zhuǎn)long等都是mybatis自身實(shí)現(xiàn)此接口處理的。

 我們可以自己實(shí)現(xiàn)一個(gè)Typehandler,滿足自己的需求。

三、詳細(xì)實(shí)現(xiàn)

1.實(shí)現(xiàn)接口,定義自己的Typehandler

一般實(shí)現(xiàn)BaseTypeHandler接口即可。筆者的加解密使用了hutool提供的des加密,maven坐標(biāo)如下:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.10</version>
</dependency>

代碼如下,可根據(jù)業(yè)務(wù)需求編寫(xiě)方法實(shí)現(xiàn)代碼:

package com.example.cryptotypehandler.common;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(String.class)
public class CryptoTypeHandler extends BaseTypeHandler<String> {
    private final byte[] key = {-26, -70, -29, -99, 73, -82, 91, -50, 79, -77, 59, 104, 2, -36, 50, -22, -39, -15, -57, -89, 81, -99, 42, -89};
    private final SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DESede, key);
    /*
     * 加工入?yún)?
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        if (parameter != null) {
            //加密
            String encryptHex = des.encryptHex(parameter);
            log.info("{} ---加密為---> {}", parameter, encryptHex);
            ps.setString(i, encryptHex);
        }
    }
    /*
     * 根據(jù)列名獲取返回結(jié)果,可在此方法中加工返回值
     */
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String originRes = rs.getString(columnName);
        if (originRes != null) {
            String res = des.decryptStr(originRes);
            log.info("{} ---解密為---> {}", originRes, res);
            return res;
        }
        log.info("結(jié)果為空,無(wú)需解密");
        return null;
    }
    /*
     * 根據(jù)列下標(biāo)獲取返回結(jié)果,可在此方法中加工返回值
     */
    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String originRes = rs.getString(columnIndex);
        if (originRes != null) {
            String res = des.decryptStr(originRes);
            log.info("{} ---解密為---> {}", originRes, res);
            return res;
        }
        log.info("結(jié)果為空,無(wú)需解密");
        return null;
    }
    /*
     * 根據(jù)列下標(biāo)獲取返回結(jié)果(存儲(chǔ)過(guò)程),可在此方法中加工返回值
     */
    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String originRes = cs.getString(columnIndex);
        if (originRes != null) {
            String res = des.decryptStr(originRes);
            log.info("{} ---解密為---> {}", originRes, res);
            return res;
        }
        log.info("結(jié)果為空,無(wú)需解密");
        return null;
    }
}

 2.注冊(cè)自定義的TypeHandler

編寫(xiě)好的TypeHandler需要注冊(cè)到mybatis中,在application.yml或者application.properties中加入配置:

properties文件:

mybatis.type-handlers-package=com.example.cryptotypehandler.common

yml文件

mybatis: type-handlers-package: com.example.cryptotypehandler.common

筆者包結(jié)構(gòu)如下

 3.定義mapper層接口

實(shí)體對(duì)象類

package com.example.cryptotypehandler.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class AccountDO {
    private Long id;
    /**
     * 用戶名
     */
    private String userName;
    /**
     * 密碼
     */
    private String password;
}

和普通的mapper沒(méi)區(qū)別:

package com.example.cryptotypehandler.mapper;
import com.example.cryptotypehandler.domain.AccountDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author shuai.mh
 * @since 2022-11-29
 */
@Mapper
public interface AccountMapper {
    int insertEncrypt(AccountDO accountDO);
    List<AccountDO> selectAccount(AccountDO accountDO);
}

4.編寫(xiě)mapper.xml

這邊有幾個(gè)注意點(diǎn):

  • 首先看insert語(yǔ)句,我們需要加密的是password字段,因此在password后加上typeHandler=com.example.cryptotypehandler.common.CryptoTypeHandler;此外,#{userName}中,jdbcType=varchar不要填寫(xiě),因?yàn)樽远x的typerHandler中加了下面兩個(gè)注解:@MappedJdbcTypes(JdbcType.VARCHAR)和@MappedTypes(String.class),這兩個(gè)注解表示JdbcType為varchar是會(huì)使用此handler,加了的話,userName也會(huì)被加密。
  • 再看select語(yǔ)句,sql和普通的沒(méi)有區(qū)別,但是resultMap中的password映射加了typeHandler="com.example.cryptotypehandler.common.CryptoTypeHandler",代表此字段在轉(zhuǎn)換成實(shí)體對(duì)象時(shí)會(huì)被handler處理,此外其他字段的映射jdbcType保持缺省,如果是varchar也會(huì)被處理。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.cryptotypehandler.mapper.AccountMapper">
    <!-- 通用查詢映射結(jié)果 -->
    <resultMap id="BaseResultMap" type="com.example.cryptotypehandler.domain.AccountDO">
        <id column="id" property="id" />
        <result column="user_name" property="userName"/>
        <result column="password" property="password" typeHandler="com.example.cryptotypehandler.common.CryptoTypeHandler" />
    </resultMap>
    <!-- 通用查詢結(jié)果列 -->
    <sql id="Base_Column_List">
        id, user_name, password
    </sql>
    <insert id="insertEncrypt">
        insert into account (id, user_name, password)
        values (#{id}, #{userName}, #{password, typeHandler=com.example.cryptotypehandler.common.CryptoTypeHandler})
    </insert>
    <select id="selectAccount" resultMap="BaseResultMap">
        select <include refid="Base_Column_List"></include>
        from account
        where user_name = #{userName}
    </select>
</mapper>

5.調(diào)用接口,簡(jiǎn)單測(cè)試

①新增用戶

 ②查看數(shù)據(jù)庫(kù),密碼已被加密

 ③查詢用戶,查詢結(jié)果已解密

到此這篇關(guān)于Mybatis的TypeHandler實(shí)現(xiàn)數(shù)據(jù)加解密詳解的文章就介紹到這了,更多相關(guān)TypeHandler數(shù)據(jù)加解密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud客戶端報(bào)錯(cuò):- was unable to send heartbeat!的解決

    SpringCloud客戶端報(bào)錯(cuò):- was unable to send&nb

    這篇文章主要介紹了SpringCloud客戶端報(bào)錯(cuò):- was unable to send heartbeat!的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • JAVA 日常開(kāi)發(fā)中Websocket示例詳解

    JAVA 日常開(kāi)發(fā)中Websocket示例詳解

    JAVA |日常開(kāi)發(fā)中Websocket詳解,WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,它在Web應(yīng)用中實(shí)現(xiàn)了客戶端與服務(wù)器之間的實(shí)時(shí)數(shù)據(jù)傳輸,本文將詳細(xì)介紹Java開(kāi)發(fā)中WebSocket的使用,包括基本概念、Java API、使用示例以及注意事項(xiàng),感興趣的朋友一起看看吧
    2024-12-12
  • 面試必問(wèn)項(xiàng)之Set實(shí)現(xiàn)類:TreeSet

    面試必問(wèn)項(xiàng)之Set實(shí)現(xiàn)類:TreeSet

    這篇文章主要介紹了Java TreeSet類的簡(jiǎn)單理解和使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Tomcat ClassLoader打破雙親委派源碼解析

    Tomcat ClassLoader打破雙親委派源碼解析

    這篇文章主要為大家介紹了Tomcat ClassLoader打破雙親委派源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • java實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    java實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)籍管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 解決FileWriter 寫(xiě)入文本不換行的問(wèn)題

    解決FileWriter 寫(xiě)入文本不換行的問(wèn)題

    這篇文章主要介紹了解決FileWriter 寫(xiě)入文本不換行的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot實(shí)現(xiàn)圖片上傳與下載功能

    springboot實(shí)現(xiàn)圖片上傳與下載功能

    這篇文章主要為大家詳細(xì)介紹了后端spring項(xiàng)目經(jīng)常要做的功能,實(shí)現(xiàn)圖片上傳和下載,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實(shí)現(xiàn)

    IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實(shí)現(xiàn)

    這篇文章主要介紹了IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • 命令行編譯java文件方式

    命令行編譯java文件方式

    這篇文章主要介紹了命令行編譯java文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • SpringBoot嵌套事務(wù)詳解及失效解決方案

    SpringBoot嵌套事務(wù)詳解及失效解決方案

    在復(fù)雜的業(yè)務(wù)場(chǎng)景中,嵌套事務(wù)可以幫助我們更加精細(xì)地控制數(shù)據(jù)的一致性,然而,在 Spring Boot 中,如果嵌套事務(wù)的配置不當(dāng),可能會(huì)導(dǎo)致事務(wù)不生效的問(wèn)題,尤其是在同一個(gè)類中進(jìn)行方法調(diào)用時(shí),本文將詳細(xì)介紹嵌套事務(wù)的原理、失效的原因以及解決方案
    2025-01-01

最新評(píng)論