Encrypting Sensitive Data in MySQL with MyBatis TypeHandler – A Step‑by‑Step Guide
This article explains why storing plain‑text sensitive fields such as phone numbers is unsafe, then demonstrates how to use a custom MyBatis TypeHandler to automatically encrypt data on insert and decrypt it on query, complete with code samples, configuration steps, and test results.
Background
In many databases, sensitive user information like phone numbers or bank cards is sometimes stored in plain text, which can be leaked if the database is compromised or data is exported by a departing employee.
Solution
Because the project uses MyBatis as the persistence layer, a custom TypeHandler is chosen to handle encryption and decryption of specific columns.
Implementation Steps
Define an entity class for encrypted values
public class Encrypt {
private String value;
public Encrypt() {}
public Encrypt(String value) { this.value = value; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}Implement the TypeHandler
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(Encrypt.class)
public class EncryptTypeHandler extends BaseTypeHandler<Encrypt> {
private static final byte[] KEYS = "12345678abcdefgh".getBytes(StandardCharsets.UTF_8);
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null || parameter.getValue() == null) {
ps.setString(i, null);
return;
}
AES aes = SecureUtil.aes(KEYS);
String encrypt = aes.encryptHex(parameter.getValue());
ps.setString(i, encrypt);
}
@Override
public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
return decrypt(rs.getString(columnName));
}
@Override
public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return decrypt(rs.getString(columnIndex));
}
@Override
public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return decrypt(cs.getString(columnIndex));
}
private Encrypt decrypt(String value) {
if (value == null) return null;
return new Encrypt(SecureUtil.aes(KEYS).decryptStr(value));
}
}Mapper XML configuration
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huan.study.mybatis.mappers.CustomerMapper">
<resultMap id="BaseResultMapper" type="com.huan.study.mybatis.entity.Customer">
<id column="id" property="id"/>
<result column="phone" property="phone"/>
<result column="address" property="address"/>
</resultMap>
<insert id="addCustomer">
INSERT INTO customer(phone, address) VALUES (#{phone}, #{address})
</insert>
<select id="findCustomer" resultMap="BaseResultMapper">
SELECT * FROM customer WHERE phone = #{phone}
</select>
</mapper>MyBatis configuration
mybatis.type-handlers-package = com.huan.study.mybatis.typehandlerService layer Provide methods to add a customer (the phone field is wrapped in Encrypt so it gets encrypted) and to query a customer by phone (the result is automatically decrypted).
Testing Results
After inserting a record, the phone column in the database contains an encrypted string. When querying the same record, MyBatis invokes the TypeHandler to decrypt the value, returning the original phone number.
Below are screenshots of the mapper XML and the test output confirming the encryption/decryption behavior.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
