当前位置: 首页 > news >正文

aws dynamodb java低等级api和高级客户端api的使用

参考资料

  • https://docs.amazonaws.cn/zh_cn/sdk-for-java/latest/developer-guide/setup-project-maven.html

初始化环境

创建maven项目

mvn org.apache.maven.plugins:maven-archetype-plugin:3.1.2:generate \-DarchetypeArtifactId="maven-archetype-quickstart" \-DarchetypeGroupId="org.apache.maven.archetypes" \-DarchetypeVersion="1.4" \-DgroupId="com.zhojiew.myapp" \-DartifactId="ddbapp" 

加载依赖

https://mvnrepository.com/artifact/software.amazon.awssdk/bom/latest

配置maven依赖

<project><dependencyManagement><dependencies><dependency><groupId>software.amazon.awssdk</groupId><artifactId>bom</artifactId><version>2.20.21</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>software.amazon.awssdk</groupId><artifactId>dynamodb</artifactId></dependency><dependency><groupId>software.amazon.awssdk</groupId><artifactId>dynamodb-enhanced</artifactId></dependency></dependencies>...
</project>

java低级api操作

官方文档和示例仓库中有非常详细的样例,例如以下创建删除表,注意流程如下

  • 初始化区域和凭证
  • 初始化ddb客户端
  • 构造请求参数
  • 发送请求接受响应
// 初始化客户端
Region region = Region.CN_NORTH_1;  
ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();  
DynamoDbClient ddb = DynamoDbClient.builder().region(region).build();DynamoDbWaiter dbWaiter = ddb.waiter();  //初始化ddb客户端请求,创建复合主键表
CreateTableRequest request = CreateTableRequest.builder() //设置属性字段 .attributeDefinitions(  AttributeDefinition.builder().attributeName(keypart).attributeType(ScalarAttributeType.S).build(),  AttributeDefinition.builder().attributeName(keyrange).attributeType(ScalarAttributeType.S).build()  )  // 指定分区和排序键.keySchema(  KeySchemaElement.builder().attributeName(keypart).keyType(KeyType.HASH).build(),  KeySchemaElement.builder().attributeName(keyrange).keyType(KeyType.RANGE).build()  )  // 预置读写容量5.provisionedThroughput(ProvisionedThroughput.builder()  .readCapacityUnits(new Long(5))  .writeCapacityUnits(new Long(5))  .build())  .tableName(tableName)  .build();  // 返回值  
String newTable = "";  try {  // 创建表CreateTableResponse response = ddb.createTable(request);  DescribeTableRequest tableRequest = DescribeTableRequest.builder()  .tableName(tableName)  .build();  // 等待请求返回WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest);  waiterResponse.matched().response().ifPresent(System.out::println);  newTable = response.tableDescription().tableName();  return newTable;  } catch (DynamoDbException e) {  System.err.println(e.getMessage());  System.exit(1);  
}// 初始化删除请求
DeleteTableRequest request = DeleteTableRequest.builder()  .tableName("ThreeKingdoms")  .build();
// 删除表
try {  ddb.deleteTable(request);  
} catch (DynamoDbException e) {  System.err.println(e.getMessage());  System.exit(1);  
}

查询item(同步)

public static void getDynamoDBItem(DynamoDbClient ddb,String tableName,String key,String keyVal ) {HashMap<String,AttributeValue> keyToGet = new HashMap<String,AttributeValue>();// 初始化键参数keyToGet.put(key, AttributeValue.builder().s(keyVal).build());// 构造请求GetItemRequest request = GetItemRequest.builder().key(keyToGet).tableName(tableName).build();try {Map<String,AttributeValue> returnedItem = ddb.getItem(request).item();// 输出itemif (returnedItem != null) {Set<String> keys = returnedItem.keySet();System.out.println("Amazon DynamoDB table attributes: \n");for (String key1 : keys) {System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());}} else {System.out.format("No item found with the key %s!\n", key);}} catch (DynamoDbException e) {System.err.println(e.getMessage());System.exit(1);}}

插入item

    public static void putItemInTable(DynamoDbClient ddb,String tableName,String key,String keyVal,String albumTitle,String albumTitleValue,String awards,String awardVal,String songTitle,String songTitleVal){HashMap<String,AttributeValue> itemValues = new HashMap<String,AttributeValue>();// 构造itemitemValues.put(key, AttributeValue.builder().s(keyVal).build());itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());itemValues.put(awards, AttributeValue.builder().s(awardVal).build());// 给否在请求PutItemRequest request = PutItemRequest.builder().tableName(tableName).item(itemValues).build();try {ddb.putItem(request);System.out.println(tableName +" was successfully updated");} catch (ResourceNotFoundException e) {...}}

从以上的流程可知,低等级的api需要手动构造请求参数和发送请求,属于一种过程式的客户端。用户需要控制请求的具体参数,实际上就是awscli的java版本调用

  • 对于创建表来说,需要指定表名,键名,读写容量等。
  • 对于item的操作会更复杂,需要手动构造item的请求,尽管有batch操作的api仍旧较为繁琐。

java高级api操作

我们主要来看java的高级api操作

https://docs.amazonaws.cn/zh_cn/sdk-for-java/latest/developer-guide/examples-dynamodb-enhanced.html
DynamoDB 增强版客户端是一个高级库,是Amazon SDK for Java版本 2 (v2) 的一部分。它提供一种将客户端类映射到 DynamoDB 表的直接方法。您可以在代码中定义表与其相应模型类之间的关系。定义这些关系后,您可以直观地对 DynamoDB 中的表或项目执行各种创建、读取、更新或删除 (CRUD) 操作

img

需要在java项目中额外导入依赖

<dependency><groupId>software.amazon.awssdk</groupId><artifactId>dynamodb-enhanced</artifactId>
</dependency>

DynamoDbEnhancedClient实例用于处理 DynamoDB 表和映射类。DynamoDbEnhancedClient从现有DynamoDbClient对象创建

之前接触过一些SSM和SSH框架,有点类似与hibernate的DAO映射,通过注解完成POJO和item的映射,用户就不需要写CRUD操作了,更像是一种声明式的写法。

第一步生成TableSchema

  • v2的java sdk包括一组注解用来快速生成TableSchema用于将类映射到表的注释
  • 例如以下POJO,注解指定了分区键和排序键
@DynamoDbBean  
public class Customer {  private String id;  private String name;  private String email;  private Instant regDate;  @DynamoDbPartitionKey  public String getId() {  return this.id;  }  public void setId(String id) {  this.id = id;  }  public String getCustName() {  return this.name;  }  public void setCustName(String name) {  this.name = name;  }  @DynamoDbSortKey  public String getEmail() {  return this.email;  }  public void setEmail(String email) {  this.email = email;  }  public Instant getRegistrationDate() {  return regDate;  }  public void setRegistrationDate(Instant registrationDate) {  this.regDate = registrationDate;  }  @Override  public String toString() {  return "Customer [id=" + id + ", name=" + name + ", email=" + email  + ", regDate=" + regDate + "]";  }  
}

创建表

https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/enhanced/EnhancedCreateTable.java

public static void main(String[] args) {  // 初始化客户端DynamoDbClient ddb = DynamoDbClient.builder().region(Region.CN_NORTH_1).build();  DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()  .dynamoDbClient(ddb)  .build();  // 从Bean tableschema创建表请求DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));  // 创建表customerTable.createTable(builder -> builder  .provisionedThroughput(b -> b  .readCapacityUnits(5L)  .writeCapacityUnits(5L)  .build())  );  System.out.println("Waiting for table creation...");  // 等待表创建,获取响应try (DynamoDbWaiter waiter = DynamoDbWaiter.create()) {  ResponseOrException<DescribeTableResponse> response = waiter  .waitUntilTableExists(builder -> builder.tableName("Customer").build())  .matched();  DescribeTableResponse tableDescription = response.response().orElseThrow(  () -> new RuntimeException("Customer table was not created."));  System.out.println(tableDescription.table().tableName() + " was created.");  }  
}

控制台查看表创建结果

  • 默认情况下,类名和表名一致
  • 字段名和键名一致

在这里插入图片描述

再来看看item的相关示例

  • 此时我们只需要构造实例,然后使用高级客户端插入item即可
  • 比起低级api开发效率更高了
DynamoDbClient ddb = DynamoDbClient.builder().region(Region.CN_NORTH_1).build();  
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()  .dynamoDbClient(ddb)  .build();  
try {  DynamoDbTable<Customer> custTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));  // 构造item LocalDate localDate = LocalDate.parse("2020-04-07");  LocalDateTime localDateTime = localDate.atStartOfDay();  Instant instant = localDateTime.toInstant(ZoneOffset.UTC);  Customer custRecord = new Customer();  custRecord.setCustName("Tom red");  custRecord.setId("id101");  custRecord.setEmail("tred@noserver.com");  custRecord.setRegistrationDate(instant);  // 在表中插入itemcustTable.putItem(custRecord);  } catch (DynamoDbException e) {  System.err.println(e.getMessage());  System.exit(1);  
}

查看item插入成功

在这里插入图片描述

rust低级api操作

不得不说,java低级api的写法有点繁琐,对比下rust看看

创建表

说实话下面的这段代码咱只能看懂和java类似的部分,至于tokio和strucopt看不太懂,需要继续学习下rust,现在先抄着用吧

$ cat Cargo.toml
[package]
name = "rustdemo"
version = "0.1.0"
edition = "2021"[dependencies]
aws-config = "0.54.1"
aws-sdk-dynamodb = "0.24.0"
structopt = "0.3.26"
tokio = { version = "1.26.0", features = ["full"] }
tracing-subscriber = "0.3.16"

话说就这一点东西debug编译之后有187M,而release只有17M

use aws_sdk_dynamodb::{model::{AttributeDefinition, KeySchemaElement, KeyType, ProvisionedThroughput, ScalarAttributeType,},Client, Error,
};
use aws_config::meta::region::RegionProviderChain;
use aws_sdk_dynamodb::{ Region, PKG_VERSION};
use structopt::StructOpt;#[derive(Debug, StructOpt)]
struct Opt {/// The AWS Region.#[structopt(short, long)]region: Option<String>,/// Whether to display additional information.#[structopt(short, long)]verbose: bool,
}#[tokio::main]
async fn main() -> Result<(), Error> {tracing_subscriber::fmt::init();let Opt { region, verbose } = Opt::from_args();let region_provider = RegionProviderChain::first_try(region.map(Region::new)).or_default_provider().or_else(Region::new("cn-north-1"));println!();if verbose {println!("DynamoDB client version: {}", PKG_VERSION);println!("Region:                  {}",region_provider.region().await.unwrap().as_ref());println!();}let shared_config = aws_config::from_env().region(region_provider).load().await;let client = Client::new(&shared_config);list_tables(&client).await?;create_table(&client).await
}async fn list_tables(client: &Client) -> Result<(), Error> {let tables = client.list_tables().send().await?;println!("Current DynamoDB tables: {:?}", tables);Ok(())
}async fn create_table(client: &Client) -> Result<(), Error> {let new_table = client.create_table().table_name("test-table").key_schema(KeySchemaElement::builder().attribute_name("k").key_type(KeyType::Hash).build(),).attribute_definitions(AttributeDefinition::builder().attribute_name("k").attribute_type(ScalarAttributeType::S).build(),).provisioned_throughput(ProvisionedThroughput::builder().write_capacity_units(5).read_capacity_units(5).build(),).send().await?;println!("new table: {:#?}",&new_table.table_description().unwrap().table_arn().unwrap());Ok(())
}

执行试试

$ ./rustdemo 
2023-03-11T11:22:12.870149Z  INFO aws_credential_types::cache::lazy_caching: credentials cache miss occurred; retrieved new AWS credentials (took 7.115433ms)
Current DynamoDB tables: ListTablesOutput { table_names: Some(["AppSyncCommentTable-JiXcP7eW", "AppSyncEventTable-JiXcP7eW", "Music", "http-crud-tutorial-items", "learnddb"]), last_evaluated_table_name: None }
new table: "arn:aws-cn:dynamodb:cn-north-1:xxxxxxxxxxx:table/test-table"

总结一下

  • api的使用就是照着文档抄没什么好说的,毕竟是不开源的东西会用就行,最重要的还是理解不同层次的api的区别

  • 之后可以将ayysync,dynamodb和apigateway集成看看有什么火花

http://www.lryc.cn/news/38717.html

相关文章:

  • Kafka中那些巧妙的设计
  • 《JavaEE》进程和线程的区别和联系
  • Matlab生成sinc信号
  • 进程与线程区别与联系
  • 使用vbscript.regexp实现VBA代码格式化
  • 选择结构习题:百分值转换成其相应的等级
  • c# 源生成器
  • [N1CTF 2018]eating_cms1
  • 数据结构与算法基础(王卓)(15):KMP算法详解(含速成套路和详细思路剖析)
  • 【互联网架构】聊一聊所谓的“跨语言、跨平台“
  • 1.JVM常识之 类加载器
  • 一天搞定《AI工程师的PySide2 PyQt5实战开发手册》
  • 身份推理桌游
  • [LeetCode周赛复盘] 第 99 场双周赛20230304
  • Parcel Bundle漏洞学习
  • RTP载荷H264(实战细节)
  • 软考高级信息系统项目管理师系列之四十三:信息系统安全管理
  • 并发编程之AtomicUnsafe
  • GDB调试快速入门
  • Vim一次复制,多次粘贴
  • 如何修改Win11上的默认程序?
  • 安装Linux虚拟机和Hadoop平台教程汇总及踩坑总结
  • Shell脚本的使用和介绍
  • 机械学习 - 基础概念 - scikit-learn - 数据预处理 - 1
  • OLCNE cluster 配置 NFS Storage(英文)
  • RabbitMQ高级特性
  • 利用Dockerfile开发定制镜像实战.
  • PyInstaller 将DLL文件打包进exe
  • 【JVM篇2】垃圾回收机制
  • LeetCode598. 范围求和 II(python)