資料庫儲存加密資料,應用層查詢時自動解密,寫入時自動加密,對業務代碼透明。
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); // 你的解密工具類
}
}
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; }
// ... 其他介面方法
}
<!-- mybatis-config.xml -->
<typeHandlers>
<typeHandler javaType="com.yourpkg.CryptType" handler="com.yourpkg.CryptTypeHandler"/>
</typeHandlers>
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;
}
}
<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>
typeHandler 屬性局部使用。