首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 自定義 TypeHandler 實現字段加解密

     編輯:Java 相關知識

MyBatis TypeHandler 實現敏感字段自動加解密

需求場景

資料庫儲存加密資料,應用層查詢時自動解密,寫入時自動加密,對業務代碼透明。

核心實作步驟

1. 實作 TypeHandler 介面

public class CryptTypeHandler implements TypeHandler<CryptType> {

    @Override
    public CryptType getResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        CryptType cryptType = new CryptType();
        if (value != null) {
            cryptType.setValue(decrypt(value));
        }
        return cryptType;
    }

    @Override
    public CryptType getResult(ResultSet rs, int columnIndex) throws SQLException {
        String value = rs.getString(columnIndex);
        CryptType cryptType = new CryptType();
        if (value != null) {
            cryptType.setValue(value); // 查詢結果集索引方式同樣處理
        }
        return cryptType;
    }

    @Override
    public CryptType getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        CryptType cryptType = new CryptType();
        if (value != null) {
            cryptType.setValue(value);
        }
        return cryptType;
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, CryptType parameter, JdbcType jdbcType) throws SQLException {
        String value = "";
        if (parameter != null && parameter.getValue() != null) {
            value = encrypt(parameter.getValue());
        }
        ps.setString(i, value);
    }

    private String encrypt(String value) {
        return CryptUtils.encrypt(value); // 你的加密工具類
    }

    private String decrypt(String value) {
        return CryptUtils.decrypt(value); // 你的解密工具類
    }
}

2. 定義自定義類型包裝類

public class CryptType implements Serializable, CharSequence, Comparable<String> {
    private static final long serialVersionUID = 1L;
    private String value;

    public CryptType() {}
    public CryptType(String value) { this.value = value; }

    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }

    // 實作 CharSequence、Comparable 介面方法(省略具體實作)
    @Override public String toString() { return value; }
    // ... 其他介面方法
}

3. MyBatis 配置註冊 TypeHandler

<!-- mybatis-config.xml -->
<typeHandlers>
    <typeHandler javaType="com.yourpkg.CryptType" handler="com.yourpkg.CryptTypeHandler"/>
</typeHandlers>

4. 實體類中使用自定義類型

public class User {
    private CryptType idCard; // 身分證等敏感字段

    public CryptType getIdCard() {
        // 查詢條件為空時返回 null,避免 SQL 條件匹配失敗
        if (idCard != null && idCard.getValue().isEmpty()) {
            return null;
        }
        return idCard;
    }

    public void setIdCard(CryptType idCard) {
        this.idCard = idCard;
    }
}

Mapper XML 中的使用

<resultMap id="UserResult" type="User">
    <result column="id_card" property="idCard" javaType="CryptType" jdbcType="VARCHAR" />
</resultMap>

<insert id="insertUser">
    INSERT INTO user (id_card) VALUES (#{idCard, typeHandler=CryptTypeHandler})
</insert>

<select id="selectUser" resultMap="UserResult">
    SELECT id_card FROM user WHERE id = #{id}
</select>

注意事項

  • 查詢條件若使用加密字段,需在 SQL 中手動加密或避免直接用於 WHERE 條件。
  • 確保加解密算法可逆且效能可接受。
  • TypeHandler 註冊後,全局生效,亦可在具體映射中指定 typeHandler 屬性局部使用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved