Spring Data JdbcTemplate向MySQL JSON列存入POJO的正确实践是什么?
POJO存入MySQL JSON列的正确方案
直接传POJO报错的核心原因:Spring JDBC默认未提供POJO到MySQL JSON类型的自动转换逻辑,JDBC驱动无法识别自定义Java对象对应的SQL类型,因此抛出类型不匹配错误。
下面分场景给出最优实现方案:
方案1:单次调用快速实现(无需全局配置)
通过Spring提供的AbstractSqlTypeValue显式指定参数类型,适合偶尔需要存JSON的场景:
import org.springframework.jdbc.core.support.AbstractSqlTypeValue; import java.sql.Types; mapSqlParameterSource.addValue("someJsonColumn", new AbstractSqlTypeValue() { @Override protected Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException { return _objectMapper.writeValueAsString(somePOJO); } }, Types.JSON, "json");
如果使用MySQL 8.0+官方驱动,还可以简化为直接指定SQL类型:
mapSqlParameterSource.addValue("someJsonColumn", _objectMapper.writeValueAsString(somePOJO), Types.JSON);
该方案和直接传字符串的原始写法区别是:会明确告知JDBC驱动该参数对应JSON列类型,驱动会自动做格式校验、编码优化,避免普通字符串存入JSON列的潜在兼容性问题。
方案2:全局配置实现直接传POJO(推荐高频场景使用)
配置全局类型转换器后,就可以直接调用mapSqlParameterSource.addValue("someJsonColumn", somePOJO)完成写入,无需每次手动序列化:
- 首先实现POJO到JSON字符串的转换器:
import org.springframework.core.convert.converter.Converter; import com.fasterxml.jackson.databind.ObjectMapper; public class PojoToJsonConverter implements Converter<Object, String> { private final ObjectMapper objectMapper; public PojoToJsonConverter(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } @Override public String convert(Object source) { try { return objectMapper.writeValueAsString(source); } catch (Exception e) { throw new IllegalArgumentException("JSON序列化失败", e); } } }
- 将转换器注册到Spring转换服务中,同时配置
NamedParameterJdbcTemplate的参数源工厂使用该转换服务,并且添加列类型映射,将JSON列对应的SQL类型指定为Types.JSON,配置完成后即可直接传入POJO写入JSON列。
方案3:MyBatis场景(如果使用MyBatis框架)
自定义JsonTypeHandler,在POJO对应的字段上添加@TypeHandler(JsonTypeHandler.class)注解,或者在全局配置中注册该类型处理器,即可自动完成POJO和JSON列的互相转换。
内容的提问来源于stack exchange,提问作者wxh
相关产品推荐
相关产品推荐

