IT/AWS

[AWS] DynamoDB 연동기

어린이개발자 2024. 11. 29. 20:07

회사에서 NoSQL 도입을 고려하다가 AWS 를 사용하고 있기에 DynamoDB 연동을 검토해봤다.

그 과정에서 알게 된 설정 관련 내용을 정리하고자 한다.

 

1. 환경 설정

- build.gradle 에 의존성(dependency) 추가

implementation platform('software.amazon.awssdk:bom:2.20.85')
implementation 'software.amazon.awssdk:dynamodb-enhanced'

 

참고) Spring Boot 버전에 따라 라이브러리 버전도 변경 필요할 수 있다.

 

- application.properties 파일에 설정 추가

  • amazon.dynamodb.accessKey=XXX
  • amazon.dynamodb.secretKey=XXX

2. Configuration 파일 추가 및 수정

- DynamoDBConfig.java

  > DynamoDbEnhancedClient 사용 권장

@Configuration
public class DynamoDBConfig {

    @Value("${amazon.dynamodb.accessKey}")
    private String accessKey;

    @Value("${amazon.dynamodb.secretKey}")
    private String secretKey;

    @Bean
    public DynamoDbClient dynamoDbClient() {
        return DynamoDbClient.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();
    }

    @Qualifier("dynamoDbClient")
    @Bean
    public DynamoDbEnhancedClient dynamoDbEnhancedClient(DynamoDbClient dynamoDbClient) {
        return DynamoDbEnhancedClient.builder().dynamoDbClient(dynamoDbClient).build();
    }

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
        return amazonDynamoDB;
    }

    @Bean
    public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB) {
        return new DynamoDBMapper(amazonDynamoDB, DynamoDBMapperConfig.DEFAULT);
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(accessKey, secretKey);
    }
}

 

- RdbConfig.java

  > Class 단에 @EnableJpaRepositories 어노테이션 추가하여 JpaRepository 를 상속하여 사용하는 repository 구분 (DynamoDB 관련 사용되는 repository 는 JpaRepository 상속 불가)

@EnableJpaRepositories(basePackages = "test.demo.backend.repositories")

 

3. 테이블 관리

- 예시) products_synonym (부품 동의어)

  • attribute
    • synonym (Partition-Key)
    • name
  • Partition-Key(필수) 와 Sort-Key(선택) 설정
  • 인덱스
    • 글로벌 보조 인덱스

4. Entity 관리

@DynamoDbBean
//@Getter
@Setter
@NoArgsConstructor
@DynamoDBTable(tableName = "products_synonym")
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class ProductsSynonyms {

    @DynamoDBHashKey(attributeName = "synonym")
    private String synonym;

    @DynamoDBAttribute(attributeName = "name")
    private String name;

    @DynamoDbPartitionKey -> @Getter 사용시 어노테이션 설정 불가하여 직접 get 함수 추가
    public String getSynonym() {
        return synonym;
    }

    public String getName() {
        return name;
    }

    @Builder
    public PartsSynonyms(String name, String synonym) {
        this.name = name;
        this.synonym = synonym;
    }
}

 

5. Package 관리

- test.demo.backend 하위에 dynamo 패키지 생성 후 domain, repositories, objects 패키지 각각 생성하여 파일 추가

 

6. Repository 관리 (CRUD 함수)

@Repository
public class ProductsSynonymsRepository {

    private final DynamoDbTable<ProductsSynonyms> productsSynonymsDynamoDbTable;

    public ProductsSynonymsRepository(DynamoDbEnhancedClient dynamoDbEnhancedClient) {
        this.productsSynonymsDynamoDbTable = dynamoDbEnhancedClient.table("products_synonym", TableSchema.fromBean(ProductsSynonyms.class));
    }

    // 조회
    public ProductsSynonyms findBySynonym(String synonym) {
        QueryConditional conditional = QueryConditional.keyEqualTo(Key.builder().partitionValue(synonym).build());
        QueryEnhancedRequest queryRequest = QueryEnhancedRequest.builder().queryConditional(conditional).limit(1).build();
        return productsSynonymsDynamoDbTable.query(queryRequest).items().stream().findAny().orElseGet(() -> null);
    }

    // 생성
    public void saveProductsSynonym(ProductsSynonyms productsSynonyms) {
        productsSynonymsDynamoDbTable.putItem(productsSynonyms);
    }

    // 수정
    public void updateProductsSynonym(ProductsSynonyms productsSynonyms) {
        productsSynonymsDynamoDbTable.updateItem(productsSynonyms);
    }

    // 삭제
    public void deleteProductsSynonym(ProductsSynonyms productsSynonyms) {
        productsSynonymsDynamoDbTable.deleteItem(productsSynonyms);
    }
}

 

설정은 이 정도로 해봤고, 호출 테스트 시 원하는 결과를 도출할 수 있었다.

그리고 NoSQL 인데, RDBMS 처럼 사용하지 않도록 주의가 필요하다는 생각이 들었다.

'IT > AWS' 카테고리의 다른 글

[AWS] EC2 Nginx 무중단 배포  (0) 2024.12.05
[AWS] ECS Fargate 도입기  (0) 2024.11.27