mybatis自定義參數(shù)類(lèi)型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏
1 問(wèn)題背景
在數(shù)據(jù)庫(kù)存儲(chǔ)人員的信息時(shí),有一些信息是敏感數(shù)據(jù),如身份證號(hào)、出生地等。為了防止信息泄漏,這些信息不允許直接在數(shù)據(jù)庫(kù)中查看,此時(shí)就需要對(duì)這些字段進(jìn)行加密存儲(chǔ),但在頁(yè)面查看的仍舊是解密后的數(shù)據(jù)。這里就涉及到加解密的問(wèn)題,有兩種解決方案。
2 解決方案
2.1 使用數(shù)據(jù)庫(kù)加密算法
通過(guò)數(shù)據(jù)庫(kù)自帶的加密算法,在sql里直接使用算法加解密,這種有較多缺點(diǎn),不推薦使用。
- 寫(xiě)法繁瑣,不易開(kāi)發(fā)維護(hù)
- 適配多種數(shù)據(jù)庫(kù)時(shí),算法難以統(tǒng)一,工作量也劇增
2.2 使用mybatis的自定義參數(shù)類(lèi)型轉(zhuǎn)換器
通過(guò)自定義Java類(lèi)型和類(lèi)型轉(zhuǎn)換器,并在mapper.xml里標(biāo)注類(lèi)型,通過(guò)mybatis進(jìn)行加解密。
- 加密算法可自由選擇
- 開(kāi)發(fā)維護(hù)比較簡(jiǎn)單方便
- 不存在適配多種數(shù)據(jù)庫(kù)的問(wèn)題
3 一般web項(xiàng)目使用
3.1 創(chuàng)建自定義Java類(lèi)型
創(chuàng)建一個(gè)空白類(lèi),在mapper.xml文件查詢(xún)和新增修改時(shí)標(biāo)注說(shuō)明,表示需要mybatis進(jìn)行相關(guān)類(lèi)型轉(zhuǎn)換。
@Alias("SecretField")
public class SecretField {
}
3.2 自定義類(lèi)的轉(zhuǎn)換處理器
這里使用國(guó)密SM4進(jìn)行加解密,當(dāng)然算法可自由選擇別的如AES等。
@MappedTypes注解映射剛才的自定義Java類(lèi)
@MappedTypes(SecretField.class)
public class SecretFieldTypeHandler extends BaseTypeHandler<String> {
private static final Logger log = LoggerFactory.getLogger(SecretFieldTypeHandler.class);
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
try {
if (StringUtils.hasText(parameter)) {
String encryptStr = Sm4Util.encryptData_ECB(parameter);
ps.setString(i, encryptStr);
}
} catch (Exception e) {
ps.setString(i, parameter);
log.error("mybatis加密參數(shù)異常,i:{},parameter:{}", i, parameter);
}
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
String columnValue = rs.getString(columnName);
try {
if (StringUtils.hasText(columnValue)) {
columnValue = Sm4Util.decryptData_ECB(columnValue);
}
} catch (Exception e) {
log.error("mybatis解密參數(shù)異常,columnName:{}, columnValue:{}", columnName, columnValue);
}
return columnValue;
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return null;
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return null;
}
}
3.3 配置自定義類(lèi)型和類(lèi)型轉(zhuǎn)換器
這一步也可使用相關(guān)注解完成。
配置文件為mybatis的配置文件,如mybatis-config.xml。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE configuration PUBLIC "-//mybaties.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
</settings>
<typeAliases>
<typeAlias type="com.banxian.mybatis.alias.SecretField" alias="SecretField"/>
</typeAliases>
<typeHandlers>
<typeHandler handler="com.banxian.mybatis.typehandler.SecretFieldTypeHandler" />
</typeHandlers>
</configuration>
3.4 查詢(xún)使用
查詢(xún)返回需通過(guò)resultMap映射,在加密字段進(jìn)行javaType指明需要的類(lèi)型轉(zhuǎn)換器。
另外如果舊代碼中結(jié)果集大量直接使用map返回,時(shí)間緊張的情況下,則可考慮寫(xiě)一個(gè)工具類(lèi),在service里調(diào)用進(jìn)行手動(dòng)解密,沒(méi)得辦法呀!。
<resultMap id="BaseResultMap" type="User">
<result column="sfz" property="sfz" javaType="SecretField"/>
</resultMap>
3.5 新增修改使用
在設(shè)置相關(guān)參數(shù)值時(shí),也就是在#{}里,使用javaType指明需要的類(lèi)型轉(zhuǎn)換器。
insert into ... values(...
<if test="sfz!= null">
#{sfz,jdbcType=VARCHAR,javaType=SecretField},
</if>
)
4. springboot項(xiàng)目使用
- 自定義類(lèi)型和類(lèi)型轉(zhuǎn)換器代碼和上面一樣,這里不在贅述。
- 項(xiàng)目使用了mybatis-plus插件。
4.1 配置自定義類(lèi)型和類(lèi)型轉(zhuǎn)換器
在項(xiàng)目配置文件里application.yml里加上配置type-handlers-package 和 type-aliases-package:分別指出你的類(lèi)型轉(zhuǎn)換器所在包名和自定義類(lèi)所在包名。
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-not-delete-value: "0"
logic-delete-value: "1"
mapper-locations: "classpath*:/mapper/**/*.xml"
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-handlers-package: com.banxian.mybatis.typehandler
type-aliases-package: com.banxian.mybatis.alias
4.2 mybatis-plus的使用
當(dāng)然上面web項(xiàng)目的查詢(xún)、新增和修改使用方法這里也是可以正常使用的
1)在實(shí)體類(lèi)上使用注解
@TableName(autoResultMap = true)
2)在加密字段上指明類(lèi)型
@TableField(value = "sfz", typeHandler = SecretFieldTypeHandler.class)
@Data
@TableName(autoResultMap = true)
public class User implements Serializable {
private static final long serialVersionUID = 4344848828462926573L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Integer id;
/**
* 名稱(chēng)
*/
private String userName;
/**
* 是否刪除 1:是 0:否
*/
@TableLogic
private String deleted;
/**
* 是否有效 1:是 0:否
*/
private String valid;
/**
* 創(chuàng)建時(shí)間
*/
@TableField(value = "create_at", fill = FieldFill.INSERT)
private LocalDateTime createAt;
/**
* 更新時(shí)間
*/
@TableField(value = "update_at", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateAt;
@TableField(value = "sfz", typeHandler = SecretFieldTypeHandler.class)
private String sfz;
}以上就是mybatis自定義參數(shù)類(lèi)型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏的詳細(xì)內(nèi)容,更多關(guān)于mybatis數(shù)據(jù)庫(kù)字段加密脫敏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何解決IDEA沒(méi)有新建servlet選項(xiàng)問(wèn)題
這篇文章主要介紹了如何解決IDEA沒(méi)有新建servlet選項(xiàng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
SpringBoot實(shí)現(xiàn)向量數(shù)據(jù)庫(kù)優(yōu)化檢索的方案及示例
在Spring?Boot中實(shí)現(xiàn)RAG(Retrieval-Augmented?Generation)的增強(qiáng),可以從檢索優(yōu)化、生成優(yōu)化和系統(tǒng)架構(gòu)三個(gè)維度進(jìn)行改進(jìn),本文給大家介紹了具體實(shí)現(xiàn)方案及示例,需要的朋友可以參考下2025-02-02
Java的web開(kāi)發(fā)中SSH框架的協(xié)作處理應(yīng)用筆記
這篇文章主要介紹了Java的web開(kāi)發(fā)中SSH框架的協(xié)作處理應(yīng)用筆記,SSH是指Struts和Spring以及Hibernate的框架搭配,需要的朋友可以參考下2015-12-12
Java讀取文件及基于正則表達(dá)式的獲取電話(huà)號(hào)碼功能詳解
這篇文章主要介紹了Java讀取文件及基于正則表達(dá)式的獲取電話(huà)號(hào)碼功能,結(jié)合實(shí)例形式詳細(xì)分析了正則匹配操作的相關(guān)語(yǔ)法及電話(huà)號(hào)碼匹配的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09
詳解spring mvc 請(qǐng)求轉(zhuǎn)發(fā)和重定向
這篇文章主要介紹了詳解spring mvc 請(qǐng)求轉(zhuǎn)發(fā)和重定向,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
java開(kāi)發(fā)SSM框架具有rest風(fēng)格的SpringMVC
這篇文章主要介紹了java開(kāi)發(fā)中如何使SSM框架具有rest風(fēng)格的SpringMVC實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
解決使用mybatis-plus時(shí),生成的SQL大寫(xiě)變小寫(xiě)加下劃線(xiàn)問(wèn)題
這篇文章主要介紹了解決使用mybatis-plus時(shí),生成的SQL大寫(xiě)變小寫(xiě)加下劃線(xiàn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
Springcloud Eureka配置及集群代碼實(shí)例
這篇文章主要介紹了Springcloud Eureka配置及集群代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
Java字符流和字節(jié)流對(duì)文件操作的區(qū)別
本篇文章主要介紹了Java的IO流分為字符流(Reader,Writer)和字節(jié)流(InputStream,OutputStream),字節(jié)流顧名思義字節(jié)流就是將文件的內(nèi)容讀取到字節(jié)數(shù)組,對(duì)初學(xué)者很有用,有需要的朋友可以了解一下。2016-10-10
springboot如何通過(guò)URL方式訪(fǎng)問(wèn)外部資源
這篇文章主要介紹了springboot如何通過(guò)URL方式訪(fǎng)問(wèn)外部資源,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

