MyBatis 实体类中的数据加密实践
很多开发者在使用 MyBatis 时,可能会遇到一个现实问题:框架本身并未内置数据加密功能。但这并不意味着我们束手无策。实际上,通过在实体类中巧妙地融入 Ja va 代码,我们完全可以自主实现数据的加密与解密逻辑。下面,就通过一个清晰的示例,来看看具体如何操作。

首先,一切的基础是一个可靠的加密工具类。这里,我们借助 Ja va 标准库中的 ja vax.crypto 包,来构建一个基于 AES 算法的加密工具:
import ja vax.crypto.Cipher;
import ja vax.crypto.spec.SecretKeySpec;
import ja va.nio.charset.StandardCharsets;
import ja va.util.Base64;
public class EncryptionUtils {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
public static String encrypt(String data, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedData);
}
public static String decrypt(String encryptedData, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decodedData = Base64.getDecoder().decode(encryptedData);
return new String(cipher.doFinal(decodedData), StandardCharsets.UTF_8);
}
}
有了工具,下一步就是在实体类中将其用起来。关键在于,如何让加密解密过程与实体类的属性存取无缝衔接:
public class User {
private String id;
private String name;
private String encryptedPassword;
// 省略 getter 和 setter 方法
public void setPassword(String password, String encryptionKey) {
try {
this.encryptedPassword = EncryptionUtils.encrypt(password, encryptionKey);
} catch (Exception e) {
throw new RuntimeException("Error encrypting password", e);
}
}
public String getPassword(String encryptionKey) {
try {
return EncryptionUtils.decrypt(this.encryptedPassword, encryptionKey);
} catch (Exception e) {
throw new RuntimeException("Error decrypting password", e);
}
}
}
看明白了吗?这里的核心思路是“明存密取”。我们不再直接存储明文密码,而是将加密后的结果存入 encryptedPassword 字段。同时,通过自定义的 setPassword 方法,在设置密码的瞬间完成加密;而通过 getPassword 方法,则在需要时提供解密后的原始密码。
当然,需要特别提醒的是,上面这个示例主要用于展示实现思路。在实际生产环境中,你必须根据具体的安全等级要求,审慎选择更强大的加密算法,并设计一套周全的密钥管理方案,这才是保障数据安全的关键所在。
