当前位置:   article > 正文

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

mybatis xml 找不到typehandler

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

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

再比如:

ClassNotFoundcom.xxx.XXXTypeHandler
  • 1

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

  1. 先看一下需要用到TypeHandler的实体类:
@Data
public class MyConfig implements Serializable {
	private Long id;
	private DetailJson detail;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 然后是TypeHandler类:
public class MyConfigDetailJsonHandler extends BaseTypeHandler<DetailJson> {
	@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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  1. mapper.xml文件中的写法:
  • resultMap:
<resultMap id="BaseResultMap" type="com.xxx.MyConfig">
        <id column="id" jdbcType="BIGINT" property="id"/>
        <result column="detail" jdbcType="VARCHAR" property="detail" typeHandler="com.abc.typehandler.MyConfigDetailJsonHandler"/>
</resultMap>
  • 1
  • 2
  • 3
  • 4
  • select:
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select *
    from my_config
    where id = #{id,jdbcType=BIGINT}
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • insert:
<insert id="insert" parameterType="com.xxx.MyConfig">
    insert into my_config (id, detail)
    values (#{id,jdbcType=BIGINT}, #{detail,jdbcType=VARCHAR})
</insert>
  • 1
  • 2
  • 3
  • 4

这里需要注意,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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 直接配置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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

喜欢本文的朋友不要忘记点一个免费的赞哦,你的赞将是我最大的动力。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/173059
推荐阅读
相关标签
  

闽ICP备14008679号