包含多种 Java 类型的表上的 DynamoDBMapper

Duk*_*ver 2 java amazon-dynamodb dynamodb-queries dynamodb-mapper

我有一个 DynamoDB 表,其中包含不止一种类型的逻辑实体。我的表存储“员工”和“组织”,并在两者之间创建多对多关系。

我正在努力解决如何使用 DynamoDBMapper 对实体和表进行建模。特别是在尝试编写将返回员工和组织的查询时。

在我的 Java 代码中,我首先使用两个类来表示这些实体。

员工.java

@DynamoDBTable(tableName = "workplaces")
public class Employee() {
  @DynamoDBHashKey(attributeName = "pk")
  public String employeeId;

  @DynamoDBRangeKey(attributeName = "sk")
  public String sortKey

  // Other attributes specific to employees, as well as getters and setters
}
Run Code Online (Sandbox Code Playgroud)

和 Organization.java:

@DynamoDBTable(tableName = "workplaces")
public class Organization() {
  @DynamoDBHashKey(attributeName = "pk")
  public String organizationId;

  @DynamoDBRangeKey(attributeName = "sk")
  public String sortKey

  // Other attributes specific to organizations, as well as getters and setters
}
Run Code Online (Sandbox Code Playgroud)

我的查询访问模式之一是“检索组织的详细信息及其所有员工”。我设计的表架构允许我在单个查询中检索所有这些项目。

我正在努力解决如何使用 DynamoDbMapper 在 Java 中编写此查询。DynamoDBQueryExpression 和 mapper.query() 函数都需要一个类来实例化和水化。由于我的查询结果集将包含这两种类型的对象,因此我认为我无法使用 Employee.class 或 Organization.class 提供这些函数。

我的想法是尝试提供 Object.class,但这不起作用,因为 DynamoDBMapper 期望提供的类包含 DynamoDB 注释。

测试.java:

DynamoDBMapper mapper = new DynamoDBMapper();
DynamoDBQueryExpression<Object> queryExpression = new DynamoDBQueryExpression<Object>()
  .withHashKeyValues("blah")
  .withRangeKeyCondition("blah");
List<Object> queryResult = mapper.query(Object.class, queryExpression);
Run Code Online (Sandbox Code Playgroud)

我认为解决这个问题的唯一方法是创建一个“主”类,它真正代表我表中的所有对象,例如:

@DynamoDBTable(tableName = "workplaces")
public class WorkplaceItem() {
  // All attributes from both the Employee and Organization classes
}
Run Code Online (Sandbox Code Playgroud)

然后,我的所有查询都将在 WorkplaceItem 类上完成,并且我将负责添加一些业务逻辑以将 WorkplaceItem 转换为 java 代码中更具体的 Employee 或 Organization。

这是正确的方法吗?这将是对我的代码库的重大更改,因此我很好奇在开始进行此更改之前是否有更好的方法来完成我想要的事情。

Duk*_*ver 5

在这里回答我自己的问题。

\n

DynamoDBMapper 不能用于我的目的,但我仍然应该保留各个类,而不是创建单个主类。

\n

来自AWS的这篇文章:https://aws.amazon.com/blogs/database/amazon-dynamodb-single-table-design-using-dynamodbmapper-and-spring-boot/

\n
AttributeValue liftPK = new AttributeValue("LIFT#" + liftNumber);\nQueryRequest queryRequest = new QueryRequest()\n        .withTableName("SkiLifts")\n        .withKeyConditionExpression("PK = :v_pk")\n        .withExpressionAttributeValues(Map.of(":v_pk", liftPK));\nQueryResult queryResult = amazonDynamoDB.query(queryRequest);\n
Run Code Online (Sandbox Code Playgroud)\n
\n

此查询的结果可以包含不同类型对象的项目,包括 LiftDynamicStats 和 LiftStaticStats 对象。DynamoDBMapper 类不适合实现此查询,因为其类型化方法不允许包含不同类型对象的查询结果。然而,对于这种访问模式,仅通过一次 DynamoDB 查询即可检索包含不同类型对象的数据集,这一点非常重要。由于 QueryRequest 和 QueryResult 类能够处理包含不同类型数据对象的查询结果,因此使用 QueryRequest 和 QueryResult 类是实现此查询的最佳替代方法。

\n
\n

  • **“DynamoDBMapper.query”和“AmazonDynamoDB.query”之间的一个重要区别**是前者自动处理分页。DynamoDB 对查询期间扫描的数据有 1 MB 的限制,该限制适用于扫描的记录,而不是返回的记录。https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html。如果达到该限制,则会出现一个新页面,并且“AmazonDynamoDB.query”将返回在此之前找到的任何过滤结果。必须勾选“lastKeyEvaluated”,然后设置为查询后续页面 (2认同)