I feel like this is a simple problem, but none of the things i tried work for me. I have an enum, the reason i have string constructor is because Java doesn't allow enum to be numerical..I tried AA, AB, 2C directly without string constructor but that gives an error. Note that for the existing enum i am adding C("2C").
public enum TestEnum{
AA("AA"), AB("AB"), C("2C");
private String display;
private TestEnum( String display ) {
this.display = display;
}
public String toString() {
return display;
}
public String getDisplay() {
return display;
}
public void setDisplay( String display ) {
this.display = display;
}
public String getName() {
return display;
}
Now i have a mybatis mapper which does a merge this is existing and one of the param to the mapper is TestEnum. Until now this worked fine since enum value and string value are same, but i added C("2C"). Now i want to insert 2C to the table using mybaits, but it always inserts C.
merge into text t
using (select #{id} as id from dual) d on (d.id = t.id)
when matched then
update set
appId = #{applId},
src = #{testEnum}
testEnum inserts C, so i changed that to #{testEnum.toString()} which gave me a there is no getter for property name toString() error. I tried #{testEnum.display} and #{testEnum.name} both of them still inserts C whereas i want it to insert 2C. Do you guys know an easier way of handling this?
I don't want to change the model object to pass String rather than TestEnum because this object is being used in many places.Is there a way this can be done in the mybatis mapper without changing model object?
Thanks for your help :)
What you need is a TypeHandler
First, add a static method to your
TestEnum
to return aTestEnum
given a display string:Then use it to create your TypeHandler:
Finally, register your TypeHandler in your mybatis xml:
You do not need to write any custom
TypeHandler
if you want to insert the value of your Enum.The only one thing you need to do is to specify the getter method's name in your MyBatis insert.
Example:
SQL:
MyBatis mapper:
And the Java Enum:
In your case you can use
src = #{testEnum.display}
in your SQL.In addition to @Malt Answer:
The reason why what you are trying doesn't works it's the MyBatis
EnumTypeHandler
by default setsname()
value of the method and is marked withfinal
so you cannot override it:EnumTypeHandler.class (Line 38 to 44):
Otherwise, the enum is created from the method
valueOf(type, name)
which also uses the name of the enum.So definitely, you need to use a typeHandler specific to handle your enum which has a specific behaviour, but I would
extends
directlyEnumTypeHandler
in specific enum type handlers, instead ofBaseTypeHandler
(Malt answer), because you could reuse some functionality (not in your case, but maybe in others) so it handles a general enum behaviour.