Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Uso da enumeração MyBatis


Eu trabalhei nesta questão de alguns ângulos e aqui estão minhas descobertas. Advertência:Eu fiz todas essas investigações usando o MyBatis-3.1.1, então as coisas podem ter se comportado de forma diferente nas versões anteriores.

Primeiro, MyBatis tem um EnumTypeHandler embutido . Por padrão, sempre que você especificar uma enumeração Java como resultType ou parameterType, é isso que tratará esse tipo. Para consultas, ao tentar converter um registro de banco de dados em uma enumeração Java, o EnumTypeHandler recebe apenas um argumento e tenta pesquisar o valor da enumeração Java que corresponde a esse valor.

Um exemplo ilustrará melhor. Suponha que sua consulta acima retorne 2 e "Ready" quando passo "Ready" como argumento. Nesse caso, recebo a mensagem de erro No enum constant com.foo.Status.2 . Se eu inverter a ordem da sua instrução SELECT para ser
SELECT ls.name, ls.id

então a mensagem de erro é No enum constant com.foo.Status.Ready . Suponho que você possa inferir o que MyBatis está fazendo. Observe que o EnumTypeHandler está ignorando o segundo valor retornado da consulta.

Alterando sua consulta para
SELECT UPPER(ls.name)

faz com que funcione:a enumeração Status.READY é retornada.

Então, em seguida, tentei definir meu próprio TypeHandler para o Status enum. Infelizmente, assim como o padrão EnumTypeHandler , eu só poderia obter um dos valores (id ou name) para referenciar o Enum correto, não ambos. Portanto, se o ID do banco de dados não corresponder ao valor que você codificou acima, você terá uma incompatibilidade. Se você garantir que o id do banco de dados sempre corresponda ao id especificado na enumeração, tudo o que você precisa do banco de dados é o nome (convertido para maiúsculas).

Então eu pensei em ficar esperto e implementar um MyBatis ObjectFactory, pegar o int id e o nome da String e garantir que eles correspondam no Java enum que eu passo de volta, mas isso não funcionou, pois MyBatis não chama o ObjectFactory para um Java enum type (pelo menos não consegui fazê-lo funcionar).

Portanto, minha conclusão é que enums Java no MyBatis são fáceis, desde que você só precise corresponder o nome do banco de dados ao nome da constante enum - use o EnumTypeHandler integrado ou defina o seu próprio se estiver fazendo UPPER (name) no SQL não é suficiente para corresponder aos nomes de enumeração Java. Em muitos casos, isso é suficiente, pois o valor enumerado pode ser apenas uma restrição de verificação em uma coluna e possui apenas o valor único, não um id também. Se você também precisar corresponder um id int, bem como um nome, faça com que os IDs correspondam manualmente ao configurar a enumeração Java e/ou as entradas do banco de dados.

Finalmente, se você quiser ver um exemplo funcional disso, veja o koan 23 dos meus koans do MyBatis aqui:https://github.com/midpeter444/mybatis-koans . Se você quiser apenas ver minha solução, procure no diretório completed-koans/koan23. Eu também tenho um exemplo de inserção de um registro no banco de dados por meio de uma enumeração Java.