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

news2024/12/26 0:02:11

参考资料

  • 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();
			
			// 输出item
            if (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>();

        // 构造item
        itemValues.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);  
  
  // 在表中插入item
  custTable.putItem(custRecord);  
  
} catch (DynamoDbException e) {  
    System.err.println(e.getMessage());  
    System.exit(1);  
}

查看item插入成功

在这里插入图片描述

rust低级api操作

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

创建表

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

话说就这一点东西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.coloradmin.cn/o/403872.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

正则表达式引擎NFA自动机的回溯解决方案总结

前几天线上一个项目监控信息突然报告异常&#xff0c;上到机器上后查看相关资源的使用情况&#xff0c;发现 CPU 利用率将近 100%。通过 Java 自带的线程 Dump 工具&#xff0c;我们导出了出问题的堆栈信息。 我们可以看到所有的堆栈都指向了一个名为 validateUrl 的方法&#…

【C语言】每日刷题 —— 牛客语法篇(4)

&#x1f680;&#x1f680;前言 大家好&#xff0c;继续更新专栏 c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&am…

Mr. Cappuccino的第48杯咖啡——冒泡APP(升级版)之基于Docker部署企业级Maven私服

冒泡APP&#xff08;升级版&#xff09;之基于Docker部署企业级Maven私服基于Docker安装Nexus登录Maven私服配置Maven仓库配置settings.xml和pom.xml项目实践及常见问题基于Docker安装Nexus 查看sonatype/nexus镜像版本 下载指定版本的镜像 docker pull sonatype/nexus3:3.48…

【C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)

C语音经典题型1. 在屏幕上输出9*9乘法口诀表2. 求10 个整数中最大值3. 计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值&#xff0c;打印出结果4. 编写程序数一下 1到 100 的所有整数中出现多少个数字95. 能把函数处理结果的二个数据返回给主调函数6. 实现一个函数&#xff0c;…

Https 笔记

HTTP TLS TLS 的前身是 SSL 非对称加密的核心&#xff1a; 两个密钥&#xff08;公私&#xff09; https 需要第三方CA&#xff08;证书授权中心&#xff09;申请SSL证书以确定其真实性 证书种包含了特定的公钥和私钥 密钥交换 自己将私钥上锁后发给对方对方也上锁 在还回来…

【2023包河区】题解

今天早上也是打完了包河区&#xff0c;不得不说是太 了 所以说&#xff0c;还是水一篇文章吧 T1 签到题 超级简单题吧&#xff0c;用max_score和max_name来计最大的名字和分数。 int n;scanf("%d",&n); int score,max_score; string name,max_name;对于一个新…

Windows修改Docker安装目录修改Docker镜像目录,镜像默认存储位置存放到其它盘

Windows安装Docker&#xff0c;默认是安装在C盘&#xff0c;下载镜像后会占用大量空间&#xff0c;这时需要调整镜像目录&#xff1b;场景&#xff1a;不想连服务器或者没有服务器&#xff0c;想在本地调试服务&#xff0c;该需求就非常重要。基于WSL2安装docker后&#xff0c;…

【Java】数组

目录 1.数组的定义与初始化 2.遍历数组 3.认识null 4.引用变量 5.返回多个值 6.数组拷贝 7.数组逆序 8.数组填充 9.小练习 //将整形数组转化为字符串 //二分查找优化 //冒泡排序优化 10.二维数组 //遍历二维数组 //不规则的二维数组 1.数组的定义与初始化 int…

了解国外SEO负面压制的现状与应对策略!

随着全球化的发展&#xff0c;越来越多的企业和品牌开始将目光转向海外市场&#xff0c;而谷歌作为全球最大的搜索引擎之一&#xff0c;也成为了外贸企业最主要的搜索引擎之一。 然而&#xff0c;随着谷歌的不断发展&#xff0c;国外SEO负面压制的现状也愈发严峻&#xff0c;外…

Android 9.0 Settings主菜单去掉自定义您的设备功能

1.前言 在9.0的系统rom定制化开发中,在系统Settings主页面一级菜单中,在开启护眼模式和改变系统密度的功能操作时,这时会发现在主菜单的网络菜单头部增加 自定义您的设备和设置护眼模式时间安排 等等相关的设置模块 这对于菜单布局显示相当不美观,产品要求不需要显示这些,…

SpringSecurity学习(四)密码加密、RememberMe记住我

文章目录密码加密一、简介密码为什么要加密常见的加密解决方案PasswordEncoder详解DelegatingPasswordEncoder二、自定义加密方式1. 使用灵活的密码加密方案&#xff08;BCryptPasswordEncoder&#xff09;加密验证&#xff08;推荐&#xff09;需要在密码前指定加密类型{bcryp…

Java学习笔记 --- Servlet(2)

一、HttpServletRequest类 1、基本介绍 每次只要有请求进入 Tomcat 服务器&#xff0c;Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法&#xff08;doGet 和 doPost&#xff09;中给我们使用。我们可以通过 HttpServletR…

渗透测试 | Email信息收集

0x00 免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担…

微服务保护(Sentinel)

1.雪崩微服务链路上某个服务出现了问题&#xff0c;结果导致整个微服务调用链上所有服务都出现了问题&#xff0c;这就是雪崩。2.解决雪崩问题的常见方式有四种1.超时处理&#xff1a;设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&#xff0c;不会无休止等…

人工智能简单应用1-OCR分栏识别:两栏识别三栏识别都可以,本地部署完美拼接

大家好&#xff0c;我是微学AI&#xff0c;今天给大家带来OCR的分栏识别。 一、文本分栏的问题 在OCR识别过程中&#xff0c;遇到文字是两个分栏的情况确实是一个比较常见的问题。通常情况下&#xff0c;OCR引擎会将文本按照从左到右&#xff0c;从上到下的顺序一行一行地识别…

软考高项——信息文档管理

信息文档管理信息文档管理文档分类文档质量等级文档管理的规则和方法信息文档管理 信息文档管理的总线索包括&#xff1a; 1&#xff09;文档分类 2&#xff09;文档质量等级 3&#xff09; 文档分类 1、开发文档 开发过程中用到的文档 &#xff08;可行性报告、任书、需求、…

Django实践-06导出excel/pdf/echarts

文章目录Django实践-06导出excel/pdf/echartsDjango实践-06导出excel/pdf/echarts导出excel安装依赖库修改views.py添加excel导出函数修改urls.py添加excel/运行测试导出pdf安装依赖库修改views.py添加pdf导出函数修改urls.py添加pdf/生成前端统计图表修改views.py添加get_teac…

Qt读xml文件

QXmlStreamReaderQXmlStreamReader类通过简单的流式API为我们提供了一种快速的读取xml文件的方式。他比Qt自己使用的SAX解析方式还要快。所谓的流式读取即将一个xml文档读取成一系列标记的流&#xff0c;类似于SAX。而QXmlStreamReader类和SAX的主要区别就是解析这些标记的方式…

Linux自动化交互命令expect测试

介绍 expect 是由Don Libes基于Tcl&#xff08;Tool Command Language &#xff09;语言开发的&#xff0c;主要应用于自动化交互式操作的场景&#xff0c;借助Expect处理交互的命令&#xff0c;可以将交互过程如&#xff1a;ssh登录&#xff0c;ftp登录等写在一个脚本上&#…

RabbitMQ系列(1)--RabbitMQ简介

1、RabbitMQ概念RabbitMQ是一个消息中间件&#xff0c;不对消息进行处理&#xff0c;只对消息做接收、存储和转发。2、RabbitMQ四大核心概念(1)生产者产生数据发送信息的程序(2)交换机交换机是RabbitMQ中一个非常重要的部件&#xff0c;接收来着生产者的消息并把消息推送到队列…