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个属性的项的表:
- ID
- MSRP
- 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));
}
}