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)
)