问题遇到的现象和发生背景
在将List<>数据插入mysql json格式字段时,报错
Type handler was null on parameter mapping for property 'weekData'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.
使用mybatis,并用自定义的TypeHandler,报以上错误。
使用Mybatis-plus自带的typehandler,报以上错误。
问题相关代码,请勿粘贴截图
Card对象中的变量
private List<DailyData> weekData;
public List<DailyData> getWeekData() {
return weekData;
}
public void setWeekData(List<DailyData> weekData) {
this.weekData = weekData;
}
typeHandler
public class ListTypeHandler<T extends Object> implements TypeHandler<List<T>> {
private List<T> getListByJsonArrayString(String content) {
if (StringUtils.isEmpty(content)) {
return new ArrayList<>();
}
return JSON.parseObject(content, new TypeReference<ArrayList<T>>() {});
}
/**
* java转jdbcType
* @param preparedStatement
* @param i
* @param ts
* @param jdbcType
* @throws SQLException
*/
@Override
public void setParameter(PreparedStatement preparedStatement, int i, List<T> ts, JdbcType jdbcType) throws SQLException {
if (CollectionUtils.isEmpty(ts)) {
preparedStatement.setString(i, null);
} else {
preparedStatement.setString(i, JSON.toJSONString(ts));
}
}
@Override
public List<T> getResult(ResultSet resultSet, String s) throws SQLException {
return getListByJsonArrayString(resultSet.getString(s));
}
@Override
public List<T> getResult(ResultSet resultSet, int i) throws SQLException {
return getListByJsonArrayString(resultSet.getString(i));
}
@Override
public List<T> getResult(CallableStatement callableStatement, int i) throws SQLException {
return getListByJsonArrayString(callableStatement.getString(i));
}
}
CardMapper.xml
<resultMap type="Card" id="CardResult">
<id property="id" column="id" />
<result property="weekNum" column="week_num" />
<result property="startDate" column="start_date" />
<result property="endDate" column="end_date" />
<result property="weekData" column="week_data" javaType="DailData" jdbcType="OTHER" typeHandler="com.leo.framework.config.ListTypeHandler" />
<result property="flowStatus" column="flow_status" />
<result property="flowChecker" column="flow_checker" />
<result property="createTime" column="create_time" />
<result property="personCode" column="person_code" />
</resultMap>
<sql id="selectCard">
select c.id, c.week_num, c.start_date, c.end_date, c.week_data, c.flow_status, c.flow_checker, c.create_time, c.person_code
from rsh_card c
</sql>
<select id="selectCardList" parameterType="Card" resultMap="CardResult">
<include refid="selectCard"/>
<where>
<if test="id != null and id != ''">
AND id = ${id}
</if>
<if test="weekNum != null and weekNum > 0">
AND week_num = #{weekNum}
</if>
<if test="personCode != null and personCode != ''">
AND person_code = #{personCode}
</if>
</where>
<!-- 数据范围过滤 -->
${params.dataScope}
</select>
mybatis-config.xml
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
<typeHandlers>
<typeHandler handler="com.leo.framework.config.ListTypeHandler" />
</typeHandlers>
application.yml
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.leo.project.**.domain
mapperLocations: classpath:mybatis/**/*Mapper.xml
configLocation: classpath:mybatis/mybatis-config.xml
type-handlers-package: com.leo.framework.config
MybatisConfig.java中的sqlSessionFactory
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
}
运行结果及报错内容
Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'weekData'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.
at org.apache.ibatis.mapping.ParameterMapping$Builder.validate(ParameterMapping.java:119)
at org.apache.ibatis.mapping.ParameterMapping$Builder.build(ParameterMapping.java:104)
at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.buildParameterMapping(SqlSourceBuilder.java:143)
at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.handleToken(SqlSourceBuilder.java:87)
at org.apache.ibatis.parsing.GenericTokenParser.parse(GenericTokenParser.java:77)
at org.apache.ibatis.builder.SqlSourceBuilder.parse(SqlSourceBuilder.java:50)
at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:42)
at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:305)
at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:64)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:41)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:658)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64)
at com.sun.proxy.$Proxy190.update(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194)
请问改异常如何处理