DynamoDB in a Spring Boot Application Using Spring Data


1.概述

在本文中,我们将通过实际的实际示例项目探索将DynamoDB集成到Spring Boot Application中的基础知识。

我们将演示如何使用Spring Data配置应用程序以使用本地DynamoDB实例。我们还将创建示例数据模型和存储库类,以及使用集成测试执行实际的数据库操作。

2. DynamoDB

DynamoDB是AWS上完全托管的托管NoSQL数据库,类似于其他NoSQL数据库,如Cassandra或MongoDB。DynamoDB提供快速,一致和可预测的性能,并且具有大规模可扩展性。

您可以在AWS文档中了解有关DynamoDB的更多信息。

让我们安装一个DynamoDB的本地实例,以避免产生运行实例的成本。

对于开发,在本地运行DynamoDB比在AWS上运行更有意义; 本地实例将作为可执行JAR文件运行。

您可以在此处找到有关如何在本地运行DynamoDB的说明。

3. Maven依赖

添加以下依赖项以使用Spring Data开始使用DynamoDB:

  • Spring Data JPA
  • AWS Java SDK DynamoDB
  • Spring Data DynamoDB社区模块
<dependencyManagement>
    <dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-releasetrain</artifactId>
        <version>Hopper-SR10</version>
        <type>pom</type>
        <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-dynamodb</artifactId>
        <version>1.11.34</version>
    </dependency>
    <dependency>
        <groupId>com.github.derjust</groupId>
        <artifactId>spring-data-dynamodb</artifactId>
        <version>4.3.1</version>
    </dependency>
</dependencies>

4.配置

接下来,让我们在application.properties文件中定义以下属性:

amazon.dynamodb.endpoint=http://localhost:8000/
amazon.aws.accesskey=key
amazon.aws.secretkey=key2

上面列出的访问密钥和密钥只是本地配置的任意值。访问DynamoDB的本地实例时,这些字段需要由某些值填充,但不需要实际进行身份验证。

这些属性将从Spring配置中的application.properties文件中动态拉出:

@Configuration
@EnableDynamoDBRepositories
  (basePackages = "com.baeldung.spring.data.dynamodb.repositories")
public class DynamoDBConfig {

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

    @Value("${amazon.aws.accesskey}")
    private String amazonAWSAccessKey;

    @Value("${amazon.aws.secretkey}")
    private String amazonAWSSecretKey;

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

        if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) {
            amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
        }

        return amazonDynamoDB;
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(
          amazonAWSAccessKey, amazonAWSSecretKey);
    }
}

5.数据模型

现在让我们创建一个POJO模型来表示存储在DynamoDB中的数据。

这个POJO将使用类似于Hibernate中使用的注释来定义表名,属性,键和表的其他方面。

5.1。数据模型属性

以下类ProductInfo表示包含3个属性的项的表:

  1. ID
  2. MSRP
  3. Cost

5.2 Java数据模型类

让我们在您的数据模型文件夹中创建一个名为ProductInfo.java的文件:

@DynamoDBTable(tableName = "ProductInfo")
public class ProductInfo {
    private String id;
    private String msrp;
    private String cost;

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return id;
    }

    @DynamoDBAttribute
    public String getMsrp() {
        return msrp;
    }

    @DynamoDBAttribute
    public String getCost() {
        return cost;
    }

    // standard setters/constructors
}

6. CRUD存储库

接下来,我们需要创建一个ProductRepository接口来定义我们想要构建的CRUD功能。用于从DynamoDB读取数据和从中继承数据的存储库将实现此接口:

@EnableScan
public interface ProductInfoRepository extends
  CrudRepository<ProductInfo, String> {

    List<ProductInfo> findById(String id);
}

7.集成测试

接下来,让我们创建一个集成测试,以确保我们可以成功连接到DynamoDB的本地实例:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
@ActiveProfiles("local")
@TestPropertySource(properties = {
  "amazon.dynamodb.endpoint=http://localhost:8000/",
  "amazon.aws.accesskey=test1",
  "amazon.aws.secretkey=test231" })
public class ProductInfoRepositoryIntegrationTest {

    private DynamoDBMapper dynamoDBMapper;

    @Autowired
    private AmazonDynamoDB amazonDynamoDB;

    @Autowired
    ProductInfoRepository repository;

    private static final String EXPECTED_COST = "20";
    private static final String EXPECTED_PRICE = "50";

    @Before
    public void setup() throws Exception {
        dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);

        CreateTableRequest tableRequest = dynamoDBMapper
          .generateCreateTableRequest(ProductInfo.class);
        tableRequest.setProvisionedThroughput(
          new ProvisionedThroughput(1L, 1L));
        amazonDynamoDB.createTable(tableRequest);

        //...

        dynamoDBMapper.batchDelete(
          (List<ProductInfo>)repository.findAll());
    }

    @Test
    public void sampleTestCase() {
        ProductInfo dave = new ProductInfo(EXPECTED_COST, EXPECTED_PRICE);
        ProductInfoRepository.save(dave);

        List<ProductInfo> result
          = (List<ProductInfo>) repository.findAll();

        assertTrue("Not empty", result.size() > 0);
        assertTrue("Contains item with expected cost",
          result.get(0).getCost().equals(EXPECTED_COST));
    }
}