mybatis自定義參數(shù)類型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏
1 問題背景
在數(shù)據(jù)庫(kù)存儲(chǔ)人員的信息時(shí),有一些信息是敏感數(shù)據(jù),如身份證號(hào)、出生地等。為了防止信息泄漏,這些信息不允許直接在數(shù)據(jù)庫(kù)中查看,此時(shí)就需要對(duì)這些字段進(jìn)行加密存儲(chǔ),但在頁(yè)面查看的仍舊是解密后的數(shù)據(jù)。這里就涉及到加解密的問題,有兩種解決方案。
2 解決方案
2.1 使用數(shù)據(jù)庫(kù)加密算法
通過數(shù)據(jù)庫(kù)自帶的加密算法,在sql里直接使用算法加解密,這種有較多缺點(diǎn),不推薦使用。
- 寫法繁瑣,不易開發(fā)維護(hù)
- 適配多種數(shù)據(jù)庫(kù)時(shí),算法難以統(tǒng)一,工作量也劇增
2.2 使用mybatis的自定義參數(shù)類型轉(zhuǎn)換器
通過自定義Java類型和類型轉(zhuǎn)換器,并在mapper.xml里標(biāo)注類型,通過mybatis進(jìn)行加解密。
- 加密算法可自由選擇
- 開發(fā)維護(hù)比較簡(jiǎn)單方便
- 不存在適配多種數(shù)據(jù)庫(kù)的問題
3 一般web項(xiàng)目使用
3.1 創(chuàng)建自定義Java類型
創(chuàng)建一個(gè)空白類,在mapper.xml文件查詢和新增修改時(shí)標(biāo)注說明,表示需要mybatis進(jìn)行相關(guān)類型轉(zhuǎn)換。
@Alias("SecretField") public class SecretField { }
3.2 自定義類的轉(zhuǎn)換處理器
這里使用國(guó)密SM4進(jìn)行加解密,當(dāng)然算法可自由選擇別的如AES等。
@MappedTypes注解映射剛才的自定義Java類
@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 配置自定義類型和類型轉(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 查詢使用
查詢返回需通過resultMap映射,在加密字段進(jìn)行javaType指明需要的類型轉(zhuǎn)換器。
另外如果舊代碼中結(jié)果集大量直接使用map返回,時(shí)間緊張的情況下,則可考慮寫一個(gè)工具類,在service里調(diào)用進(jìn)行手動(dòng)解密,沒得辦法呀!。
<resultMap id="BaseResultMap" type="User"> <result column="sfz" property="sfz" javaType="SecretField"/> </resultMap>
3.5 新增修改使用
在設(shè)置相關(guān)參數(shù)值時(shí),也就是在#{}里,使用javaType指明需要的類型轉(zhuǎn)換器。
insert into ... values(... <if test="sfz!= null"> #{sfz,jdbcType=VARCHAR,javaType=SecretField}, </if> )
4. springboot項(xiàng)目使用
- 自定義類型和類型轉(zhuǎn)換器代碼和上面一樣,這里不在贅述。
- 項(xiàng)目使用了mybatis-plus插件。
4.1 配置自定義類型和類型轉(zhuǎn)換器
在項(xiàng)目配置文件里application.yml里加上配置type-handlers-package
和 type-aliases-package:
分別指出你的類型轉(zhuǎn)換器所在包名和自定義類所在包名。
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)目的查詢、新增和修改使用方法這里也是可以正常使用的
1)在實(shí)體類上使用注解
@TableName(autoResultMap = true)
2)在加密字段上指明類型
@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; /** * 名稱 */ 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ù)類型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏的詳細(xì)內(nèi)容,更多關(guān)于mybatis數(shù)據(jù)庫(kù)字段加密脫敏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(28)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07多數(shù)據(jù)源模式JPA整合sharding-jdbc實(shí)現(xiàn)數(shù)據(jù)脫敏
這篇文章主要為大家介紹了JPA項(xiàng)目中多數(shù)據(jù)源模式整合sharding-jdbc來實(shí)現(xiàn)數(shù)據(jù)脫敏,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02詳解高性能緩存Caffeine原理及實(shí)戰(zhàn)
Caffeine是基于Java 8開發(fā)的,提供了近乎最佳命中率的高性能本地緩存組件,Spring5開始不再支持Guava Cache,改為使用Caffeine。Caffeine提供的內(nèi)存緩存使用參考Google guava的API2021-06-06SpringBoot啟動(dòng)遇到的異常問題及解決方案
這篇文章主要介紹了SpringBoot啟動(dòng)遇到的異常問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java為什么使用補(bǔ)碼進(jìn)行計(jì)算的原因分析
這篇文章主要介紹了Java為什么使用補(bǔ)碼進(jìn)行計(jì)算的原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08selenium + ChromeDriver安裝及使用方法
這篇文章主要介紹了selenium + ChromeDriver安裝及使用方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06