

适用于 Unity 的 AWS 移动 SDK 现已包含在 适用于 .NET 的 AWS SDK。本指南引用适用于 Unity 的 Mobile SDK 的存档版本。有关更多信息，请参阅 [适用于 Unity 的 AWS 移动 SDK 是什么？](what-is-unity-plugin.md)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon DynamoDB
<a name="dynamodb"></a>

 [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) 是一项快速、高度可扩展、高度可用且经济实惠的非关系数据库服务。DynamoDB 消除了传统上对数据存储可扩展性的限制，同时保留了低延迟性和可预测的性能。有关 DynamoDB 的信息，请参阅 [Amazon DynamoDB](https://aws.amazon.com/dynamodb/)。

适用于 Unity 的 AWS Mobile SDK 为您使用 DynamoDB 提供了高级库。您也可以直接针对低级 DynamoDB API 发出请求，但在大多数情况下，建议您使用高级库。 AmazonDynamoDBClient 是高级库中特别有用的部分。使用此类，您可以执行创建、读取、更新和删除 (CRUD) 操作和执行查询。

**注意**  
本文档中的一些示例假设使用名为的文本框变量 ResultText 来显示跟踪输出。

## 集成 Amazon DynamoDB
<a name="integrating-amazon-dynamodb"></a>

要在 Unity 应用程序中使用 DynamoDB，需要将 Unity SDK 添加到您的项目中。如果您尚未添加，则[下载适用于 Unity 的 SDK](https://aws.amazon.com/mobile/sdk/)，并按照[设置适用于 Unity 的 AWS Mobile SDK](setup-unity.md) 中的说明操作。我们建议您使用 Amazon Cognito Identity 为您的应用程序提供临时的 AWS 凭证。这些凭证允许您的应用程序访问 AWS 服务和资源。

要在应用程序中使用 DynamoDB，必须设置正确的权限。以下 IAM 策略允许用户删除、获取、放置、扫描和更新特定的用 [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) 标识的 DynamoDB 表中的项目：

```
{
"Statement": [{
    "Effect": "Allow",
    "Action": [
        "dynamodb:DeleteItem",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Scan",
        "dynamodb:UpdateItem"
    ],
    "Resource": "arn:aws:dynamodb:us-west-2:123456789012:table/MyTable"
}]
}
```

此策略应当应用到分配给 Cognito 身份池的角色，但您需要用您的 DynamoDB 表的正确 ARN 来替换 ** `Resource` ** 值。Cognito 自动为您的新身份池创建一个角色，您可以在 [IAM 控制台](https://console.aws.amazon.com/iam/)中将策略应用于此角色。

应根据您的应用程序的需要添加或删除允许的操作。要了解有关 IAM 策略的更多信息，请参阅[使用 IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html)。要了解更多有关 DynamoDB 特定策略的信息，请参阅[使用 IAM 控制对 DynamoDB 资源的访问](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/UsingIAMWithDDB.html)。

## 创建 DynamoDB 表
<a name="create-a-dynamodb-table"></a>

现在，我们已设置了权限和凭证，接下来，我们为应用程序创建一个 DynamoDB 表。要创建表，请转至 [DynamoDB 控制台](https://console.aws.amazon.com/dynamodb/home)并执行以下步骤：

1. 单击**创建表**。

1. 输入 `Bookstore` 作为表名。

1. 选择 **Hash** 作为主键类型。

1. 选择**数字**并输入哈希属性名称的 `id`。单击**继续**。

1. 再次单击 **Continue** 以跳过添加索引步骤。

1. 将读取容量设置为 `10`，将写入容量设置为 `5`。单击**继续**。

1. 输入通知电子邮件，然后单击 **Continue** 来创建吞吐量警报。

1. 单击**创建**。DynamoDB 将创建您的数据库。

## 创建 DynamoDB 客户端
<a name="create-a-dynamodb-client"></a>

我们需要一个客户端来让应用程序与 DynamoDB 表交互。可以创建一个默认的 DynamodDB 客户端，如下所示：

```
var credentials = new CognitoAWSCredentials(IDENTITY_POOL_ID, RegionEndpoint.USEast1);
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
DynamoDBContext Context = new DynamoDBContext(client);
```

该 AmazonDynamoDBClient 类是 DynamoDB API 的入口点。该类提供实例方法，用于创建、描述、更新和删除表以及其他操作。上下文在客户端之上又增加了一个抽象层，使您能够使用对象持久化模型等其他功能。

## 描述表
<a name="describe-a-table"></a>

要获取 DynamoDB 表的描述，可以使用以下代码：

```
resultText.text +=("\n*** Retrieving table information ***\n");
       var request = new DescribeTableRequest
       {
           TableName = @"ProductCatalog"
       };
       Client.DescribeTableAsync(request, (result) =>
       {
               if (result.Exception != null)
               {
                       resultText.text += result.Exception.Message;
                       Debug.Log(result.Exception);
                       return;
               }
               var response = result.Response;
               TableDescription description = response.Table;
               resultText.text += ("Name: " + description.TableName + "\n");
               resultText.text += ("# of items: " + description.ItemCount + "\n");
               resultText.text += ("Provision Throughput (reads/sec): " +
                   description.ProvisionedThroughput.ReadCapacityUnits + "\n");
               resultText.text += ("Provision Throughput (reads/sec): " +
                   description.ProvisionedThroughput.WriteCapacityUnits + "\n");

       }, null);
   }
```

在此示例中，我们创建了一个客户端和一个 DescribeTableRequest 对象，将表的名称分配给该**`TableName`**属性，然后将请求对象传递给该 AmazonDynamoDBClient 对象上的 DescribeTableAsync 方法。 DescribeTableAsync 还需要一个委托，该委托将在异步操作完成时被调用。

**注意**  
异步操作完成时调 AmazonDynamoDBClient 用的 take 委托上的所有异步方法。

## 保存对象
<a name="save-an-object"></a>

要将对象保存到 DynamoDB，请使用 SaveAsync<T> AmazonDynamoDBClient 该对象的方法，其中 T 是您要保存的对象的类型。

我们将我们的数据库称为“书店”，围绕这个主题，我们将实施一个数据模型，用于记录图书相关的属性。以下是定义我们的数据模型的类。

```
[DynamoDBTable("ProductCatalog")]
    public class Book
    {
        [DynamoDBHashKey]   // Hash key.
        public int Id { get; set; }
        [DynamoDBProperty]
        public string Title { get; set; }
        [DynamoDBProperty]
        public string ISBN { get; set; }
        [DynamoDBProperty("Authors")]    // Multi-valued (set type) attribute.
        public List<string> BookAuthors { get; set; }
    }
```

当然，就真正的书店应用程序而言，一些事项（如作者和价格等）需要附加字段。Book 类采用 [DynamoDBTable] 属性装饰，该属性定义了要写入 Book 类型的数据库表对象。Book 类的每个实例的密钥都是使用 [Dynamo DBHash Key] 属性标识的。属性用 [DynamoDBProperty] 属性标识，这些属性指定数据库表中要写入该属性的列。借助现成模型，我们可以编写一些方法来创建、检索、更新和删除 Book 对象。

## 创建书籍
<a name="create-a-book"></a>

```
private void PerformCreateOperation()
{
    Book myBook = new Book
    {
        Id = bookID,
        Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
        ISBN = "111-1111111001",
        BookAuthors = new List<string> { "Author 1", "Author 2" },
    };

    // Save the book.
    Context.SaveAsync(myBook,(result)=>{
        if(result.Exception == null)
            resultText.text += @"book saved";
    });
}
```

## 检索书籍
<a name="retrieve-a-book"></a>

```
private void RetrieveBook()
{
    this.displayMessage += "\n*** Load book**\n";
    Context.LoadAsync<Book>(bookID,
                             (AmazonDynamoResult<Book> result) =>
    {
        if (result.Exception != null)
        {

            this.displayMessage += ("LoadAsync error" +result.Exception.Message);
            Debug.LogException(result.Exception);
            return;
        }
        _retrievedBook = result.Response;
        this.displayMessage += ("Retrieved Book: " +
                                "\nId=" + _retrievedBook.Id +
                                "\nTitle=" + _retrievedBook.Title +
                                "\nISBN=" + _retrievedBook.ISBN);
        string authors = "";
        foreach(string author in _retrievedBook.BookAuthors)
            authors += author + ",";
        this.displayMessage += "\nBookAuthor= "+ authors;
        this.displayMessage += ("\nDimensions= "+ _retrievedBook.Dimensions.Length + " X " +
                                _retrievedBook.Dimensions.Height + " X " +
                                _retrievedBook.Dimensions.Thickness);

    }, null);
}
```

## 更新书籍
<a name="update-a-book"></a>

```
private void PerformUpdateOperation()
{
    // Retrieve the book.
    Book bookRetrieved = null;
    Context.LoadAsync<Book>(bookID,(result)=>
    {
        if(result.Exception == null )
        {
            bookRetrieved = result.Result as Book;
            // Update few properties.
            bookRetrieved.ISBN = "222-2222221001";
            // Replace existing authors list with this
            bookRetrieved.BookAuthors = new List<string> { "Author 1", "Author x" };
            Context.SaveAsync<Book>(bookRetrieved,(res)=>
            {
                if(res.Exception == null)
                     resultText.text += ("\nBook updated");
            });
        }
   });
}
```

## 删除书籍
<a name="delete-a-book"></a>

```
private void PerformDeleteOperation()
{
    // Delete the book.
    Context.DeleteAsync<Book>(bookID,(res)=>
    {
        if(res.Exception == null)
        {
            Context.LoadAsync<Book>(bookID,(result)=>
            {
                 Book deletedBook = result.Result;
                 if(deletedBook==null)
                     resultText.text += ("\nBook is deleted");
            });
        }
   });
}
```