MyBatis中使用常量或枚举
常量替换
最近通过代码检查发现,咱们在MyBatis中涉及到一些常量值的用法均是将具体的值直接写在Mapper文件中了,例如:
    虽然在执行上没有什么问题,但是我还是推荐使用常量来代替这里硬代码,那具体如何做呢?一般情况咱们对一些常量定义方式类似:
    其实对于数值类型的字段常量,在Mapper文件中直接可以这样写:
${@dule.User@USER_STATE_ENABLED}
类的全路径及静态常量字段名前均以“@”开头,同时此处使用${}占位符方式即可(由于该字段值是由服务端常量赋值,不会产生注入漏洞)。但这种写法只允许是数值类型(字符串类型的数字也可以,后面你会知道为什么),如果是字符串常量的就稍微做下处理了,例如现在的常量修改为了:
    从上图可以看出常量的值并非数字,如果仍然按照上面的方法来进行替换则会抛出语法错
误,这是因为上述的替换方法拼出的SQL语句会将常量值直接字面性的拼在SQL语句中,例如:
INSERT INTO USER (USER_ID,..,USER_STATE)VALUES(#{userID},, ENABLED);
    那这种情况如何处理呢?你还记得为了模糊查询而使用的bind元素吗?道理一样:
枚举替换
    自从JDK1.5之后增加了枚举类型,这种类型非常适合表示常量值的,同时限定被调用的值范围,不会误输入错误的值,将隐患消灭在编译期间,其实我还是比较推荐使用枚举的,但如果是枚举上面的方法可行吗?是可行的,但是只能用于bind方式,而且最后“@”的并不是常量名,而是枚举元素名,MyBatis会将枚举元素的字面值当成字段值。
    那又有个问题了,如果我想使用枚举,但字段值又是数值时该如何做?其实对于MyBatis专门为枚举提供了两个类型处理器类:
org.pe.EnumTypeHandler<E>
org.pe.EnumOrdinalTypeHandler<E>
其中EnumOrdinalTypeHandler就是按照枚举元素的位置返回数值的,比如:
使用时,只要告诉MyBatis你的类型处理器及你的数据Java类型即可:
javaType:指定你数据对应的Java类型
typeHandler:指定你的类型处理器,这里我们用的是EnumOrdinalTypeHandler,因此你的javaType必须是一个枚举对象。(typeHandler也可以应用到resultMap的列映射元素上)
但是细心你的应该发现了,EnumOrdinalTypeHandler有个致命的问题,就是他是根据枚举元素的位置来决定值的,如果这时我打乱了枚举元素顺序或在中间插入了新的元素,就会导致枚举元素与数值的对应关系发生混乱,与数据库中保存的数值的状态完全混乱,因此必须小心谨慎使用。
程序的问题往往是解决一个问题接着有新的问题出现,如果我一定坚持要用枚举并且避免这种自然顺序作为值的问题呢?有办法吗?当然有,甚至你可以随意使用自定义的类型作为列值的类型处理器。只要你实现了org.pe.TypeHandler<T>接口,均可以配置在typeHandler属性中作为数据库与Java类型映射的处理对象。同时MyBatis提供了很多基础的TypeHandler实现,你可以基于他们进行扩展,这属于高级话题,有机会再慢慢聊~enum类型如何使用

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。