AWSメモ > AWS Java SDKでDynamoDBのCRUDを書いてみる †
AWS Java SDK の DynamoDB関連パッケージ †以下の com.amazonaws.services.dynamodbv2 が DynamoDB関連パッケージ。 Java SDK利用時の注意点 †例えば、同じデータ登録を行う場合でも、様々なインターフェースが用意されている為、要件に応じて使い分ける必要がある。 com.amazonaws.services.dynamodbv2.AmazonDynamoDB
com.amazonaws.services.dynamodbv2.document.Table
※さらにバッチWrite 等は com.amazonaws.services.dynamodbv2.document.DynamoDB で提供されている。 個人的には、 AmazonDynamoDB.putItem(PutItemRequest request)、AmazonDynamoDB.updateItem(UpdateItemRequest request) 等の XxxxItemRequest 系を引数にとるメソッドか、 Table.putItem(PutItemSpec spec)、Table.updateItem(UpdateItemSpec spec) 等の XxxxItemSpec 系を引数にとるメソッドを使用しておけば大抵のケースには対応できる気はしている。 逆に、putItem(Item item) などを使用していると、登録結果のデータを戻り値で取得したいケースや、消費したキャパシティユニットを戻り値で得たいケースには対応できない。 ※XxxxItemRequest とか XxxxItemSpec だと withReturnValues や withReturnConsumedCapacity で登録/更新結果や、キャパシティユニットも返却できるようになるので。 DynamoDBMapperについて †Java版のSDKでは、DynamoDBMapper といういわゆるO/Rマッピングツールが提供されている。 テスト用プロジェクトの作成 †https://docs.aws.amazon.com/ja_jp/sdk-for-java/v1/developer-guide/setup-project-maven.html mkdir aws-sdk-java-test && cd aws-sdk-java-test gradle init --type java-application rm -rf src/main/java/* rm -rf src/test/java/* build.gradle の編集 plugins { id 'java' id 'application' } mainClassName = 'ScanTable' dependencies { compile 'com.google.guava:guava:23.0' //compile 'com.amazonaws:aws-java-sdk:latest.release' compile 'com.amazonaws:aws-java-sdk-dynamodb:latest.release' compile 'com.google.code.gson:gson:2.8.2' compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0' testCompile 'junit:junit:4.12' } repositories { jcenter() } run { // 引数で指定されたクラスを実行する if (project.hasProperty('main')) { main(project.main) } } テーブルの作成 †DDL格納用フォルダ作成 †mkdir -p src/test/resources/ddl テーブル定義の作成 †src/test/resources/ddl/SampleTable.json { "TableName": "SampleTable", "AttributeDefinitions": [ { "AttributeName": "pkey", "AttributeType": "S" }, { "AttributeName": "skey", "AttributeType": "S" } ], "KeySchema": [ { "AttributeName": "pkey", "KeyType": "HASH" }, { "AttributeName": "skey", "KeyType": "RANGE" } ], "ProvisionedThroughput": { "WriteCapacityUnits": 1, "ReadCapacityUnits": 1 } } テーブル作成 †aws dynamodb create-table --cli-input-json file://src/test/resources/ddl/SampleTable.json テストデータの登録 †aws dynamodb put-item --table-name SampleTable \ --item '{"pkey": {"S": "test0"}, "skey": {"S": "2018-01-01T00:00:00.001"}, "stringData": {"S": "testdata-001"} }' aws dynamodb put-item --table-name SampleTable \ --item '{"pkey": {"S": "test0"}, "skey": {"S": "2018-01-01T00:00:00.002"}, "stringData": {"S": "testdata-002"} }' aws dynamodb put-item --table-name SampleTable \ --item '{"pkey": {"S": "test0"}, "skey": {"S": "2018-01-01T00:00:00.003"}, "stringData": {"S": "testdata-003"} }' aws dynamodb put-item --table-name SampleTable \ --item '{"pkey": {"S": "test0"}, "skey": {"S": "2018-01-01T00:00:00.004"}, "stringData": {"S": "testdata-004"} }' aws dynamodb put-item --table-name SampleTable \ --item '{"pkey": {"S": "test0"}, "skey": {"S": "2018-01-01T00:00:00.005"}, "stringData": {"S": "testdata-005"} }' 処理(CRUD)の作成 †検索処理(scan) †src/main/java/ScanTable.java import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.ScanRequest; import com.amazonaws.services.dynamodbv2.model.ScanResult; import java.util.List; import java.util.Map; public class ScanTable { private static AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().build(); public static void main(String[] args){ ScanRequest request = new ScanRequest("SampleTable"); ScanResult result = amazonDynamoDB.scan(request); Integer count = result.getCount(); System.out.println("#########################################"); System.out.println("count: " + count ); List<Map<String,AttributeValue>> items = result.getItems(); for (Map<String,AttributeValue> item : items) { System.out.println(item); } System.out.println("#########################################"); } } テスト実行 gradle run -Pmain=ScanTable 登録処理 †src/main/java/PutItem.java import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.PutItemRequest; import com.amazonaws.services.dynamodbv2.model.PutItemResult; import java.time.format.DateTimeFormatter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class PutItem { private static AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().build(); public static void main(String[] args){ String datetime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS")); String pkey = "test1"; String skey = datetime; String stringData = "testdata-" + UUID.randomUUID().toString(); Map<String,AttributeValue> item = new HashMap<String,AttributeValue>(); item.put("pkey" , new AttributeValue().withS(pkey)); item.put("skey" , new AttributeValue().withS(skey)); item.put("stringData" , new AttributeValue().withS(stringData)); PutItemResult result = amazonDynamoDB.putItem(new PutItemRequest("SampleTable", item)); System.out.println("#########################################"); System.out.println(result); System.out.println("#########################################"); } } テスト実行 gradle run -Pmain=PutItem 検索処理(query) †src/main/java/QueryTable.java import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.ComparisonOperator; import com.amazonaws.services.dynamodbv2.model.Condition; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.QueryRequest; import com.amazonaws.services.dynamodbv2.model.QueryResult; import java.util.HashMap; import java.util.List; import java.util.Map; public class QueryTable { private static AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().build(); public static void main(String[] args){ QueryRequest request = new QueryRequest("SampleTable"); Map<String,Condition> keyConditions = new HashMap<String,Condition>(); keyConditions.put("pkey", new Condition().withComparisonOperator(ComparisonOperator.EQ).withAttributeValueList(new AttributeValue("test1"))); request.setKeyConditions(keyConditions); // KeyConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues を使用する場合 /* request.setKeyConditionExpression("#pkey = :pkey"); request.setExpressionAttributeNames(new HashMap<String,String>(){ {put("#pkey", "pkey");} }); request.setExpressionAttributeValues(new HashMap<String,AttributeValue>(){ {put(":pkey", new AttributeValue("test1"));} }); */ QueryResult result = amazonDynamoDB.query(request); Integer count = result.getCount(); System.out.println("#########################################"); System.out.println("count: " + count ); List<Map<String,AttributeValue>> items = result.getItems(); for (Map<String,AttributeValue> item : items) { System.out.println(item); } System.out.println("#########################################"); } } テスト実行 gradle run -Pmain=QueryTable 更新処理(update) †src/main/java/UpdateItem.java import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest; import com.amazonaws.services.dynamodbv2.model.UpdateItemResult; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class UpdateItem { private static AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().build(); public static void main(String[] args){ Map<String, String> attributeNames = new HashMap<String,String>(){{ put("#stringData", "stringData"); } }; Map<String, AttributeValue> attributeValues = new HashMap<String, AttributeValue>(){{ put(":stringData", new AttributeValue().withS("testdata-" + UUID.randomUUID().toString())); } }; Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("pkey", new AttributeValue().withS("test0")); key.put("skey", new AttributeValue().withS("2018-01-01T00:00:00.001")); UpdateItemRequest request = new UpdateItemRequest() .withTableName("SampleTable") .withKey(key) //.withConditionExpression("#other = :other") // 条件付き更新を行う場合 .withUpdateExpression("set #stringData = :stringData") .withExpressionAttributeNames(attributeNames) .withExpressionAttributeValues(attributeValues); UpdateItemResult result = amazonDynamoDB.updateItem(request); System.out.println("#########################################"); System.out.println(result); System.out.println("#########################################"); } } テスト実行 gradle run -Pmain=UpdateItem 削除処理(delete) †src/main/java/DeleteItem.java import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.DeleteItemRequest; import com.amazonaws.services.dynamodbv2.model.DeleteItemResult; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class DeleteItem { private static AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard().build(); public static void main(String[] args){ Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("pkey", new AttributeValue().withS("test0")); key.put("skey", new AttributeValue().withS("2018-01-01T00:00:00.001")); DeleteItemRequest request = new DeleteItemRequest() .withTableName("SampleTable") .withKey(key); DeleteItemResult result = amazonDynamoDB.deleteItem(request); System.out.println("#########################################"); System.out.println(result); System.out.println("#########################################"); } } テスト実行 gradle run -Pmain=DeleteItem |