【问题标题】:How can i map entity column to json Key in Spring Data JDBC我如何将实体列映射到 Spring Data JDBC 中的 json Key
【发布时间】:2021-06-24 15:04:42
【问题描述】:

这是我的实体

@Table("amazon_rds_inventory")
public class AmazonDBInstanceDataSelect {
    @Id
    @Column("id")
    private long id;

    @Column("inventory_metadata")
    private String inventoryMetadata;

    @Column("aws_identifier")
    private String awsIdentifier;

    @Column("host")
    private String host;

    @Column("region")
    private String region;

    @Column("type")
    private AmazonInventoryType amazonInventoryType;

    @Column("created_by")
    private String user;

    @Column("created_on")
    private Timestamp createdOn;

    @Column("cloned")
    private boolean cloned;

    @Column("inventory_metadata->>'$.dbclusterIdentifier' as clusterIdentifier")
    private String clusterIdentifier;

    @Column("deleted")
    private boolean deleted;

}

“inventory_metadata”列的json数据

{
"port": 27017,
"engine": "docdb",
"status": "available",
"multiAZ": false,
"tagList": [],
"capacity": null,
"endpoint": "nimesa-docdb-cluster-01.cluster-cjzyjmw4obtv.us-east-1.docdb.amazonaws.com",
"kmsKeyId": "arn:aws:kms:us-east-1:220709770714:key/293f9b17-43fc-4946-92d6-cfcb9965a8cd",
"engineMode": "provisioned",
"cloneGroupId": null,
"databaseName": null,
"dbclusterArn": "arn:aws:rds:us-east-1:220709770714:cluster:nimesa-docdb-cluster-01",
"hostedZoneId": "ZNKXH85TT8WVW",
"dbsubnetGroup": "custom-subnetgroupwith-custom",
"engineVersion": "4.0.0",
"masterUsername": "nimesa",
"readerEndpoint": "nimesa-docdb-cluster-01.cluster-ro-cjzyjmw4obtv.us-east-1.docdb.amazonaws.com",
"associatedRoles": [],
"backtrackWindow": null,
"customEndpoints": [],
"percentProgress": null,
"allocatedStorage": 1,
"characterSetName": null,
"dbclusterMembers": [
    {
        "clusterWriter": true,
        "promotionTier": 1,
        "isClusterWriter": true,
        "dbinstanceIdentifier": "nimesa-docdb-01",
        "dbclusterParameterGroupStatus": "in-sync"
    }
],
"storageEncrypted": true,
"availabilityZones": [
    "us-east-1f",
    "us-east-1b",
    "us-east-1a"
],
"clusterCreateTime": 1615532359067,
"crossAccountClone": false,
"domainMemberships": [],
"vpcSecurityGroups": [
    {
        "status": "active",
        "vpcSecurityGroupId": "sg-05c8ed6d9836007fd"
    }
],
"activityStreamMode": null,
"copyTagsToSnapshot": false,
"deletionProtection": false,
"dbClusterResourceId": "cluster-6OQQJU32K2ZZE2GSTHP2DHNGZM",
"dbclusterIdentifier": "nimesa-docdb-cluster-01",
"httpEndpointEnabled": false,
"activityStreamStatus": "stopped",
"latestRestorableTime": 1620666452774,
"backupRetentionPeriod": 1,
"earliestBacktrackTime": null,
"pendingModifiedValues": null,
"preferredBackupWindow": "00:00-00:30",
"activityStreamKmsKeyId": null,
"earliestRestorableTime": 1620666452774,
"readReplicaIdentifiers": [],
"dbclusterParameterGroup": "default.docdb4.0",
"scalingConfigurationInfo": null,
"preferredMaintenanceWindow": "wed:07:48-wed:08:18",
"globalWriteForwardingStatus": null,
"replicationSourceIdentifier": null,
"enabledCloudwatchLogsExports": [],
"backtrackConsumedChangeRecords": null,
"globalWriteForwardingRequested": null,
"activityStreamKinesisStreamName": null,
"dbclusterOptionGroupMemberships": [],
"iamdatabaseAuthenticationEnabled": false

}

我得到的错误:- java.sql.SQLSyntaxErrorException: 未知列 'amazon_rds_inventory.inventory_metadata->>'$.dbclusterIdentifier' as clusterIdentifier' in 'field list'

我想在 json 中获取 dbclusterIdentifier 键的值并将其映射到我的实体

【问题讨论】:

  • 你用的是什么数据库?
  • @JensSchauder RDBMS MYSQL
  • 我需要一些时间来制定正确的答案,但作为一个快速指针:@Column 将不起作用。您至少需要一个自定义转换
  • 没问题,目前我在@Query注解中使用Mysql原生查询直接从DB解析JSON数据

标签: java json spring spring-boot spring-data-jdbc


【解决方案1】:

根据具体目标,您有多种选择。

让我们从目前的方法行不通的原因开始。

  1. @Column 指定一列,而不是任意表达式。正如您所指出的,将其设置为表达式只会产生一个非常奇怪的列名。
  2. 即使它可以处理表达式,它不仅需要一个表达式来提取值,还需要一个用来写回值的表达式。
  3. 该字段仅包含文档的一部分。如果可行,写回该值会将原始 JSON 文档替换为仅包含该值的文档。

让我们看看几个解决方案:

  1. 在您当前的设置中,您已经将完整的 JSON 文档加载为 inventoryMetadata。因此,我建议在加载后对实体进行后期处理。在您的应用程序上下文中注册一个AfterLoadCallback,它将所需的值从inventoryMetadata 提取到clusterIdentifier

  2. 如果您真的想以结构化方式访问 JSON 文档,您可以使用自定义类型,例如 InventoryMetadata 并注册转换器以将其转换为 String 并返回,如果我没记错的话,应该使用SQL 标准,所以希望它适用于 MySQL。

  3. 如果您想将 JSON 处理保留在 Java 代码之外,您可以在数据库中拥有一个数据库视图并在那里进行任何提取/操作。您可以将您的实体映射到该视图。如果视图是可更新的,你甚至可以使用 if 来写回数据。

  4. 您描述的使用专用@Query 的解决方案是另一种选择,当您只想读取数据时效果很好。

【讨论】:

    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多