この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Spring BootからDynamoDBにアクセスする際、まず考えるのがAWS SDK for Javaを使うことだと思います(少なくとも私はそうでした)。ですが、もう少しSpringと親和性が高い方法もあるのではないかと思い調べたところSpring Data DynamoDBを見つけました。今回はこのライブラリの使用方法について書きたいと思います。
手順について
ではライブラリの使用手順についてです。Spring Data DynamoDBの使用例をベースとしておりますが
- AWSのアクセスキー・シークレットキーをクレデンシャルより取得するようにした
- CRUDを全て試したみた
などを変更しております。
1.DynamoDBの準備
まずは今回データを登録するDynamoDBをAWS上に作成します。AWSコンソール上で以下のようにテーブルを作成しました。
- テーブル名 ・・・ SpringUser
- プライマリキー ・・・ id
2.build.gradle
以降はプログラムについてです。今回はGradleを使用したのでbuild.gradleに以下のように記述しました。
buildscript {
ext {
springBootVersion = '1.3.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
jar {
baseName = 'SpringBootDynamoDBSample'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile group: 'com.github.derjust', name: 'spring-data-dynamodb', version: '4.2.3'
testCompile('org.springframework.boot:spring-boot-starter-test')
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
build.gradleのベースはSpring Initializrで作成したプロジェクトのものです。これに「spring-data-dynamodb」を追加しました(31行目)。
3.SpringUserクラス
DynamoDBに作成したSpringDataテーブルに対応するクラスです。idの他にfirstName、lastNameを属性として持たせました。
SpringUser.java
package com.example;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
@DynamoDBTable(tableName = "SpringUser")
public class SpringUser {
private String id;
private String firstName;
private String lastName;
public SpringUser(){
}
public SpringUser(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
public String getId()
{
return id;
}
@DynamoDBAttribute
public String getFirstName()
{
return firstName;
}
@DynamoDBAttribute
public String getLastName()
{
return lastName;
}
public void setId(String id){
this.id = id;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
}
クラス名には「@DynamoDBTable」アノテーションで対応するテーブル名を、Getterにもそれぞれ対応するアノテーションを付与しています。
4.SpringUserRepositoryクラス
データを操作するためのリポジトリです。以下のようになります。
SpringUserRepository.java
package com.example.repositories;
import java.util.List;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;
import com.example.SpringUser;
@EnableScan
public interface SpringUserRepository extends CrudRepository<SpringUser, String> {
List<SpringUser> findByLastName(String lastName);
}
5.DynamoDBConfigクラスとapplication.yml
DynamoDBへの接続を定義するDynamoDBConfigクラスと、定義ファイルであるapplication.ymlです。先にも書いたようにDynamoDBConfigクラスでは、AWSのアクセスキー・シークレットキーをアプリ内で保持せず、クレデンシャル(~/.aws/credentialsなど)から取得するようにしました。
DynamoDBConfig.java
package com.example;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
@Configuration
@EnableDynamoDBRepositories(basePackages = "com.example.repositories")
public class DynamoDBConfig {
@Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
@Value("${amazon.credential.profile}")
private String profile;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) {
amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
}
return amazonDynamoDB;
}
@Bean
public AWSCredentials amazonAWSCredentials() {
return new ProfileCredentialsProvider(profile).getCredentials();
}
}
application.yml
amazon:
dynamodb:
endpoint: https://dynamodb.ap-northeast-1.amazonaws.com
credential:
profile: default
DynamoDBConfigクラスはapplication.yml内の定義値(endpoint、profile)を読み取って使用しています。application.ymlのprofileについては、クレデンシャル(~/.aws/credentialsなど)に定義した任意のプロファイル名としてください。
6.Applicationクラス
最後に、ここまで書いたクラスを利用するApplicationクラスです。DynamoDBにデータを登録し、抽出・更新・削除を行います。
Application.java
package com.example;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.example.repositories.SpringUserRepository;
@SpringBootApplication
public class Application {
@Autowired
private SpringUserRepository repository;
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args)) {
Application app = ctx.getBean(Application.class);
app.run(args);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(String... args) throws Exception {
System.out.println("処理開始");
SpringUser taro = new SpringUser("taro", "yamada");
repository.save(taro);
SpringUser jiro = new SpringUser("jiro", "yamada");
repository.save(jiro);
SpringUser saburo = new SpringUser("saburo", "yamada");
repository.save(saburo);
SpringUser takeshi = new SpringUser("takeshi", "suzuki");
repository.save(takeshi);
List<SpringUser> result = repository.findByLastName("yamada");
for(SpringUser user : result){
System.out.println(user.getFirstName() + " " + user.getLastName());
}
jiro.setLastName("tanaka");
repository.save(jiro);
repository.delete(saburo);
System.out.println("処理終了");
}
}
まとめ
Spring Data DynamoDBを使い、CRUDができることが確認できました。リポジトリを通してデータの更新を行うところなどが、DynamoDB固有の処理を上手く隠蔽化しているのではと感じます。何かの時に参考になれば幸いです。