簡體   English   中英

在 Spring 上,如何使用 JPA 和復合鍵(分區鍵和排序鍵)查詢 DynamoDB 表?

[英]On Spring, how to query DynamoDB table using JPA and a composite key (Partition Key and Sort Key)?

我有一個使用 JPA 和 Spring Data DynamoDB 設置的 Spring 項目。 它工作正常。 我可以通過分區鍵和排序鍵(稱為DynamoDBHashKeyDynamoDBRangeKey )讀取它從 DynamoDB 表中獲取項目。

我的問題是我的存儲庫的設置方式是使用queryscan操作讀取表,而不是使用get-item操作,這應該更有效。

這是我的實體:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamoDBTable(tableName = "my-entity-table")
public class MyEntity {

    @Id
    @DynamoDBHashKey 
    @DynamoDBAttribute(attributeName = "partition_key")
    private String partitionKey;

    @Id
    @DynamoDBRangeKey
    @DynamoDBAttribute(attributeName = "sort_key")
    private String sortKey;

    ...
}

這是我的存儲庫:

import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@EnableScan
@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, String> {
    List<MyEntity> findByPartitionKeyAndSortKey(String partitionKey, String sortKey);
}

當我的表同時具有分區鍵和排序鍵時,如何配置我的實體和存儲庫以使用get-item操作從表中讀取項目?

做了一些研究后,我偶然發現了這兩篇文章:

  1. 復合主鍵 Kotlin 示例
  2. 帶有哈希和范圍鍵 DynamoDB 表的 Spring Data JPA

第一個解釋了如何在 Kotlin 中做我想做的事。 不錯,但這不是我正在尋找的。

第二個完美命中目標,基本上它說的是我需要為我的實體對象創建一個主鍵對象,如下所示:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamoDBTable(tableName = "my-entity-table")
public class MyEntity {

    @Id
    @DynamoDBIgnore
    private PrimaryKey primaryKey;

    ...

    @DynamoDBHashKey
    @DynamoDBAttribute(attributeName = "partition_key")
    public String getPartitionKey() {
        return primaryKey != null ? primaryKey.getPartitionKey() : null;
    }

    public void setPartitionKey(final String partitionKey) {
        if (primaryKey == null) {
            primaryKey = new PrimaryKey();
        }
        primaryKey.setPartitionKey(partitionKey);
    }

    @DynamoDBRangeKey
    @DynamoDBAttribute(attributeName = "sort_key")
    public String getSortKey() {
        return primaryKey != null ? primaryKey.getSortKey() : null;
    }

    public void setSortKey(final String sortKey) {
        if (primaryKey == null) {
            primaryKey = new PrimaryKey();
        }
        primaryKey.setSortKey(sortKey);
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @DynamoDBDocument
    public static class PrimaryKey {
        @DynamoDBHashKey 
        @DynamoDBAttribute(attributeName = "partition_key")
        private String partitionKey;

        @DynamoDBRangeKey
        @DynamoDBAttribute(attributeName = "sort_key")
        private String sortKey;
    }
}

然后,我不需要在我的存儲庫類上創建任何自定義查詢方法:

@EnableScan
@Repository
public interface MyEntityRepository extends 
        CrudRepository<MyEntity, MyEntity.PrimaryKey> {

}

之后,只需使用 JPA 的CrudRepository方法來獲取項目,就像這樣:

final MyEntity.PrimaryKey myEntityPK 
    = new MyEntity.PrimaryKey("partitionKey", "sortKey");

final MyEntity myEntity = myEntityRepository.findById(myEntityPK)
    .orElseThrow(() -> ... );

為了驗證它實際上是在使用get-item操作而不是scanquery操作,可以在以下類上放置幾個斷點(從spring-data-dynamodb-5.1.0 ):

  • org.socialsignin.spring.data.dynamodb.core.DynamoDBTemplate
  • org.socialsignin.spring.data.dynamodb.repository.support.SimpleDynamoDBCrudRepository

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM