Giới thiệu
Trong quá trình học tập về MyBatis-Plus (viết tắt là MP), tôi đã gặp phải nhiều lỗi khi thực hiện theo hướng dẫn từ khóa học. Các công cụ hỗ trợ như Doubao và DS cũng không xác định được nguyên nhân của vấn đề này, vì vậy tôi đã ghi lại giải pháp tìm được. Tham khảo: https://blog.csdn.net/sgambler/article/details/106921634
Bộ xử lý kiểu JacksonTypeHandler chính thức
- Mục đích: Thay đổi một trường trong lớp thực thể vốn lưu trữ chuỗi JSON thành sử dụng kiểu tùy chỉnh để nhận JSON và tự động gán giá trị cho các trường tương ứng.
- Các bước thực hiện:
- Sử dụng chú thích
@TableFieldđể chỉ định kiểu chuyển đổi cho trường:
@TableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info;
- Trong
@TableName, chỉ định bật ánh xạ tập kết quả tự động (tự động chuyển đổi thuộc tính kiểu tùy chỉnh thành JSON khi hiển thị):
@TableName(value = "`user`", autoResultMap = true)
- Sử dụng
@AllArgsConstructor(staticName = "of")để chỉ định tên phương thức tĩnh cho phương thức khởi tạo đầy đủ tham số. - Cách trên không hoạt động! Với phiên bản MP 3.5.3, xuất hiện lỗi không thể ràng buộc kiểu Java với kiểu JDBC (không tìm thấy bộ xử lý):
Type handler was null on parameter mapping for property 'info'. It was either not specified and/or could not be found for the javaType (com.itheima.mp.domain.po.UserInfo) : jdbcType (null) combination.
Phỏng đoán là do trong JacksonTypeHandler chính thức, tham số được sử dụng trong chú thích @MappedTypes là Object.class thay vì UserInfo cụ thể.
Sau này đã được xác nhận, @MappedTypes cần chỉ định kiểu cụ thể, không thể sử dụng Object. Lý do chưa rõ.
Bộ xử lý kiểu tùy chỉnh UserDetailTypeHandler
- Tạo một bộ xử lý kiểu JSON tùy chỉnh
UserDetailTypeHandler, kế thừa từAbstractJsonTypeHandler<UserDetail>của MP. - Thêm chú thích
@MappedTypes({UserDetail.class}), lưu ý phải chỉ định kiểu cụ thể. - Thêm chú thích
@MappedJdbcTypes(JdbcType.VARCHAR)để chỉ định kiểu JDBC. - Ghi đè các phương thức
parsevàtoJson, sử dụng triển khai của Jackson ở đây. - Sau đó, thêm chú thích
@TableField(typeHandler = UserDetailTypeHandler.class)vào trường trong lớp thực thể cần chuyển đổi. - Mã code cụ thể:
UserDetailTypeHandler
@MappedTypes({UserDetail.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class UserDetailTypeHandler extends AbstractJsonTypeHandler<UserDetail> {
private static final JsonConverter converter = new JsonConverter();
@Override
protected UserDetail parse(String jsonData) {
try {
return converter.fromJson(jsonData, UserDetail.class);
} catch (Exception ex) {
throw new RuntimeException("Lỗi khi chuyển đổi JSON thành đối tượng", ex);
}
}
@Override
protected String toJson(UserDetail entity) {
try {
return converter.toJson(entity);
} catch (Exception ex) {
throw new RuntimeException("Lỗi khi chuyển đổi đối tượng thành JSON", ex);
}
}
}