spring jpa 如何去接受 PostgreSQL 存储过程返回的 JSON 类型的参数

2022-09-01 10:32:59 +08:00
 muchenlou
spring jpa 如何去接受 PostgreSQL 存储过程返回的 JSON 类型的参数?
看了一些文档,基本都是用一个实体类去接受,但是,存储过程返回来的 JSON 数据是自定义的,没有对应的表,我应该如何去接受这个 JSON 类型呢?
返回的数据类型

{
"store_id":"1056",
"details":[
{
"glass_type":"MP",
"req_info":{
"stocks":[
{
"width":11,
"height":14,
"count":100
}
],
"order_parts":[
{
"width":null,
"height":null,
"quantity":1,
"orderId":"Q3033169842"
}
]
}
}
]
}
2348 次点击
所在节点    程序员
20 条回复
beetlerx
2022-09-01 10:45:53 +08:00
直接用 String 接收 然后反序列化也行啊
muchenlou
2022-09-01 10:49:02 +08:00
@beetlerx 用 String 接受的话,会提示 [No Dialect mapping for JDBC type: 1111]
lix7
2022-09-01 10:51:56 +08:00
写个自定义 converter
muchenlou
2022-09-01 10:56:05 +08:00
@lix7 大佬,我有点菜,可以请教下这个怎么写么?
optional
2022-09-01 11:02:17 +08:00
拿 JsonNode 接
shanai
2022-09-01 11:03:29 +08:00
https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-52
可以看一下这个的实现应该能解决你的问题
muchenlou
2022-09-01 11:05:01 +08:00
@optional dataURL 后面要加 stringtype=unspecified 这个吗?
muchenlou
2022-09-01 11:05:57 +08:00
@shanai 这个 POM 加了,但是我没有实体类去接受
nothingistrue
2022-09-01 11:11:28 +08:00
Spring JPA 的实现 Hibernate ,没有为 PostgreSQL JSON 类型提供基本类型映射,所以这个你只能自定义 BasicType 或者 Converter 。
nothingistrue
2022-09-01 11:13:00 +08:00
你可以将 JSON 类型映射到 Jackson 的 JsonNode ,然后用 Jackson 的 API 或者 JsonPath 来读写这个 JsonNode
HHHorz
2022-09-01 11:36:48 +08:00
封装一个 typeHandler 类

java 实体类
@TableField(typeHandler = JsonbTypeHandler.class) 通过拦截的方法拦截转换字段

在 Mapper.xml 文件中声明 typeHandler

set data = #{data,jdbcType=OTHER,typeHandler=com.datasync.entity.handler.JsonbTypeHandler}
muchenlou
2022-09-01 11:44:02 +08:00
@HHHorz 大佬,有 demo 吗?我想去借鉴下
zed1018
2022-09-01 12:39:28 +08:00
存储过程我不知道,但是 entity 的话可以用 Map<String,Any>或者 JsonNode ,然后配合 @Convert(converter=)做一个自定义的序列化和反序列化
xiaohusky
2022-09-01 14:56:36 +08:00
群友这是
facelezz
2022-09-01 16:04:55 +08:00
谷歌搜索 mybatis typeHandler
nothingistrue
2022-09-01 17:27:03 +08:00
@HHHorz #11
@facelezz #15
看题,spring jpa ,这是 JPA 标准 Hibernate 实现,跟 mybatais 不是一个系列。
nothingistrue
2022-09-01 17:57:20 +08:00
@muchenlou 我再看了以下,这个不只是类型映射的问题。PostgreSQL JSON 类型是非普遍的 SQL 类型,它连 JDBC type 都是自定义的 1111 ,这种情况 JPA 短时间(可能 10 年)内是不会考虑对它的支持的。这里就算你用 CUstom Basic Type 或者 Converter 解决了实体映射,在映射后的实体上也只能把它当成 Object/String 来用,最多当成只读的 JsonNode 。像部分修改 json 的值,通过 json 的特定属性来查询这些功能,都是用不了的。上面这些功能你必须要用脱离 JPA 标准的 NativeSql 来做。

我得建议是,不要再考虑映射 JSON 类型了。增加一个 varchar 或 clob 类型的列,映射到实体类的 String 类型上,额外限定该字段(对于实体类的上层应用来说)是只读的。原有的 JSON 类型的列,对实体类不可见,只能通过自定义 Repository 并使用 Native SQL 来访问,且自定义 Repository 需要负责这两个列的值的同步。当然如果你不需要 JSON 类型列的特定功能的话,你就直接 String 映射 varchar 或 clob 类型的列 即可,上层程序中自行处理 JSON 即可。
optional
2022-09-02 07:57:13 +08:00
nothingistrue
2022-09-02 09:23:40 +08:00
@optional 首先这是个好东西,楼主可以考虑直接用了。

然后还是要做下名词解释:
JPA 是 Java 实体持久化标准;
Hibernate 是 JPA 的一种实现库,类似的实现还有 EclipseLink 等等;
(背后的话,JPA 3.0 标准是基于 Hibernate 提取的,但这不影响 JPA 是独立标准;)
Spring Data JPA 是一个再次封装、更容易直接使用的库,它理论上是再封装 JPA ,但实际上是再封装 Hibernate ;
vladmihalcea/hibernate-types 这个,算是 Hibernate 核心的第三方扩展;
HHHorz
2022-10-09 10:42:12 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/876927

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX