SpringBoot中MyBatis的TypeHandler相关报错汇总以及正确写法。Type handler was null、Class Not Found等情况

迁移之前的老项目的时候,老项目中使用了一些MyBatis的TypeHandler相关的东西。但是老项目并非写在mapper.xml文件里面,而是使用@Select注解,把SQL写在了一个Class中。
在改造的过程中,我将TypeHandler迁移到了xml文件中,然后报了一些错误,比如:

Type handler was null on parameter mapping for property 'xxx'.

再比如:

ClassNotFound:com.xxx.XXXTypeHandler

解决时间也不算太长,但是还是记录一下,方便出现这类问题的人或者自己下次使用。
其实不管出现什么问题,肯定是TypeHandler没有配置好,所以我们直接说一下MyBatis的TypeHandler要怎么配置。

  1. 先看一下需要用到TypeHandler的实体类:
@Data
public class MyConfig implements Serializable {
    private Long id;
    private DetailJson detail;
}
  1. 然后是TypeHandler类:
public class MyConfigDetailJsonHandler extends BaseTypeHandler {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, DetailJson parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSON.toJSONString(parameter));
    }
    @Override
    public DetailJson getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String string = rs.getString(columnName);
        if(StringUtils.isBlank(string) || !string.startsWith("{") || !string.endsWith("}")) {
            return null;
        }
        DetailJson javaObject = JSON.toJavaObject(JSON.parseObject((rs.getString(columnName))), DetailJson.class);
        return javaObject;
    }
    @Override
    public DetailJson getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }
    @Override
    public DetailJson getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }
}
  1. mapper.xml文件中的写法:
  • resultMap:

        
        

  • select:

  • insert:

    insert into my_config (id, detail)
    values (#{id,jdbcType=BIGINT}, #{detail,jdbcType=VARCHAR})

这里需要注意,TypeHandler只在resultMap中写就可以了,insert和update语句不需要写,否则会报错。
上述代码能简化就简化了,像select * 这种并不是提倡的写法。

  1. 配置数据库Factory的时候,把TypeHandler所在的路径配上,也可以直接配置TypeHandler类:
  • 配置TypeHandler路径:
@Primary
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    bean.setTypeHandlersPackage("com.abc.typehandler");
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
    return bean.getObject();
}
  • 直接配置TypeHandler:
@Primary
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    bean.setTypeHandlers(new MyConfigDetailJsonHandler());
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
    return bean.getObject();
}

你可能感兴趣的:(SpringBoot中MyBatis的TypeHandler相关报错汇总以及正确写法。Type handler was null、Class Not Found等情况)