Pracowałem nad tym pytaniem z kilku stron i oto moje ustalenia. Zastrzeżenie:wszystkie te badania przeprowadziłem za pomocą MyBatis-3.1.1, więc rzeczy mogły zachowywać się inaczej we wcześniejszych wersjach.
Po pierwsze, MyBatis ma wbudowany EnumTypeHandler
. Domyślnie za każdym razem, gdy określasz wyliczenie Java jako typ wyniku lub typ parametru, ten typ będzie obsługiwał ten typ. W przypadku zapytań, podczas próby konwersji rekordu bazy danych na wyliczenie Java, EnumTypeHandler pobiera tylko jeden argument i próbuje wyszukać wartość wyliczenia Java, która odpowiada tej wartości.
Lepiej zilustruje to przykład. Załóżmy, że powyższe zapytanie zwraca 2
i "Ready"
kiedy przekazuję "Gotowy" jako argument. W takim przypadku otrzymuję komunikat o błędzie No enum constant com.foo.Status.2
. Jeśli odwrócę kolejność instrukcji SELECT na
SELECT ls.name, ls.id
komunikat o błędzie to No enum constant com.foo.Status.Ready
. Zakładam, że możesz wywnioskować, co robi MyBatis. Zauważ, że EnumTypeHandler ignoruje drugą wartość zwróconą z zapytania.
Zmiana zapytania na
SELECT UPPER(ls.name)
powoduje to, że działa:zwracane jest wyliczenie Status.READY.
Następnie spróbowałem zdefiniować własny TypeHandler dla wyliczenia Status. Niestety, tak jak w przypadku domyślnego EnumTypeHandler
, mogłem uzyskać tylko jedną z wartości (id lub name), aby odwołać się do właściwego Enum, a nie obu. Więc jeśli identyfikator bazy danych nie pasuje do wartości, którą zakodowałeś powyżej, będziesz mieć niezgodność. Jeśli upewnisz się, że identyfikator bazy danych zawsze jest zgodny z identyfikatorem określonym w wyliczeniu, wszystko, czego potrzebujesz z bazy danych, to nazwa (przekonwertowana na wielkie litery).
Potem pomyślałem, że zrobię się sprytny i zaimplementuję obiekt MyBatis ObjectFactory, pobierz zarówno int id, jak i nazwę String i upewnię się, że są one dopasowane w wyliczeniu Java, które przekazuję z powrotem, ale to nie zadziałało, ponieważ MyBatis nie wywołuje ObjectFactory w celu Typ wyliczenia Java (przynajmniej nie mogłem go uruchomić).
Więc mój wniosek jest taki, że wyliczenia Java w MyBatis są łatwe, o ile wystarczy dopasować nazwę z bazy danych do nazwy stałej wyliczenia - albo użyj wbudowanego EnumTypeHandler lub zdefiniuj własne, jeśli robisz UPPER(name) w SQL nie wystarcza do dopasowania nazw wyliczenia Java. W wielu przypadkach jest to wystarczające, ponieważ wyliczona wartość może być tylko ograniczeniem sprawdzającym w kolumnie i ma tylko pojedynczą wartość, a nie identyfikator. Jeśli chcesz również dopasować int id, a także nazwę, dopasuj identyfikatory ręcznie podczas konfigurowania wyliczenia Java i/lub wpisów w bazie danych.
Na koniec, jeśli chcesz zobaczyć działający przykład tego, zobacz koan 23 moich koanów MyBatis tutaj:https://github.com/midpeter444/mybatis-koans . Jeśli chcesz tylko zobaczyć moje rozwiązanie, zajrzyj do katalogu complete-koans/koan23. Mam tam również przykład wstawiania rekordu do bazy danych za pomocą wyliczenia Java.