You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot结合PostgreSQL JSONB动态结构免多POJO实现方案咨询

优化实现方案

1 替换多实体为通用JSONB映射实体

完全不需要为每个JSON结构单独定义实体、UserType类,直接使用Hibernate对JSONB的原生支持,将data字段映射为通用的Jackson JsonNode 类型即可适配任意结构的JSON数据:

import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.*;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import org.hibernate.annotations.TypeDef;

@Entity
@Table(name = "information", schema = "public")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class CommonInfoEntity {
    @Id
    private Integer id;

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private JsonNode data;

    // 通用getter/setter
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public JsonNode getData() { return data; }
    public void setData(JsonNode data) { this.data = data; }
}

依赖说明:Hibernate 6+自带JSON类型支持无需额外引入依赖;Hibernate 5版本需引入hypersistence-utils依赖:

<dependency>
    <groupId>io.hypersistence</groupId>
    <artifactId>hypersistence-utils-hibernate-55</artifactId>
    <version>3.7.0</version>
</dependency>

2 业务层实现类型自动匹配

如果部分固定JSON结构需要对应POJO做业务逻辑处理,可在Service层根据id或者JSON内的标识字段自动做类型转换:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CommonInfoService {
    @Autowired
    private CommonInfoRepository infoRepository;
    @Autowired
    private ObjectMapper objectMapper;

    // 通用查询方法,自动匹配对应POJO
    public Object getInfoById(Integer id) {
        CommonInfoEntity entity = infoRepository.findById(id).orElseThrow();
        // 可根据id或者JSON内的name字段匹配对应类型
        String userName = entity.getData().get("name").asText();
        return switch (userName) {
            case "AlexRob" -> objectMapper.convertValue(entity.getData(), AlexRob.class);
            case "Janice" -> objectMapper.convertValue(entity.getData(), Janice.class);
            default -> entity.getData(); // 未知结构直接返回原始JSON
        };
    }

    // 通用保存方法
    public CommonInfoEntity saveInfo(Integer id, Object data) {
        CommonInfoEntity entity = new CommonInfoEntity();
        entity.setId(id);
        entity.setData(objectMapper.valueToTree(data));
        return infoRepository.save(entity);
    }
}

3 统一控制器实现

仅需要一个控制器即可处理所有id的存取请求:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/info")
public class CommonInfoController {
    @Autowired
    private CommonInfoService infoService;

    @GetMapping("/{id}")
    public Object getInfo(@PathVariable Integer id) {
        return infoService.getInfoById(id);
    }

    @PostMapping("/{id}")
    public CommonInfoEntity saveInfo(@PathVariable Integer id, @RequestBody Object data) {
        return infoService.saveInfo(id, data);
    }
}

该方案后续新增JSON结构仅需要新增对应POJO、在Service层加类型分支即可,无需修改底层实体、控制器代码,冗余度极低。

内容的提问来源于stack exchange,提问作者Deepak Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:36:03