How to Mask Sensitive Data in MySQL and Java with MyBatis‑Mate
This article demonstrates practical techniques for data masking, covering MySQL string functions for phone and ID masking, a Java library for various sensitive fields, and a MyBatis‑Mate extension that applies custom and built‑in masking strategies through annotations and REST endpoints.
1. SQL Data Masking Implementation
Shows how to mask phone numbers and ID cards using MySQL string functions CONCAT, LEFT and RIGHT.
SELECT mobilePhone AS original_phone,
CONCAT(LEFT(mobilePhone,3), '********') AS masked_phone
FROM t_s_user;
SELECT idcard AS original_idcard,
CONCAT(LEFT(idcard,3), '****', RIGHT(idcard,4)) AS masked_idcard
FROM t_s_user;2. Java Data Masking Implementation
References the open‑source sensitive-plus library, which supports masking of address, bank card, Chinese name, landline, ID card, mobile, password, etc., using regular‑expression or length‑based strategies.
3. mybatis‑mate‑sensitive‑jackson
Provides a MyBatis‑Mate extension that applies masking strategies defined by SensitiveType or custom strategies.
package mybatis.mate.strategy;
public interface SensitiveType {
String chineseName = "chineseName";
String idCard = "idCard";
String phone = "phone";
String mobile = "mobile";
String address = "address";
String email = "email";
String bankCard = "bankCard";
String password = "password";
String carNumber = "carNumber";
}Configuration class registers a custom strategy named testStrategy.
@Configuration
public class SensitiveStrategyConfig {
@Bean
public ISensitiveStrategy sensitiveStrategy() {
return new SensitiveStrategy()
.addStrategy("testStrategy", t -> t + "***test***");
}
}Entity class User uses @FieldSensitive to mark fields for masking.
@Getter @Setter
public class User {
private Long id;
@FieldSensitive("testStrategy")
private String username;
@FieldSensitive(SensitiveType.mobile)
private String mobile;
@FieldSensitive(SensitiveType.email)
private String email;
}Controller demonstrates three endpoints: /info returns a single masked user. /map returns a map containing a user object and manually masked values. /list returns a list of users; adding query parameter skip=1 disables masking.
@RestController
public class UserController {
@Autowired private UserMapper userMapper;
@Autowired private ISensitiveStrategy sensitiveStrategy;
@GetMapping("/info")
public User info() {
return userMapper.selectById(1L);
}
@GetMapping("/map")
public Map<String,Object> map() {
Map<String,Object> userMap = new HashMap<>();
userMap.put("user", userMapper.selectById(1L));
userMap.put("mobile", sensitiveStrategy.getStrategyFunctionMap()
.get(SensitiveType.mobile).apply("15315388888"));
return userMap;
}
@GetMapping("/list")
public List<User> list(HttpServletRequest request) {
if ("1".equals(request.getParameter("skip"))) {
RequestDataTransfer.skipSensitive();
}
return userMapper.selectList(null);
}
}Sample JSON responses show masked usernames (e.g., "Jone***test***"), masked mobile numbers (e.g., "153******81") and partially hidden email addresses.
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
