Here's how I do this.
I have an interface that I use for my enums:
public interface ValueEnum { Object getValue(); }
It looks like this to implement an enum that uses this:
public enum EmploymentTermReason implements ValueEnum { Voluntary("V"), Fired("F"), Retired("R"); private String value; private EmploymentTermReason(String value){ this.value = value; } public String getName(){ return name(); } public Object getValue() { return value; } }
The getName() method is just for the sake of reflection - blah.name will work for this enum now.
Next, I created an EnumTypeHandler annotation:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface EnumTypeHandler { Class enumClass(); int jdbcType(); }
Here's the implementation of that:
public class EnumTypeHandlerImpl implements TypeHandlerCallback { private int jdbcType; private Map<Object, Enum> map = new HashMap<Object, Enum>(); protected EnumTypeHandlerImpl() { if(this.getClass().isAnnotationPresent(EnumTypeHandler.class)){ EnumTypeHandler eth = this.getClass().getAnnotation(EnumTypeHandler.class); jdbcType = eth.jdbcType(); Class aClass = eth.enumClass(); for(Object o : aClass.getEnumConstants()){ Enum e = (Enum) o; ValueEnum v = (ValueEnum) o; Object value = v.getValue(); map.put(value, e); if(value instanceof String){ // special case, we want to use toString and value when reading... map.put(v.toString(), e); } } }else{ throw new RuntimeException("Must provide @EnumTypeHandler annotation."); } } public void setParameter(ParameterSetter parameterSetter, Object object) throws SQLException { if (object == null) { parameterSetter.setNull(jdbcType); } else { ValueEnum anEnum = (ValueEnum) object; parameterSetter.setObject(anEnum.getValue(), jdbcType); } } public Object valueOf(String string) { return string; } public Object getResult(ResultGetter resultGetter) throws SQLException { Object value = resultGetter.getObject(); if (resultGetter.wasNull()) { return null; } return map.get(value); } }
And a complete type handler:
@EnumTypeHandler(enumClass = EmploymentTermReason.class, jdbcType = Types.VARCHAR) public class EmploymentTermReasonTypeHandler extends EnumTypeHandlerImpl { }
Further enums simply implement the ValueEnum interface, then creating a type handler is simply a matter of extending the EnumTypeHandlerImpl class, providing the enumClass and jdbcType values, and registering the type handler in your iBATIS configuration.
