【问题解决】Mybatis中使用net.sf.json.JSONObject接收数据库为null的数据时报错

项目场景:

使用SpringBoot+Mybatis+PostgreSQL搭建后端服务接口。
Mybatis接收数据库返回数据,resultType使用json作为接收容器。

control层

@Operation(summary = "地址数据")
    @GetMapping("/doorplate")
    public ResultResponse findByDoorplateExtent(@Parameter(description = "空间范围,组织为多边形坐标的形式,注意首尾坐标一致,例如POLYGON((112.20576805114746 30.367256514643596, 112.10380554199219 30.457256514643596, 112.10380554199219 30.39434753102366, 112.26576805114746 30.39434753102366, 112.20576805114746 30.367256514643596),(112.16049236297609 30.38571390562601, 112.22049236297609 30.414260761324122, 112.13951110839845 30.414260761324122, 112.13951110839845 30.44571390562601, 112.16049236297609 30.38571390562601))")String polygon){
        JSONObject obj = pointExtentService.findDoorplateByExtent(polygon);
        return ResultResponse.success(obj); }

server层

@Override
    public JSONObject findDoorplateByExtent(String polygon){
        JSONObject jsonObj = extentMapper.findDoorplateByExtent(polygon).getJSONObject("row_to_json");
        String value = jsonObj.getString("value");
        return JSONObject.fromObject(value);
    }

mapper层

	package com.example.toponym.mapper;
	import net.sf.json.JSONObject;
	public interface ExtentMapper {
	    JSONObject findDoorplateByExtent(String polygon);
	}

xml文件里的sql语句: 用于实现给定一个多边形空间范围查找对应范围内的目标结果。

<select id="findDoorplateByExtent" parameterType="String" resultType="net.sf.json.JSONObject">
   SELECT row_to_json ( fc ) FROM
	( SELECT 'FeatureCollection' AS TYPE, json_agg ( f ) AS features 
			FROM
		(SELECT 'Feature' AS TYPE,
			(SELECT row_to_json ( T ) 
				FROM
				(SELECT "uid","road") AS T ) AS properties,
			ST_AsGeoJSON ( "geometry" ) :: JSON AS geometry 
		FROM "T_S_DOORPLATE" WHERE
			ST_Intersects ( "geometry", ST_GeomFromText ( #{ POLYGON }, 4326 ) ) 
		) AS f 
	) AS fc
    </select>">

问题描述

存在当数据库中值为空的时候,报错:
在这里插入图片描述

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Object is null (through reference chain: 
com.example.toponym.model.ResultResponse["result"]
->net.sf.json.JSONObject["features"]->net.sf.json.JSONArray[3]->net.sf.json.JSONObject["properties"]
->net.sf.json.JSONObject["road"]->net.sf.json.JSONNull["empty"])

报错原因为:查询结果中,road字段有一个值为空值,返回的json数据中有属性为null的情况net.sf.json.JSONObject无法处理。

解决方案:

方案一:

引入fastjson依赖

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.66</version>
</dependency>

xml容器修改;同时mapper层引入fastjson

<select id="findDoorplateByExtent" parameterType="String" 
resultType="com.alibaba.fastjson.JSONObject">

方案二:

修改sql,设置默认值

应用场景:
当代码中使用net.sf.json.JSONObject过多,不便重构代码时。修改xml中sql语句的检索方式即可,当sql查询某个字段为空时赋新值。

pgsql函数:
NULLIF(value1,value2) :当value1 == value2时,返回null

COALESCE(col, ‘replacement’) :如果col列的值为null,则col的值将被替换为’replacement’

select COALESCE(NULLIF(trim(字段名), ''), '默认值') as 别称 from 表名

对比试验:
(1)普通select:
在这里插入图片描述
(2)使用COALESCE,将数据库中为null的值修改为‘null’字符串,使用as别名road(不使用as默认coalesce)
在这里插入图片描述
(3)使用COALESCE+NULLIF,当road==‘发展大道’&&road == null时,将数据库中的值修改为‘aaa’字符串
在这里插入图片描述
(4)注意:替换值要和字段值类型一致。
在这里插入图片描述

应用:
修改xml代码(同时添加了一些其他字段):

<select id="findDoorplateByExtent" parameterType="String" resultType="net.sf.json.JSONObject">
   SELECT row_to_json ( fc ) FROM
	( SELECT 'FeatureCollection' AS TYPE, json_agg ( f ) AS features 
			FROM
		(SELECT 'Feature' AS TYPE,
			(SELECT row_to_json ( T ) 
				FROM
				(SELECT "uid","district","township","village",
					COALESCE(road, 'null') as road,
					COALESCE(doorplate, 'null') as doorplate,
					COALESCE(doorplate_sub, 'null') as doorplate_sub
			     ) AS T ) AS properties,
			ST_AsGeoJSON ( "geometry" ) :: JSON AS geometry 
		FROM "T_S_DOORPLATE" WHERE
			ST_Intersects ( "geometry", ST_GeomFromText ( #{ POLYGON }, 4326 ) ) 
		) AS f 
	) AS fc
    </select>">

成功检索结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在使用MyBatis返回com.alibaba.fastjson.JSONObject对象,遇到了字段值为null而未返回的情况。解决问题需要进行以下步骤: 1. 检查数据库相关字段是否为null:首先需要确认数据库对应的字段是否确实为null,如果是null,那么MyBatis在映射为JSONObject对象会将其忽略,不进行返回。如果确实需要返回null字段,则需要进行后续操作。 2. 在MyBatis映射文件增加null值字段的判断:在映射文件,可以通过添加if标签对字段进行判断,如下所示: ```xml <if test="fieldName == null"> fieldName is null </if> ``` 这样,在字段为null,会将相应的信息返回。 3. 使用JavaBean代替JSONObject对象:若上述方法无效,可以考虑使用JavaBean对象代替JSONObject对象进行返回。JavaBean对象的属性可以包含null值字段,并能够被正确返回。 4. 检查FastJson版本:确保使用的是最新版本的FastJson库,因为不同版本可能存在差异,可能会导致某些情况下字段为null而未返回。 总结起来,解决MyBatis返回com.alibaba.fastjson.JSONObject对象为null字段不返回的问题,可以通过检查数据库字段状态、添加null值字段判断、使用JavaBean对象代替JSONObject对象等方法来解决。请按照上述步骤进行尝试。 ### 回答2: 问题是在使用MyBatis,返回的com.alibaba.fastjson.JSONObject对象有一些字段的值为null,并且希望不返回这些null字段。 要解决这个问题,我们可以使用MyBatis的resultMap来进行字段映射和处理。首先,需要在MyBatis的映射文件定义一个resultMap,指定需要处理的字段和对应的处理方式。 如下所示: <resultMap id="JSONObjectResultMap" type="com.alibaba.fastjson.JSONObject"> <id property="id" column="id" javaType="Long" /> <result property="name" column="name" javaType="String" /> <result property="age" column="age" javaType="Integer" nullValue="" /> </resultMap> 在这个resultMap,我们通过result标签来定义字段的映射关系。在需要处理null字段的地方,可以使用nullValue属性来指定默认值。 然后,在查询语句使用这个resultMap,如下所示: <select id="query" resultMap="JSONObjectResultMap"> SELECT id, name, age FROM table_name </select> 这样,在执行查询后,com.alibaba.fastjson.JSONObject对象null字段将会赋予我们在resultMap指定的默认值,而不再返回null。 当然,如果你不想显示这些null值的字段,你也可以在使用结果集的候手动进行处理,判断字段的值是否为null,如果是null,则不进行处理。 总结起来,要解决MyBatis返回com.alibaba.fastjson.JSONObjectnull的字段不返回的问题,可以通过使用resultMap进行字段映射,并设置nullValue属性来指定默认值,或者在使用结果集手动处理null字段的值。 ### 回答3: 当MyBatis返回给你的com.alibaba.fastjson.JSONObject对象某些字段的值为空,可以通过以下方法解决: 1. 在自定义的MyBatis映射文件,确保将数据库的列映射到实体类的属性上。如果某些列没有对应的字段,MyBatis会将对应的属性值设置为null。 2. 检查数据库数据,确保相应的字段有被正确地存储和获取。如果数据库的字段值为空,那么对应的JSONObject对象的相应字段也会为空。 3. 检查com.alibaba.fastjson.JSONObject类的引入和使用是否正确。你可以尝试在代码打印出JSONObject对象,确保其它属性的值都可以正常获取到。 4. 确保MyBatis的配置文件开启了自动驼峰命名映射。在配置文件添加以下配置: ``` <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> ``` 这样的话,MyBatis会将数据库列名的下划线形式自动转换为Java属性的驼峰命名形式,以便正确地映射到对应的属性。 5. 如果上述方法都没有解决问题,可能是由于某些不可预见的原因导致。你可以通过添加日志输出来查看MyBatis的执行和结果,以帮助你定位具体的问题所在。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值