Zpracoval jsem tuto otázku z několika úhlů a zde jsou moje zjištění. Upozornění:Všechna tato vyšetřování jsem provedl pomocí MyBatis-3.1.1, takže se věci v dřívějších verzích mohly chovat jinak.
Za prvé, MyBatis má vestavěný EnumTypeHandler
. Ve výchozím nastavení, kdykoli zadáte výčet Java jako resultType nebo parameterType, zpracuje tento typ právě toto. U dotazů při pokusu o převod databázového záznamu na Java enum EnumTypeHandler vezme pouze jeden argument a pokusí se vyhledat hodnotu Java enum, která této hodnotě odpovídá.
Lépe to ilustruje příklad. Předpokládejme, že váš dotaz výše vrátí 2
a "Ready"
když předám jako argument "Připraveno". V takovém případě se mi zobrazí chybová zpráva No enum constant com.foo.Status.2
. Pokud změním pořadí vašeho příkazu SELECT na
SELECT ls.name, ls.id
pak je chybová zpráva No enum constant com.foo.Status.Ready
. Předpokládám, že můžete odvodit, co dělá MyBatis. Všimněte si, že EnumTypeHandler ignoruje druhou hodnotu vrácenou z dotazu.
Změna dotazu na
SELECT UPPER(ls.name)
způsobí, že bude fungovat:vrátí se výčet Status.READY.
Dále jsem se pokusil definovat svůj vlastní TypeHandler pro stavový výčet. Bohužel, stejně jako u výchozího EnumTypeHandler
, mohl jsem získat pouze jednu z hodnot (id nebo jméno), abych mohl odkazovat na správné Enum, ne na obě. Pokud se tedy ID databáze neshoduje s hodnotou, kterou jste napevno zakódovali výše, budete mít nesoulad. Pokud zajistíte, aby se ID databáze vždy shodovalo s ID, které zadáte ve výčtu, pak vše, co z databáze potřebujete, je název (převedený na velká písmena).
Pak jsem si řekl, že zbystřím a implementuji MyBatis ObjectFactory, vezmu jak int id, tak String name a zajistím, že se shodují ve výčtu Java, který předám zpět, ale to nefungovalo, protože MyBatis nevolá ObjectFactory pro Typ výčtu Java (alespoň já jsem ho nemohl zprovoznit).
Můj závěr je, že výčty Java v MyBatis jsou snadné, pokud stačí porovnat název z databáze s názvem konstanty výčtu – buď použijte vestavěný EnumTypeHandler, nebo definujte své vlastní, pokud uděláte UPPER(name) v SQL nestačí ke shodě s názvy výčtů Java. V mnoha případech to stačí, protože vyčíslená hodnota může být pouze kontrolním omezením na sloupci a má pouze jednu hodnotu, nikoli také id. Pokud potřebujete porovnat také int id a jméno, pak nastavte ID, aby se shodovala ručně při nastavování Java enum a/nebo záznamů databáze.
Nakonec, pokud byste chtěli vidět funkční příklad tohoto, podívejte se na koan 23 mých koanů MyBatis zde:https://github.com/midpeter444/mybatis-koans . Pokud chcete vidět moje řešení, podívejte se do adresáře Complete-koans/koan23. Mám tam také příklad vložení záznamu do databáze přes Java enum.