mybatis自定义typeHandler
1、项目问题:
我们项目中有一个字段是存地址位置的,数据库采用自定义的类型,是一个多参数类型。该类型共又7个数字类型的字段,其中有4个是固定的,其中两个为2001,8307 ,另外两个为空。另外三个是保存x,y,z经纬度的值。
这种多值参数字段,mybatis会默认解析成Struct类型。但是如果一旦开启mybatis的缓存模式。项目就会报错。
为此,我去Github上mybatis项目组发了issue,得到了回答。
具体请看 :
https://github.com/mybatis/mybatis-3/issues/1152
2、如何实现并解决问题:
1)定义处理类型:
package com.wcs.wms.task.util.typehandler; import lombok.Getter; import lombok.Setter; import java.io.Serializable; import java.math.BigDecimal; import java.sql.SQLException; import java.sql.Struct; import java.util.List; @Getter @Setter public class StructType implements Serializable{ private static final long serialVersionUID = 7586786691581809590L; private BigDecimal taskSdoGtype; private BigDecimal taskSdosrid; private BigDecimal taskSdoPointX; private BigDecimal taskSdoPointY; private BigDecimal taskSdoPointZ; private List<BigDecimal> taskSdoOrdinates = null; private List<BigDecimal> taskSdoElemInfo = null; public StructType(){ } public StructType(Struct struct){ if(null != struct){ try { Object[] params = struct.getAttributes(); taskSdoGtype = (BigDecimal)params[0]; taskSdosrid = (BigDecimal) params[1]; if(params[2] != null){ Object[] geo = ((Struct) params[2]).getAttributes(); taskSdoPointX = (BigDecimal) geo[0]; taskSdoPointY = (BigDecimal) geo[1]; taskSdoPointZ = (BigDecimal) geo[2]; } } catch (SQLException e) { e.printStackTrace(); taskSdoGtype = null; taskSdosrid = null; taskSdoPointX = null; taskSdoPointY = null; taskSdoPointZ = null; } } } @Override public String toString() { return "StructType{" + "taskSdoGtype=" + taskSdoGtype + ", taskSdosrid=" + taskSdosrid + ", taskSdoPointX=" + taskSdoPointX + ", taskSdoPointY=" + taskSdoPointY + ", taskSdoPointZ=" + taskSdoPointZ + ", taskSdoOrdinates=" + taskSdoOrdinates + ", taskSdoElemInfo=" + taskSdoElemInfo + '}'; } }
2)自定义类型处理器:
package com.wcs.wms.task.util.typehandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import java.sql.*; public class StructTypeHandler implements TypeHandler<StructType> { public StructTypeHandler() { } @Override public void setParameter(PreparedStatement preparedStatement, int i, StructType struct, JdbcType jdbcType) throws SQLException { preparedStatement.setObject(i,struct); } @Override public StructType getResult(ResultSet resultSet, String columnName) throws SQLException { Object object = resultSet.getObject(columnName); if(object instanceof Struct){ return new StructType((Struct) object); } return null; } @Override public StructType getResult(ResultSet resultSet, int i) throws SQLException { Object object = resultSet.getObject(i); if(object instanceof Struct){ return new StructType((Struct) object); } return null; } @Override public StructType getResult(CallableStatement callableStatement, int i) throws SQLException { Object object = callableStatement.getObject(i); if(object instanceof Struct){ return new StructType((Struct) object); } return null; } }
3)配置类型处理器:
在mybatis-config.xml中添加:
<typeHandlers>
<typeHandler handler="com.wcs.wms.task.util.typehandler.StructTypeHandler" javaType="com.wcs.wms.task.util.typehandler.StructType"/>
</typeHandlers>
4)使用:
在对应的mapper.xml中指定自定义类型就可以了:
TASK_LOC_GEO = #{taskLocGeo,javaType=com.wcs.wms.task.util.typehandler.StructType,typeHandler=com.wcs.wms.task.util.typehandler.StructTypeHandler},
注意:此时我们的地址位置的字段已经是我们自定的类型了:
private StructType taskLocGeo;
测试,开启缓存。解决!
浙公网安备 33010602011771号