Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Verwendung von MyBatis-Enumerationen

Ich habe diese Frage aus verschiedenen Blickwinkeln bearbeitet, und hier sind meine Ergebnisse. Vorbehalt:Ich habe all diese Untersuchungen mit MyBatis-3.1.1 durchgeführt, daher könnten sich die Dinge in früheren Versionen anders verhalten haben.

Erstens hat MyBatis einen eingebauten EnumTypeHandler . Jedes Mal, wenn Sie eine Java-Enumeration als resultType oder parameterType angeben, wird dieser Typ standardmäßig von diesem behandelt. Wenn bei Abfragen versucht wird, einen Datenbankeintrag in eine Java-Enumeration umzuwandeln, nimmt der EnumTypeHandler nur ein Argument und versucht, den Java-Enumerationswert nachzuschlagen, der diesem Wert entspricht.

Ein Beispiel wird besser veranschaulichen. Angenommen, Ihre obige Abfrage gibt 2 zurück und "Ready" wenn ich "Ready" als Argument übergebe. In diesem Fall erhalte ich die Fehlermeldung No enum constant com.foo.Status.2 . Wenn ich die Reihenfolge Ihrer SELECT-Anweisung umkehre, um

zu sein
SELECT ls.name, ls.id

dann ist die Fehlermeldung No enum constant com.foo.Status.Ready . Ich nehme an, Sie können daraus schließen, was MyBatis tut. Beachten Sie, dass der EnumTypeHandler den zweiten von der Abfrage zurückgegebenen Wert ignoriert.

Ändern Sie Ihre Abfrage in

SELECT UPPER(ls.name)

bewirkt, dass es funktioniert:die Status.READY-Aufzählung wird zurückgegeben.

Also habe ich als nächstes versucht, meinen eigenen TypeHandler für die Status-Enumeration zu definieren. Leider wie beim Standard EnumTypeHandler , konnte ich nur einen der Werte (ID oder Name) erhalten, um auf die richtige Enum zu verweisen, nicht beide. Wenn also die Datenbank-ID nicht mit dem oben hartcodierten Wert übereinstimmt, liegt eine Diskrepanz vor. Wenn Sie sicherstellen, dass die Datenbank-ID immer mit der ID übereinstimmt, die Sie in der Aufzählung angeben, benötigen Sie aus der Datenbank nur den Namen (in Großbuchstaben umgewandelt).

Dann dachte ich, ich würde schlau werden und eine MyBatis ObjectFactory implementieren, sowohl die int id als auch den String-Namen holen und sicherstellen, dass diese in der Java-Enumeration, die ich zurückgebe, übereinstimmen, aber das hat nicht funktioniert, da MyBatis die ObjectFactory nicht für a aufruft Java-Enumerationstyp (zumindest konnte ich es nicht zum Laufen bringen).

Meine Schlussfolgerung ist also, dass Java-Enums in MyBatis einfach sind, solange Sie nur den Namen aus der Datenbank mit dem Namen der Enum-Konstante abgleichen müssen - verwenden Sie entweder den integrierten EnumTypeHandler oder definieren Sie Ihren eigenen, wenn Sie UPPER (Name) in verwenden SQL reicht nicht aus, um die Java-Enumerationsnamen abzugleichen. In vielen Fällen ist dies ausreichend, da der Aufzählungswert möglicherweise nur eine Check-Einschränkung für eine Spalte ist und nur den Einzelwert und keine ID enthält. Wenn Sie auch eine int-ID sowie einen Namen abgleichen müssen, dann passen Sie die IDs manuell an, wenn Sie die Java-Enumeration und/oder Datenbankeinträge einrichten.

Wenn Sie schließlich ein funktionierendes Beispiel dafür sehen möchten, sehen Sie sich Koan 23 meiner MyBatis-Koans hier an:https://github.com/midpeter444/mybatis-koans . Wenn Sie nur meine Lösung sehen möchten, schauen Sie im Verzeichnis complete-koans/koan23 nach. Ich habe dort auch ein Beispiel für das Einfügen eines Datensatzes in die Datenbank über eine Java-Enumeration.