Tôi đã giải quyết câu hỏi này từ một số góc độ và đây là những phát hiện của tôi. Lưu ý:Tôi đã thực hiện tất cả các cuộc điều tra này bằng MyBatis-3.1.1, vì vậy mọi thứ có thể hoạt động khác trong các phiên bản trước đó.
Đầu tiên, MyBatis tích hợp sẵn EnumTypeHandler
. Theo mặc định, bất kỳ khi nào bạn chỉ định một enum Java là resultType hoặc tham sốType, đây là thứ sẽ xử lý kiểu đó. Đối với các truy vấn, khi cố gắng chuyển đổi một bản ghi cơ sở dữ liệu thành một Java enum, EnumTypeHandler chỉ nhận một đối số và cố gắng tìm kiếm giá trị Java enum tương ứng với giá trị đó.
Một ví dụ sẽ minh họa rõ hơn. Giả sử truy vấn của bạn ở trên trả về 2
và "Ready"
khi tôi chuyển vào "Sẵn sàng" làm đối số. Trong trường hợp đó, tôi nhận được thông báo lỗi No enum constant com.foo.Status.2
. Nếu tôi đảo ngược thứ tự câu lệnh SELECT của bạn thành
SELECT ls.name, ls.id
thì thông báo lỗi là No enum constant com.foo.Status.Ready
. Tôi giả sử bạn có thể suy ra MyBatis đang làm gì. Lưu ý rằng EnumTypeHandler đang bỏ qua giá trị thứ hai được trả về từ truy vấn.
Thay đổi truy vấn của bạn thành
SELECT UPPER(ls.name)
khiến nó hoạt động:enum Status.READY được trả về.
Vì vậy, tiếp theo, tôi đã cố gắng xác định TypeHandler của riêng mình cho enum Trạng thái. Thật không may, như với EnumTypeHandler
mặc định , Tôi chỉ có thể nhận một trong các giá trị (id hoặc tên) để tham chiếu đến Enum phù hợp, không phải cả hai. Vì vậy, nếu id cơ sở dữ liệu không khớp với giá trị bạn đã mã hóa cứng ở trên, thì bạn sẽ có một mã không khớp. Nếu bạn đảm bảo rằng id cơ sở dữ liệu luôn khớp với id bạn chỉ định trong enum, thì tất cả những gì bạn cần từ cơ sở dữ liệu là tên (được chuyển đổi thành chữ hoa).
Sau đó, tôi nghĩ rằng tôi sẽ thông minh và triển khai MyBatis ObjectFactory, lấy cả int id và String name và đảm bảo chúng khớp với nhau trong enum Java mà tôi trả lại, nhưng điều đó không hoạt động vì MyBatis không gọi ObjectFactory cho một Kiểu enum của Java (ít nhất là tôi không thể làm cho nó hoạt động được).
Vì vậy, kết luận của tôi là các enum Java trong MyBatis rất dễ dàng miễn là bạn chỉ cần khớp tên từ cơ sở dữ liệu với tên hằng enum - hoặc sử dụng EnumTypeHandler tích hợp sẵn hoặc định nghĩa của riêng bạn nếu thực hiện UPPER (tên) trong SQL không đủ để khớp với các tên enum Java. Trong nhiều trường hợp, điều này là đủ, vì giá trị được liệt kê có thể chỉ là một ràng buộc kiểm tra trên một cột và nó chỉ có một giá trị duy nhất, không phải là một id. Nếu bạn cũng cần đối sánh một id int cũng như một tên, thì hãy làm cho các ID đó khớp theo cách thủ công khi thiết lập các mục nhập Java enum và / hoặc cơ sở dữ liệu.
Cuối cùng, nếu bạn muốn xem một ví dụ hoạt động về điều này, hãy xem công án 23 trong số các công án MyBatis của tôi tại đây: https://github.com/midpeter444/mybatis-koans . Nếu bạn chỉ muốn xem giải pháp của tôi, hãy tìm trong thư mục complete-koans / koan23. Tôi cũng có một ví dụ ở đó về việc chèn một bản ghi vào cơ sở dữ liệu thông qua một enum Java.