如何简化 postgres 数据和 java 对象/json 有效负载之间的映射(反之亦然)

Posted

技术标签:

【中文标题】如何简化 postgres 数据和 java 对象/json 有效负载之间的映射(反之亦然)【英文标题】:How to simplify mapping between postgres data and java object / json payload (and vice versa) 【发布时间】:2021-02-03 12:42:19 【问题描述】:

该项目是简单的rest api(springboot框架),其中交换json消息并将有效负载保存到Postgres数据库。

实现了两种方法,第一种(http post)保存数据,第二种(http get)从数据库中检索数据。

初始 json 请求(执行 HTTP POST 时),payload 由客户端的要求预定义:

...


"characteristics" : [ 
    "name" : "char1",
    "value" : "value1"
  , 
    "name" : "char2",
    "value" : "value2"
  , 
    "name" : "char3",
    "value" : "value3"
  
 ]

Json 响应(在 HTTP GET 上)具有与请求完全相同的输出

...


"characteristics" : [ 
    "name" : "char1",
    "value" : "value1"
  , 
    "name" : "char2",
    "value" : "value2"
  , 
    "name" : "char3",
    "value" : "value3"
  
 ]

我的模型如下所示:

1.

    public class Request 
    
    ...

    @JsonProperty("characteristics")
    private List<Characteristics> characteristics = new ArrayList<>();

    //Getters and setters

    
    public Class Characteristics 

    @JsonProperty
    private String name;

    @JsonProperty
    private String value;

    
    //Getters and setters

    

关于 db 通信 - jpa 存储库已实现,并定义了一个本机查询以从 postgres 检索数据:

@Repository
public interface PostgresRepository extends JpaRepository<DbObject, Long> 

    @Query(value = "SELECT * FROM someTableName", nativeQuery = true)
    List<DbObject> getAll();


每个单独的特征“名称”都是 postgres 中的一个单独的列:

        Column        |            Type             |                     
----------------------+-----------------------------+
 id                   | integer                     |
 char1                | character varying(50)       |
 char2                | character varying(50)       |
 char3                | character varying(50)       |

对于 REST API 的每个 GET 调用,结果检索过程如下:

 ...

 
 List<DbObject> dbObjectList = postgresRepo.getAll();
 List<SpeedtestRequest> resultList = new ArrayList<>();
 SingleResult singleResult;
 
 for (DbObject dbObject : dbObjectList) 

            List<Characteristics> characteristicsList = new ArrayList<>();
            Characteristics char1 = new Characteristics("char1", dbObject.getChar1());
            characteristicsList.add(char1);
            Characteristics char2 = new Characteristics("char2", dbObject.getChar2());
            characteristicsList.add(char2);
            Characteristics char3 = new Characteristics("char3", dbObject.getChar3());
            characteristicsList.add(char3);
            
            singleResult = new SingleResult(characteristicsList)
            resultList.add(speedtestRequest);
  


  return ResponseEntity.ok(objectMapper.writeValueAsString(resultList));
  
  

在数据库中存储数据时会发生相同的过程,反之亦然。每个特征都必须被读取(解析)并存储在数据库的特定列中。

我的问题是 - 是否可以通过某种方式简化数据检索以及将每列映射到特性对象中的单个特性以减少此样板代码?

【问题讨论】:

是的。如果您愿意更改架构。尝试改用jsonb。您不再需要执行任何操作,因为您可以直接从数据库中按原样检索它(一个 json 对象)。 【参考方案1】:

您可以很好地将 REST 输入存储为 json or jsonb 文档。为此,您必须更改表架构。您的表架构最终将如下所示:

        Column        |            Type             |                     
----------------------+-----------------------------+
 id                   | integer                     |
 document             | jsonb                       |

请注意,Postgres 中的 JSON 支持从 9.5 及更高版本开始。 (9.4 / 9.3 / 9.2 不受支持)

【讨论】:

很遗憾,客户端已经定义了表模式,无法更改。 哦,我想一个优雅的方法是存储为 jsonb 对象。可能有人会为您提供更好的方法!祝你好运

以上是关于如何简化 postgres 数据和 java 对象/json 有效负载之间的映射(反之亦然)的主要内容,如果未能解决你的问题,请参考以下文章

如果用户有依赖对象,如何在 postgres 中删除用户

Navicat、对象数据库和 Postgres

Java 枚举、JPA 和 Postgres 枚举——如何让它们一起工作?

如何从 Postgres 9.4 中转储大对象数据,然后将其导入 Postgres8.x?

从Java中的Postgres加载非物化数组

使用 Java 和 Postgres 数据库进行客户端加密