為了方便使用DynamoDBMapper跟POJO存取,本篇進一步使用DAO設計
為了方便切換成使用DynamoDB-Local,我先撰寫了一個極簡取得client的factory
public class DBClientFactory {
private static final boolean useLocal = true;
public static AmazonDynamoDB getAmazonDynamoDB() {
AmazonDynamoDBClientBuilder client = AmazonDynamoDBClientBuilder.standard();
if (useLocal)
client.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://10.0.2.15:8000", "us-west-2"));
return client.build();
}
}
然後我希望實作的介面有load、save、delete
public interface PersonDao {
public Person load(Person person);
public void save(Person person);
public void delete(Person person);
}
接著就可以進行實作了
public class PersonDaoImp implements PersonDao {
private DynamoDBMapper mapper;
public PersonDaoImp() {
mapper = new DynamoDBMapper(DBClientFactory.getAmazonDynamoDB());
}
public static PersonDaoImp getInstance() {
return new PersonDaoImp();
}
@Override
public Person load(Person person) {
return mapper.load(person);
}
@Override
public void save(Person person) {
if (StringUtils.isNullOrEmpty(person.getId())) {
person.setId(UUID.randomUUID().toString());
person.setCreate_date(new Date());
}
person.setUpdate_date(new Date());
mapper.save(person);
}
@Override
public void delete(Person person) {
mapper.delete(person);
}
}
注意這邊使用save時檢查id為空,則當作建立項目,然後也給予create_date及update_date的內容。
對於之前的Person我們要補上DynamoDB註釋
首先是資料表名稱
@DynamoDBTable(tableName="table1")
public class Person {
然後partition key
@DynamoDBHashKey(attributeName = "pk_id")
private String id;
而有個屬性不打算儲存進去,因為是用來變更密碼檢核用的,就可以忽略它
@DynamoDBIgnore
private String password_old
而其他屬性皆使用預設值
get item by person_id的部分,只需要讓Person的id有值即可取得資料
Person person = new Person();
person.setId(person_id);
person = PersonDaoImp.getInstance().load(person);
return new ResponseBean(person, Views.Public.class);
post method 定義是新增資料,所以我們只接受沒有提供 path person_id的request,即是新增項目
if (!StringUtils.isNullOrEmpty(person_id))
return new ResponseBean(500);
PersonDaoImp.getInstance().save(person);
return new ResponseBean(person, Views.idOnly.class);
要記得Person bean當中id的JsonView應當不包含在Views.Request,避免從Json當中取得值
put method 則為新增或完整更新,所以允許從path person_id取得要更新的id
因為之前我們直接透過getBody(Person.class, Views.Request.class)取得person了,只要把path的person_id塞進去就可以了
if (!StringUtils.isNullOrEmpty(person_id))
person.setId(person_id);
PersonDaoImp.getInstance().save(person);
return new ResponseBean(person, Views.idOnly.class);
所以當path沒有person_id的時候仍然進行儲存,就可以建立新項目了
patch則為更新資料,且允許部分更新,所以一定要指定path person_id
if (!StringUtils.isNullOrEmpty(person_id))
return new ResponseBean(500);
PersonDaoImp.getInstance().save(person);
return new ResponseBean(person, Views.idOnly.class);
不過如果僅是這樣,測試過會發現,即便request我們允許只接收部分值,mapper會更新包含未指定值的屬性,就像put完整更新一樣,所以我們之後應該做些調整解決這個問題。
刪除項目就跟getItem差不多,有person_id就可以進行了
Person person = new Person();
person.setId(person_id);
PersonDaoImp.getInstance().delete(person);
return new ResponseBean(200);