MyBatis3自定义typeHandlers
mybatis3中默认了标准的java类型的typeHandlers,对枚举类型也内置了一个叫EnumTypeHandler的处理器,但是有一个问题,如果在数据库里面的字段类型是SMALLINT、TYININT、INTEGER等数据类型,默认的EnumTypeHandler就不能处理了,http://asialee.iteye.com/blog/1013238,这个地方有比较详细的说明。解决这个问题有两种方法,一是修改数据库字段的类型为枚举类型,并且枚举值用字符表示;另外一种方法就是自己实现一个typeHandlers。实现的方法很简单,官方的手册上就一个例子。配置的时候需要注意,不光只在 MapperConfig.xml 配置
<typeHandlers> <typeHandler javaType="String" jdbcType="VARCHAR" handler="org.mybatis.example.ExampleTypeHandler"/> </typeHandlers>
还需要在对应的字段在resultMap中配置jdbcType属性,而且select的返回结果类型不能使用resultType,必须用resultMap,否则mybatis就无法应用用自定义的typeHandlers。为何一定要配置jdbcType呢?因为MyBatis为POJO中字段设置typeHandlers是根据在javaType和jdbcType来确定的,javaType可以根据POJO来获取,MyBatis不会审视数据库元信息来决定jdbcType,如果没有指定,那么都是按null来处理,因而获取typeHandlers通过javaType了,就算在MapperConfig.xml中配置的全局typeHandlers也无法正确应用。
另外一种配置是直接在resultMap中指定对应字段的typeHandlers,这样可以不在MapperConfig.xml配置typeHandlers和设置jdbcType。
官方文档中有如下说明:
使用这样的类型处理器将会覆盖已经存在的处理Java的String类型属性和VARCHAR参数及结果的类型处理器。要注意MyBatis不会审视数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指定那是VARCHAR类型的字段,来绑定到正确的类型处理器上。这是因为MyBatis直到语句被执行都不知道数据类型的这个现实导致的。
由于没有很好的理解“不会审视数据库元信息来决定使用哪种类型”导致走了很多弯路,一直无法使用自定义的typehandler。