V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
muchenlou
V2EX  ›  程序员

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

  •  
  •   muchenlou · 98 天前 · 1622 次点击
    这是一个创建于 98 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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"
    }
    ]
    }
    }
    ]
    }
    第 1 条附言  ·  97 天前
    尝试了 JDBC ,能搞起来了
    20 条回复    2022-10-09 10:42:12 +08:00
    beetlerx
        1
    beetlerx  
       98 天前   ❤️ 1
    直接用 String 接收 然后反序列化也行啊
    muchenlou
        2
    muchenlou  
    OP
       98 天前
    @beetlerx 用 String 接受的话,会提示 [No Dialect mapping for JDBC type: 1111]
    lix7
        3
    lix7  
       98 天前   ❤️ 1
    写个自定义 converter
    muchenlou
        4
    muchenlou  
    OP
       98 天前
    @lix7 大佬,我有点菜,可以请教下这个怎么写么?
    optional
        5
    optional  
       98 天前 via iPhone   ❤️ 1
    拿 JsonNode 接
    shanai
        6
    shanai  
       98 天前   ❤️ 1
    https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-52
    可以看一下这个的实现应该能解决你的问题
    muchenlou
        7
    muchenlou  
    OP
       98 天前
    @optional dataURL 后面要加 stringtype=unspecified 这个吗?
    muchenlou
        8
    muchenlou  
    OP
       98 天前
    @shanai 这个 POM 加了,但是我没有实体类去接受
    nothingistrue
        9
    nothingistrue  
       98 天前   ❤️ 1
    Spring JPA 的实现 Hibernate ,没有为 PostgreSQL JSON 类型提供基本类型映射,所以这个你只能自定义 BasicType 或者 Converter 。
    nothingistrue
        10
    nothingistrue  
       98 天前   ❤️ 1
    你可以将 JSON 类型映射到 Jackson 的 JsonNode ,然后用 Jackson 的 API 或者 JsonPath 来读写这个 JsonNode
    HHHorz
        11
    HHHorz  
       98 天前   ❤️ 1
    封装一个 typeHandler 类

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

    在 Mapper.xml 文件中声明 typeHandler

    set data = #{data,jdbcType=OTHER,typeHandler=com.datasync.entity.handler.JsonbTypeHandler}
    muchenlou
        12
    muchenlou  
    OP
       98 天前
    @HHHorz 大佬,有 demo 吗?我想去借鉴下
    zed1018
        13
    zed1018  
       98 天前
    存储过程我不知道,但是 entity 的话可以用 Map<String,Any>或者 JsonNode ,然后配合 @Convert(converter=)做一个自定义的序列化和反序列化
    xiaohusky
        14
    xiaohusky  
       98 天前
    群友这是
    facelezz
        15
    facelezz  
       98 天前
    谷歌搜索 mybatis typeHandler
    nothingistrue
        16
    nothingistrue  
       98 天前
    @HHHorz #11
    @facelezz #15
    看题,spring jpa ,这是 JPA 标准 Hibernate 实现,跟 mybatais 不是一个系列。
    nothingistrue
        17
    nothingistrue  
       98 天前   ❤️ 2
    @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 即可。
    nothingistrue
        19
    nothingistrue  
       97 天前
    @optional 首先这是个好东西,楼主可以考虑直接用了。

    然后还是要做下名词解释:
    JPA 是 Java 实体持久化标准;
    Hibernate 是 JPA 的一种实现库,类似的实现还有 EclipseLink 等等;
    (背后的话,JPA 3.0 标准是基于 Hibernate 提取的,但这不影响 JPA 是独立标准;)
    Spring Data JPA 是一个再次封装、更容易直接使用的库,它理论上是再封装 JPA ,但实际上是再封装 Hibernate ;
    vladmihalcea/hibernate-types 这个,算是 Hibernate 核心的第三方扩展;
    HHHorz
        20
    HHHorz  
       60 天前
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1243 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 22:33 · PVG 06:33 · LAX 14:33 · JFK 17:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.