Mysql
 sql >> Base de données >  >> RDS >> Mysql

Utilisation de l'énumération MyBatis

J'ai travaillé sur cette question sous plusieurs angles et voici mes conclusions. Mise en garde :J'ai effectué toutes ces investigations à l'aide de MyBatis-3.1.1, donc les choses auraient pu se comporter différemment dans les versions précédentes.

Tout d'abord, MyBatis a un EnumTypeHandler intégré . Par défaut, chaque fois que vous spécifiez une énumération Java en tant que resultType ou parameterType, c'est ce qui gérera ce type. Pour les requêtes, lorsque vous essayez de convertir un enregistrement de base de données en une énumération Java, EnumTypeHandler ne prend qu'un seul argument et essaie de rechercher la valeur d'énumération Java qui correspond à cette valeur.

Un exemple illustrera mieux. Supposons que votre requête ci-dessus renvoie 2 et "Ready" quand je passe dans "Ready" comme argument. Dans ce cas, j'obtiens le message d'erreur No enum constant com.foo.Status.2 . Si j'inverse l'ordre de votre instruction SELECT pour être

SELECT ls.name, ls.id

alors le message d'erreur est No enum constant com.foo.Status.Ready . Je suppose que vous pouvez déduire ce que fait MyBatis. Notez que EnumTypeHandler ignore la deuxième valeur renvoyée par la requête.

Changer votre requête en

SELECT UPPER(ls.name)

le fait fonctionner :l'énumération Status.READY est renvoyée.

Ensuite, j'ai essayé de définir mon propre TypeHandler pour l'énumération Status. Malheureusement, comme avec le EnumTypeHandler par défaut , je n'ai pu obtenir qu'une seule des valeurs (id ou nom) afin de référencer le bon Enum, pas les deux. Donc, si l'ID de la base de données ne correspond pas à la valeur que vous avez codée en dur ci-dessus, vous aurez une incompatibilité. Si vous vous assurez que l'ID de la base de données correspond toujours à l'ID que vous spécifiez dans l'énumération, alors tout ce dont vous avez besoin de la base de données est le nom (converti en majuscules).

Ensuite, j'ai pensé devenir intelligent et implémenter une MyBatis ObjectFactory, saisir à la fois l'int id et le nom de la chaîne et m'assurer qu'ils correspondent dans l'énumération Java que je renvoie, mais cela n'a pas fonctionné car MyBatis n'appelle pas l'ObjectFactory pour un Type d'énumération Java (du moins je n'ai pas pu le faire fonctionner).

Donc, ma conclusion est que les énumérations Java dans MyBatis sont faciles tant que vous avez juste besoin de faire correspondre le nom de la base de données au nom de la constante enum - soit utilisez le EnumTypeHandler intégré ou définissez le vôtre si vous faites UPPER(name) dans le SQL n'est pas suffisant pour faire correspondre les noms d'énumération Java. Dans de nombreux cas, cela suffit, car la valeur énumérée peut simplement être une contrainte de vérification sur une colonne et elle n'a qu'une seule valeur, pas un identifiant également. Si vous devez également faire correspondre un identifiant int ainsi qu'un nom, faites correspondre les identifiants manuellement lors de la configuration de l'énumération Java et/ou des entrées de base de données.

Enfin, si vous souhaitez voir un exemple concret de cela, consultez le koan 23 de mes koans MyBatis ici :https://github.com/midpeter444/mybatis-koans . Si vous voulez juste voir ma solution, regardez dans le répertoire filled-koans/koan23. J'ai également un exemple d'insertion d'un enregistrement dans la base de données via une énumération Java.