Mybatis中自定义TypeHandler处理枚举详解
程序员文章站
2024-03-07 12:17:51
在mybatis中,处理枚举类的typehandler有两个:
enumtypehandler: 用于保存枚举名
enumordinaltypehandle...
在mybatis中,处理枚举类的typehandler有两个:
- enumtypehandler: 用于保存枚举名
- enumordinaltypehandler: 用于保存枚举的序号。
在实际项目中,以上往往不能满足我们的需求。
需求分析
枚举需要包含两个属性,label(用于显示), value(实际的枚举值)。数据库保存枚举值(value)。
这很明显mybatis提供的两个枚举typehandler不能满足我们的需求。此时,我们可以自定义一个通用的枚举typehandler来满足我们的需求。
自定义枚举typehandler
通用枚举displayedenum
public interface displayedenum { string default_value_name = "value"; string default_label_name = "label"; default integer getvalue() { field field = reflectionutils.findfield(this.getclass(), default_value_name); if (field == null) return null; try { field.setaccessible(true); return integer.parseint(field.get(this).tostring()); } catch (illegalaccessexception e) { throw new runtimeexception(e); } } @jsonvalue default string getlabel() { field field = reflectionutils.findfield(this.getclass(), default_label_name); if (field == null) return null; try { field.setaccessible(true); return field.get(this).tostring(); } catch (illegalaccessexception e) { throw new runtimeexception(e); } } static <t extends enum<t>> t valueofenum(class<t> enumclass, integer value) { if (value == null) throw new illegalargumentexception("displayedenum value should not be null"); if (enumclass.isassignablefrom(displayedenum.class)) throw new illegalargumentexception("illegal displayedenum type"); t[] enums = enumclass.getenumconstants(); for (t t: enums) { displayedenum displayedenum = (displayedenum)t; if (displayedenum.getvalue().equals(value)) return (t) displayedenum; } throw new illegalargumentexception("cannot parse integer: " + value + " to " + enumclass.getname()); } }
说明:
普通枚举类通过实现displayedenum接口,就可以:
- 通过getvalue()获取枚举值。
- 通过getlabel()获取枚举的label属性。
- 通过valueofenum()将integer值转换为指定的枚举类型。
普通枚举类
public enum commonstype implements displayedenum { normal("正常", 0), invalid("无效", 1); string label; integer value; private commonstype(string label, integer value) { this.label = label; this.value = value; } }
以上就是一个普通枚举类的示例。
自定义枚举typehandler
@mappedjdbctypes(value = jdbctype.tinyint, includenulljdbctype = true) public class defaultenumtypehandler extends basetypehandler<displayedenum> { private class<displayedenum> type; public enumtypehandler(){}; public enumtypehandler(class<displayedenum> type) { if (type == null) throw new illegalargumentexception("type argument cannot be null"); this.type = type; } @override public void setnonnullparameter(preparedstatement ps, int i, displayedenum parameter, jdbctype jdbctype) throws sqlexception { ps.setint(i, parameter.getvalue()); } @override public displayedenum getnullableresult(resultset rs, string columnname) throws sqlexception { return convert(rs.getint(columnname)); } @override public displayedenum getnullableresult(resultset rs, int columnindex) throws sqlexception { return convert(rs.getint(columnindex)); } @override public displayedenum getnullableresult(callablestatement cs, int columnindex) throws sqlexception { return convert(cs.getint(columnindex)); } private displayedenum convert(int status){ displayedenum[] objs = type.getenumconstants(); for(displayedenum em: objs){ if(em.getvalue() == status){ return em; } } return null; } }
使用我们自定义的defaultenumtypehandler
由于mybatis默认在处理枚举类型的时候会使用enumtypehandler(只保存及转换枚举类型的名字), 因此,我们需要手动指定使用defaultenumtypehandler。示例如下:
<resultmap id="xxx" type="xxx"> ... <result column="type" jdbctype="tinyint" property="type" typehandler="xxx.xxx.xxx.defaultenumtypehandler" /> ... </resultmap>
即我们需要通过使用typehandler来指定。
小结
以上是我们应用在实际项目中的一个对于mybatis处理枚举类的方案。我看大多数人也都是这样在用。然而,在实际项目中,我们会发现随着枚举类的增多,这样写起来会很繁琐。我看了一下网络上似乎也没人处理这种情况。那么,下一篇文章将针对这种情况进行处理。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!