JavaによるDynamoDBへのアクセス
AWS SDK for Javaを用いることで、JavaプログラムからDynamoDBにアクセスすることができる。DynamoDBはHashKeyでインデックス化されており、Itemの追加や更新には当該テーブルのHashKeyの情報が必要となる。
DynamoDBインスタンスを取得
Credentialsやテーブル名を指定してDynamoDBインスタンスを指定する。リージョンを明示的に指定しないとデフォルトではバージニア州が指定されてしまう。通常credentialsは、ホームディレクトリ直下の「.aws」ディレクトリ(~/.aws/credentials)に置かれている。
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
// ProfileCredentialsProvider
credentialsProvider = new ProfileCredentialsProvider();
try {
credentialsProvider.getCredentials();
} catch (Exception e) {
throw new AmazonClientException("Cannot load the credentials from the credential profiles file. "
+ "Please make sure that your credentials file is at the correct "
+ "location (/Users/hoge/.aws/credentials), and is in valid format.", e);
}
// AmazonDynamoDBClient
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(credentialsProvider);
// リージョンの設定
dynamoDBClient.setRegion(Region.getRegion(Regions.fromName("ap-northeast-1")));
// DynamoDB
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
// DynamoDB Table
Table dynamodbTable = dynamoDB.getTable(TABLE_NAME);
データの取得
getItemメソッドで、HashKeyを指定することでItemの取得が可能となる。HashKeyの「名称」と「値」を指定することで、Itemを取得できる。
dynamodbTable.getItem(HASH_KEY_NAME, HASH_KEY_VAL);
データの書き込み
DynamoDBは空文字を格納することができない。データを格納する前に空文字チェックを行っておく。
データの挿入
putItemメソッドで、Itemの書き込みが可能となる。書き込みを行う際、HashKeyの「名称」と「値」の指定が必須である。なお、同じキーを持つ項目が存在している場合は、全ての値が更新(上書き)される。
Item item = new Item()
.withPrimaryKey(HASH_KEY_NAME, HASH_KEY_VAL)
.withString(key, val);
dynamodbTable.putItem(item);
データの更新
updateItemメソッドで、Itemを更新する。HashKeyの「名称」と「値」を指定することで、どのItemを更新するかが決定される。また更新内容は、SETやADD, REMOVEで始まる更新式によって指定する。なお、同じキーを持つ項目が存在している場合は、指定したAttributeのみ置換される。指定したキーが存在しない場合は、新規の項目が作成される。
// 更新するAttributeの名称(Key)
Map<String,String> resultExpressionAttributeNames = new HashMap<String,String>();
resultExpressionAttributeNames.put("#key", KEY_NAME);
// 更新するAttributeの値(Value)
Map<String,Object> resultExpressionAttributeValues = new HashMap<String,Object>();
resultExpressionAttributeValues.put(":val", VALUE);
// Attributeの更新
dynamodbTable.updateItem(
HASH_KEY_NAME, HASH_KEY_VALUE, // 更新対象のItem(HASH_KEY, VALUE)
"set #key = :val",
resultExpressionAttributeNames,
resultExpressionAttributeValues);
the provided key element does not match the schema javaというエラーが発生した場合は、誤ったHashKeyを指定している可能性があるので確認する。
アトミックカウンター
DynamoDBは、高い可用性やスケーラビリティ(BASE属性)を確保している一方で、厳密な一貫性や即時反映性(ACID属性)を諦めている。しかし、アトミックカウンター(一貫性のあるカウンタ)をサポートしているため、他の処理を妨げることなく並列に、一貫性のあるカウンタ処理を実施することは可能である。
アトミックカウンターをサポートとあるが、アトミックカウンターという特別に用意された機能が存在するわけでもない。updateItemメソッドを利用して以下のような記述をすると、アトミック性のあるカウンタを実装することができる。
Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#key", kEY_NAME);
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);
try {
dynamodbTable.updateItem(
HASH_KEY_NAME, HASH_KEY_VAL,
"ADD #key :val",
expressionAttributeNames,
expressionAttributeValues);
} catch (Exception e) {
}
更新式にて単純に1を加算する処理を行っているだけであるので、プログラムを書き換えることで加算もできれば減算もできる。2を足す、3を引くといったことも可能である。
dynamodbTable.updateItem(
HASH_KEY_NAME, HASH_KEY_VAL,
"SET #key = #key + :val",
expressionAttributeNames,
expressionAttributeValues);
としてもよいが、SETアクションの場合、アイテムが事前に存在しない場合にエラーとなるので、ADDアクションで実装したほうがよい。
DynamoDB操作の違い
なお、DynamoDBのそれぞれの操作の差異は以下の通り。
操作 |
アクション |
既にアイテムが存在している場合の挙動 |
putItem |
|
全ての属性を消去した上で新たに属性を追加する |
updateItem |
SET |
対象の属性のみ更新される |
updateItem |
REMOVE |
対象の属性のみ削除される |
updateItem |
ADD |
対象の属性が数値の場合は値に追加される、セットデータの場合は要素が追加される |
updateItem |
DELETE |
対象の属性のセットデータから要素が削除される |