纪念一次由setter,getter致使JSON.toJSONString()丢失部分字段的坑

工作中遇到的问题随笔:

  • 1、问题的复现,字段丢失
  • 2、问题分析,查找原因
  • 3、找到原因,粗略剖析

1、问题的复现,字段丢失

这是一个比较老的项目,使用了fast-json-1.1.28.jar。在一次实际使用中,列表中始终无法显示其中2个字段,所以一步一步进行问题排查。

  • 1.使用debugger查看查询结果集,查询结果有值,说明sql,DAO层,service层都没有错。

    这里写图片描述

  • 2.查看发送到页面的json数据,通过日志查看,在经过JSON.toJSONString()的时候,这两个值丢了。

这里写图片描述

2、问题分析,查找原因

经过上面的排查,大概找到原因是,json转换字符串的时候,把这个字段弄丢了

  • 1.会不会是类型的问题?

       这个字段的类型是 Double的类型, 还有其他字段是Double的,比如上图中的sumRecord也是Double类型,在转换之后没丢,看来不是类型的问题。

  • 2.灵光乍现,会不会是没找到getter方法?

       虽然没有读过fastjson的源码,但是推测了应该是是用了反射,调用对象的getter方法取值,前往检查getter方法,查完感觉问题很有可能出现在这。 我的setter,getter方法用的MyEclipse自动生成,fScores的getter,自动生成的名为:getfScores(),这显然和平常的不一样。

这里写图片描述

  • 3.修改代码,再次检查,结果是如预期一样,问题解决了。

    这里写图片描述

3、找到原因,粗略剖析

因为我是使用了MyEclipse自动生成的setter,getter,工具应该严格遵守着一套命名规范,我应该再去查找学习学习。

  • 感慨

       在我以前的认知中, java的变量,都是驼峰命名,如:helloWorld,那么它生成的setter,getter方法就是,setHelloWorld(),getHelloWorld()。hWorld这样生成的时候,h不大写,依然小写。还有以前也了解过,is开头的setter,getter,是isSuccess()和getSuccess()。 有另类就有差异,有差异就会发生一些莫名其妙的问题,写写博客,记录一些自己遇到的莫名奇妙的问题,一点点进步,学习的道路孤独而坎坷,踽踽而行。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果 MySQL 数据库中某字段JSON 类型,且返回的是 JSON 对象数组,那么在 MyBatis 中需要进行特殊的处理。一般情况下,我们可以使用 `@Result` 注解或 `<result>` 标签来对查询结果进行映射,但是这种方式对于 JSON 对象数组来说并不适用。 针对这种情况,可以使用 MyBatis 的 `TypeHandler` 接口来自定义类型处理器,将 JSON 字符串转化为 Java 对象。具体步骤如下: 1. 创建一个实体类,用于存储 JSON 对象数组的数据。 ```java public class MyJsonArray { private List<MyJsonObject> jsonArray; // gettersetter 方法省略 } ``` 2. 创建一个 `TypeHandler` 接口的实现类,用于将 JSON 字符串转化为 `MyJsonArray` 对象。代码如下: ```java public class MyJsonArrayTypeHandler extends BaseTypeHandler<MyJsonArray> { @Override public void setNonNullParameter(PreparedStatement ps, int i, MyJsonArray parameter, JdbcType jdbcType) throws SQLException { // 将 MyJsonArray 对象转化为 JSON 字符串,并设置到 PreparedStatement 中 ps.setString(i, JSON.toJSONString(parameter.getJsonArray())); } @Override public MyJsonArray getNullableResult(ResultSet rs, String columnName) throws SQLException { // 从 ResultSet 中获取 JSON 字符串,并将其转化为 MyJsonArray 对象 return parseJson(rs.getString(columnName)); } @Override public MyJsonArray getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // 从 ResultSet 中获取 JSON 字符串,并将其转化为 MyJsonArray 对象 return parseJson(rs.getString(columnIndex)); } @Override public MyJsonArray getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // 从 CallableStatement 中获取 JSON 字符串,并将其转化为 MyJsonArray 对象 return parseJson(cs.getString(columnIndex)); } private MyJsonArray parseJson(String jsonString) { // 将 JSON 字符串转化为 MyJsonArray 对象 if (StringUtils.isEmpty(jsonString)) { return null; } return JSON.parseObject(jsonString, MyJsonArray.class); } } ``` 3. 在实体类的 `resultMap` 中,使用 `typeHandler` 属性指定刚才创建的 `MyJsonArrayTypeHandler` 类型处理器。代码如下: ```xml <resultMap id="myResultMap" type="com.example.MyEntity"> <id property="id" column="id" /> <result property="jsonArray" column="json_column" javaType="com.example.MyJsonArray" typeHandler="com.example.MyJsonArrayTypeHandler" /> </resultMap> ``` 这样就可以将 MySQL 中的 JSON 对象数组映射到 Java 对象中了。需要注意的是,如果 JSON 对象数组中的元素类型不一致,需要在 `MyJsonArray` 类中定义多个字段来存储不同类型的元素。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值