项目中经常会遇到一些PO类中的某个字段的取值范围范围是一组固定的值,为了方便期间使用了number来存储这些值。这样会带来的一个问题,当我创建一个PO对象时,这个字段怎么赋值,应该有那些值?通常我们会提供一个enum来维护这个字段的取值范围,随之而来的问题当项目中enum越来越多,或者文档没有更新的情况下,开发人员很难知道,这个字段是不是有enum与之对应,或者是哪个enum与之对应。很多时候我们知道有几种值,我们随手就赋值了一个字面常量值。这就可能出现了莫名其妙的类型。最直接的解决方案,我们在PO字段上直接声明enum类型,就完全避开了错误使用值的情况。
MyBatis官网提供了两种方案,EnumTypeHandler
和EnumOrdinalTypeHandler
。EnumTypeHandler在数据库中使用VARCHAR
存储enum的名字。EnumOrdinalTypeHandler
在数据库使用NUMBER
或DOUBLE
存储enum的索引。
我们更想的是在表中存储NUMBER
类型,所以EnumOrdinalTypeHandler
更适合我们的需求。EnumOrdinalTypeHandler
存储是enum的索引,但是如果我们在enum中想使用自己的code,而不是enum本身的索引,要怎么去做呢?根据MyBatis官网文档我们可以自定义类型处理器来试下,下面是自定义处理器的使用方法。
既然我们的目的是想使用自定义的code存储到表中,所以首先我们应该强制我们的enum类型应该有对应的code字段,我们通过在enum中实现接口来实现。
1 | public interface EnumCode { |
上面我们定义了一个接口EnumCode
它值定义了一个方法就是返回code
。在我们的enum中实现该接口
1 | public enum PlatformEnum implements EnumCode { |
接下来就是实现类型处理器,代码如下:
1 | public class EnumCodeTypeHandler extends BaseTypeHandler<EnumCode> { |
以上就完成我们自定义的类型处理器。接下来就看看我们如果在xml中使用类型处理器:
1 | <resultMap> |
在声明resultMap
和进行插入、修改时使用上面形式就可以了。
还有一种比较常用的情况,如果在where语句中使用enum,而不是通过方法传入值该怎么处理?
这种情况我也搞了很久,查了很多资料,终于找到对应的方案…
1 | token_type = ${@cn.xxx.TokenTypeEnum@ACCESS.getCode()} |
使用OGNL
表达式就可以了。