Mysql
 sql >> Database >  >> RDS >> Mysql

Utilizzo dell'enumerazione di MyBatis

Ho lavorato su questa domanda da un paio di angolazioni e qui ci sono i miei risultati. Avvertenza:ho eseguito tutte queste indagini utilizzando MyBatis-3.1.1, quindi le cose avrebbero potuto comportarsi diversamente nelle versioni precedenti.

Innanzitutto, MyBatis ha un EnumTypeHandler integrato . Per impostazione predefinita, ogni volta che specifichi un enum Java come resultType o parameterType, questo è ciò che gestirà quel tipo. Per le query, quando si tenta di convertire un record di database in un enum Java, EnumTypeHandler accetta solo un argomento e tenta di cercare il valore enum Java che corrisponde a quel valore.

Un esempio illustrerà meglio. Supponiamo che la tua query sopra restituisca 2 e "Ready" quando passo "Pronto" come argomento. In tal caso, viene visualizzato il messaggio di errore No enum constant com.foo.Status.2 . Se inverto l'ordine della tua istruzione SELECT in modo che sia

SELECT ls.name, ls.id

quindi il messaggio di errore è No enum constant com.foo.Status.Ready . Presumo che tu possa dedurre cosa sta facendo MyBatis. Si noti che EnumTypeHandler sta ignorando il secondo valore restituito dalla query.

Modificare la query in

SELECT UPPER(ls.name)

fa funzionare:viene restituita l'enum Status.READY.

Quindi ho provato a definire il mio TypeHandler per lo Status enum. Sfortunatamente, come con il EnumTypeHandler predefinito , ho potuto ottenere solo uno dei valori (id o name) per fare riferimento all'Enum corretto, non a entrambi. Quindi, se l'ID del database non corrisponde al valore che hai codificato in precedenza, avrai una mancata corrispondenza. Se ti assicuri che l'id del database corrisponda sempre all'id specificato nell'enumerazione, tutto ciò che ti serve dal database è il nome (convertito in maiuscolo).

Quindi ho pensato di diventare intelligente e implementare un MyBatis ObjectFactory, prendere sia l'ID int che il nome String e assicurarmi che siano abbinati nell'enumerazione Java che passo indietro, ma ciò non ha funzionato poiché MyBatis non chiama ObjectFactory per un Tipo enum Java (almeno non sono riuscito a farlo funzionare).

Quindi la mia conclusione è che le enumerazioni Java in MyBatis sono facili fintanto che devi solo abbinare il nome dal database al nome della costante enum - usa l'EnumTypeHandler integrato o definisci il tuo se stai facendo UPPER(nome) nel SQL non è sufficiente per abbinare i nomi enum Java. In molti casi, questo è sufficiente, poiché il valore enumerato potrebbe essere solo un vincolo di controllo su una colonna e ha solo il valore singolo, non anche un id. Se è necessario abbinare anche un int id oltre a un nome, fare in modo che gli ID corrispondano manualmente durante l'impostazione dell'enumerazione Java e/o delle voci del database.

Infine, se desideri vedere un esempio funzionante di questo, vedi koan 23 dei miei koan MyBatis qui:https://github.com/midpeter444/mybatis-koans . Se vuoi solo vedere la mia soluzione, guarda nella directory complete-koans/koan23. Ho anche un esempio di inserimento di un record nel database tramite un enum Java.