LoginSignup
6
5

More than 5 years have passed since last update.

ScalaからDynamoDBを扱うサンプル

Last updated at Posted at 2016-08-31

ScalaからDynamoDB Java SDKを扱う際のサンプルです。足りないAPIは必要に応じて増やしていきます。
各APIを扱う書き方は複数あるので特定のパターンのみ記述しています。

フルのソースコードはこちら

はじめに

aws-java-sdk-dynamodblibraryDependenciesに含めておきます。

build.sbt
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)
  )
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5