ScalaからDynamoDB Java SDKを扱う際のサンプルです。足りないAPIは必要に応じて増やしていきます。
各APIを扱う書き方は複数あるので特定のパターンのみ記述しています。
フルのソースコードはこちら
はじめに
aws-java-sdk-dynamodbをlibraryDependenciesに含めておきます。
libraryDependencies += "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.29"
dynamodb-localは既に立ち上がってる前提で進めます。
AWS-CLIでサンプルとして使うDynamoDBのテーブルも先に作っておきましょう。
# !/usr/bin/env bash
export AWS_ACCESS_KEY_ID="dummy"
export AWS_SECRET_ACCESS_KEY="dummy"
aws dynamodb --endpoint-url "http://localhost:8000" create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
AmazonDynamoDBClientとmodelをimportしておきます。
collection.JavaConversions._もimportしておくとJavaとScala間でコレクションを自動的に変換してくれるので便利です。
collection.JavaConversions._は非推奨になる可能性があるので、今後はJavaConvertersを使うほうが良いそうです。 参考
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
import com.amazonaws.services.dynamodbv2.model._
// import collection.JavaConversions._
import collection.JavaConverters._
クライアント生成
val client: AmazonDynamoDBClient = (new AmazonDynamoDBClient())
    .withEndpoint("http://localhost:8000")
テーブル一覧
println(client.listTables)
テーブル情報
println(client.describeTable("Music"))
Batch Write
テーブルに複数のアイテムを一度に書き込みます。
  val batchWriteItems: java.util.List[WriteRequest] = Seq(
    new WriteRequest(new PutRequest(
      Map(
        "Artist"    -> new AttributeValue("Rainbow"),
        "SongTitle" -> new AttributeValue("Kill the King"),
        "Member"    -> new AttributeValue(Seq(
          "Ronnie James Dio",
          "Ritchie Blackmore"
        ).asJava)
      ).asJava
    )),
    new WriteRequest(new PutRequest(
      Map(
        "Artist"    -> new AttributeValue("Rainbow"),
        "SongTitle" -> new AttributeValue("All Night Long"),
        "Member"    -> new AttributeValue(Seq(
          "Graham Bonnet",
          "Ritchie Blackmore"
        ).asJava)
      ).asJava
    )),
    new WriteRequest(new PutRequest(
      Map(
        "Artist"    -> new AttributeValue("Metallica"),
        "SongTitle" -> new AttributeValue("Enter Sandman"),
        "Member"    -> new AttributeValue(Seq(
          "James Hetfield",
          "Kirk Hammett"
        ).asJava)
      ).asJava
    )),
    new WriteRequest(new PutRequest(
      Map(
        "Artist"    -> new AttributeValue("Deep Purple"),
        "SongTitle" -> new AttributeValue("Highway Star"),
        "Member"    -> new AttributeValue(Seq(
          "Ian Gillan",
          "Ritchie Blackmore"
        ).asJava)
      ).asJava
    ))
  ).asJava
  println(
    client.batchWriteItem(
      (new BatchWriteItemRequest())
        .withRequestItems(Map("Music" -> batchWriteItems).asJava)
    )
  )
ハッシュキーでクエリ
ハッシュキーを指定してクエリします(prettyPrintメソッドはMapを拡張して追加しています。詳しくはコード)
val hashCondition = new Condition()
    .withComparisonOperator(ComparisonOperator.EQ)
    .withAttributeValueList(new AttributeValue("Rainbow")
  )
  println(
    client.query(
      (new QueryRequest("Music"))
        .withKeyConditions(Map("Artist" -> hashCondition).asJava)
    ).getItems.asScala.map(_.asScala.toMap.prettyPrint)
  )
クエリ + フィルター
フィルター条件を加えてクエリします
val filterCondition = new Condition()
    .withComparisonOperator(ComparisonOperator.EQ)
    .withAttributeValueList(new AttributeValue("Ronnie James Dio")
  )
  println(
    client.query(
      (new QueryRequest("Music"))
        .withKeyConditions(Map("Artist" -> hashCondition).asJava)
        .withQueryFilter(Map("Vocal" -> filterCondition).asJava)
    ).getItems.asScala.map(_.asScala.toMap.prettyPrint)
  )
クエリ + リミット、 さらに続きをクエリ
リミットを掛けてクエリします
val limitQueryResult = client.query(
    (new QueryRequest("Music"))
      .withKeyConditions(Map("Artist" -> hashCondition).asJava)
      .withLimit(1)
  )
  println(
    limitQueryResult.getItems.asScala.map(_.asScala.toMap.prettyPrint)
  )
続きがある場合、LastEvaluatedKeyが取得できるのでExclusiveStartKeyに指定して続きから取得します。
  println(
    client.query(
      (new QueryRequest("Music"))
        .withKeyConditions(Map("Artist" -> hashCondition).asJava)
        .withExclusiveStartKey(limitQueryResult.getLastEvaluatedKey)
    ).getItems.asScala.map(_.asScala.toMap.prettyPrint)
  )
スキャン
全てのアイテムを取得します
println(
    client.scan(
      new ScanRequest("Music")
    ).getItems.asScala.map(_.asScala.toMap.prettyPrint)
  )
