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) 操作

需要在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集成看看有什么火花
相关文章:
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&quo…...
Kafka中那些巧妙的设计
一、kafka的架构 Kafka是一个分布式、多分区、基于发布/订阅模式的消息队列(Message Queue),具有可扩展和高吞吐率的特点。 kafka中大致包含以下部分: Producer: 消息生产者,向 Kafka Broker 发消息的客户…...
《JavaEE》进程和线程的区别和联系
👑作者主页:Java冰激凌 📖专栏链接:JavaEE 目录 进程是什么? 线程是什么? 进程和线程之间的联系~ ps1:假设我们当前的大兴国际机场有一条登机口可以登入飞机 ps2:我们为…...
Matlab生成sinc信号
Matlab生成sinc信号 在Matlab中生成sinc信号非常容易。首先,我们需要了解什么是sinc波形。 sinc波形是一种理想的信号,它在时域上是一个宽度为无穷的矩形函数,而在频域上则是一个平的频谱。它的公式为: sinc(x)sin(πx)πx\…...
进程与线程区别与联系
进程与线程的区别与联系线程线程介绍为什么要有线程呢?线程与进程的区别于联系(重点)线程 线程介绍 我们知道进程就是运行起来的程序, 那线程又是什么呢? 一个线程就是一个 “执行流”. 每个线程之间都可以按照顺序执行自己的代码. 多个线程之间 “同时” 执行着多份代码. …...
使用vbscript.regexp实现VBA代码格式化
Office自带的VBE在编辑代码时,没有自动完成代码缩进的功能,而我们在网上找到的VBA代码,经常没有实现良好的自动缩进,复制到VBE后,可读性较差。本文介绍的宏,通过使用vbscript.regexp对象,利用正…...
选择结构习题:百分值转换成其相应的等级
Description 编一程序,输入一个百分制的成绩(整数类型),按要求输出相应的字符串信息,对应关系为: excellent 90-100 good 80-89 middle 70-79 pass 60-69 fail 60以下或100以上 Input 输入仅一行&…...
c# 源生成器
本文概述了 .NET Compiler Platform(“Roslyn”)SDK 附带的源生成器。 通过源生成器,C# 开发人员可以在编译用户代码时检查用户代码。 生成器可以动态创建新的 C# 源文件,这些文件将添加到用户的编译中。 这样,代码可以…...
[N1CTF 2018]eating_cms1
一个cms,先打开环境试了一下弱口令,无效,再试一下万能密码,告诉我有waf,先不想怎么绕过,直接开扫(信息收集)访问register.php注册一个账号进行登录上面的链接尝试用php读文件http://…...
数据结构与算法基础(王卓)(15):KMP算法详解(含速成套路和详细思路剖析)
如果时间不够,急(忙)着应付考试没心思看,直接参考(照抄)如下套路: PART 1:关于next [ j ] PPT:P30 根据书上以及视频上给出的思路(提醒)&#x…...
【互联网架构】聊一聊所谓的“跨语言、跨平台“
文章目录序跨语言跨平台【饭后杂谈】为什么有人说Java的跨平台很鸡肋?序 很多技术都具有跨语言、跨平台的特点 比如JSON是跨语言的、Java是跨平台的、UniAPP、Electron是跨平台的 跨语言和跨平台,是比较重要的一个特性。这些特性经常能够决定开发者是否…...
1.JVM常识之 类加载器
1.jvm组成 JVM组成: 1.类加载器 2.运行时数据区 3.执行引擎 4.本地库接口 各组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码…...
一天搞定《AI工程师的PySide2 PyQt5实战开发手册》
PySide2/PySide6、PyQt5/PyQt6:都是基于Qt 的Python库,可以形象地这样说,PySide2 是Qt的 亲儿子(Qt官方开发的) , PyQt5 是Qt还没有亲儿子之前的收的 义子 (Riverbank Computing这个公司开发的,有商业版权限…...
身份推理桌游
目录 杀人游戏(天黑请闭眼) (1)入门版 (2)标准版 (3)延伸版——百度百科 (3.1)引入医生和秘密警察 (3.2)引入狙击手、森林老人和…...
[LeetCode周赛复盘] 第 99 场双周赛20230304
[LeetCode周赛复盘] 第 99 场双周赛20230304 一、本周周赛总结二、 [Easy] 2578. 最小和分割1. 题目描述2. 思路分析3. 代码实现三、[Medium] 2579. 统计染色格子数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 2580. 统计将重叠区间合并成组的方案数1. 题目描述2. 思路分析…...
Parcel Bundle漏洞学习
Bundle的序列化细节看上去还是有些复杂的,在之前已经讨论过,一般我们使用Parcel的时候,都是严格的write和read相对应。一些疏漏,不对应,竟然就可以成为漏洞,https://xz.aliyun.com/t/2364 里介绍了Bundle漏…...
RTP载荷H264(实战细节)
RTP包由两部分组成,RTP头和RTP载荷: RTP头 RTP头的 结构如下: 代码结构: typedef struct RtpHdr {uint8_t cc : 4, // CSRC countx : 1, // header extendp : 1, // padding flagversion : 2; // versionuint8_t …...
软考高级信息系统项目管理师系列之四十三:信息系统安全管理
软考高级信息系统项目管理师系列之四十三:信息系统安全管理 一、信息系统安全管理内容二、信息安全策略1.信息系统安全策略的概念与内容2.信息系统安全等级保护的概念三、信息安全系统1.信息安全系统三维空间2.信息安全系统三种架构体系四、PKI公开密钥基础设施1.PKI总体架构2…...
并发编程之AtomicUnsafe
目录 原子操作 定义 术语 处理器如何实现原子操作 处理器自动保证基本内存操作的原子性 使用总线锁保证原子性 使用缓存锁保证原子性 Java当中如何实现原子操作 Atomic 定义 原子更新基本类型类 原子更新数组类 原子更新引用类型 原子更新字段类 Unsafe应用解析…...
GDB调试快速入门
什么是GDB: GDB - - - (GNU symbolic debugger)是Linux平台下最常用的一款程序调试器。 自己的Linux是否安装GDB? 一般来说,使用Ubuntu的话,系统就会自带的有GDB调试器的 命令窗口输入如下命令可以查看是否安装了gdb: gdb -v …...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
