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 | 対象の属性のセットデータから要素が削除される |