包含多个Java类型的表上的DynamoDBmapper

发布于 2025-01-22 11:59:24 字数 1983 浏览 0 评论 0原文

我有一个DynamoDB表,该表包含多种逻辑实体。我的桌子存储“员工”和“组织”,并在两个人之间建立了许多一对一的关系。

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

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

雇员。Javaand

@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
}

andyman.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
}

我的查询访问模式之一是“检索组织的详细信息及其所有员工”。我以某种方式设计了我的表格模式,该模式使我可以在一个查询中检索所有这些项目。

我正在努力使用DynamoDBMapper在Java中编写此查询。 DynamodBquery Expression和mapper.query()函数都需要类实例化和水合的类。由于我的查询结果集将包含这两种类型的对象,因此我认为我可以使用雇员或agrommans.class提供这些功能。

我的想法是尝试提供对象。类,但这是行不通的,因为DynamoDBMapper期望提供的类包括DynamoDB注释。

test.java:

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

我认为围绕此的唯一方法是创建一个“主”类,该类真正代表我的表中的所有对象,类似:

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

然后,我所有的查询都将在WorkplaceItem类中完成,而我' d负责添加一些业务逻辑,以将工作场所ITEM转换为Java代码中更具体的员工或组织。

这是正确的方法吗?对于我的代码库来说,这将是一个实质性的更改,因此我很好奇是否有更好的方法可以在开始进行此更改之前完成我想要的工作。

I have a single DynamoDB table which contains more than one type of Logical Entity. My table stores "Employees" and "Organizations" and creates a many-to-many relationship between the two of them.

I am struggling with how to use DynamoDBMapper to model both the entities and my table. Particularly when trying to write queries that will return both Employees and Organizations.

In my Java code, I've started by representing these entities using two classes.

Employee.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
}

And 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
}

One of my query access patterns is, "Retrieve an organization's details and all of its employees". I have designed my table schema in a way which allows me to retrieve all of these items within a single query.

I'm struggling with how to write this query in Java using DynamoDbMapper. Both DynamoDBQueryExpression and the mapper.query() function require a class to instantiate and hydrate. Since my query result set will contain both types of objects, I don't think I can supply these functions with either Employee.class or Organization.class.

My idea was to just try supplying Object.class, but that doesn't work because DynamoDBMapper expects the supplied class to include the DynamoDB annotations.

Test.java:

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

I am thinking that the only way around this is to create a "master" class which truly represents all objects in my table, something like:

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

Then, all of my queries would be done on the WorkplaceItem class, and I'd be responsible for adding some business logic to convert a WorkplaceItem into a more specific Employee or Organization within the java code.

Is this the right approach? It would be a substantial change to my codebase so I'm curious if there is a better way to accomplish what I want before I start making this change.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

向地狱狂奔 2025-01-29 11:59:24

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

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

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

AttributeValue liftPK = new AttributeValue("LIFT#" + liftNumber);
QueryRequest queryRequest = new QueryRequest()
        .withTableName("SkiLifts")
        .withKeyConditionExpression("PK = :v_pk")
        .withExpressionAttributeValues(Map.of(":v_pk", liftPK));
QueryResult queryResult = amazonDynamoDB.query(queryRequest);

此查询的结果可以包含不同类型对象的项目,包括LiftdynamicStats和LiftStaticStats对象。 DynamoDBMapper类不适合实现此查询,因为其键入方法不允许包含不同类型的对象的查询结果。但是,对于此访问模式,重要的是检索包含不同类型的对象的数据集,只有一个查询DynamoDB。因为QueryRequest和QueryResult类能够处理包含不同类型数据对象的查询结果,因此使用QueryRequest和QueryResult类是实现此查询的最佳选择。

Answering my own question here.

DynamoDBMapper cannot be used for my purpose, but I should still keep the individual classes and not create a single master class.

From this article by AWS: https://aws.amazon.com/blogs/database/amazon-dynamodb-single-table-design-using-dynamodbmapper-and-spring-boot/

AttributeValue liftPK = new AttributeValue("LIFT#" + liftNumber);
QueryRequest queryRequest = new QueryRequest()
        .withTableName("SkiLifts")
        .withKeyConditionExpression("PK = :v_pk")
        .withExpressionAttributeValues(Map.of(":v_pk", liftPK));
QueryResult queryResult = amazonDynamoDB.query(queryRequest);

The results of this query can contain items of different types of objects, both LiftDynamicStats and LiftStaticStats objects. The DynamoDBMapper class isn’t suited to implement this query because its typed methods don’t allow for a query result that contains different types of objects. However, for this access pattern it is important to retrieve the data set containing different types of objects with just one query to DynamoDB. Because the QueryRequest and QueryResult classes are able to deal with query results containing different types of data objects, using the QueryRequest and QueryResult classes is the best alternative for implementing this query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文