![c0b366b1ffb87d0a7a7cc35c60067617.png](https://i-blog.csdnimg.cn/blog_migrate/a6e608860484479e7e5f56e52451c86a.png)
此文章代码均在github repository中:
yjf27281181/dynamodb-demogithub.com![aaa61f384a54585b448fa2856aa2b734.png](https://i-blog.csdnimg.cn/blog_migrate/8c3e486d99bc5841054811c725eb7bc0.jpeg)
本文前置知识:
颜小四:通俗易懂之DynamoDB(一) ----分区键、排序键、GSIzhuanlan.zhihu.com![73fe3fa20a5d4df69474da60cd416af5.png](https://i-blog.csdnimg.cn/blog_migrate/1bdbb3b620a3fc71f7a270687a8194d4.png)
![73fe3fa20a5d4df69474da60cd416af5.png](https://i-blog.csdnimg.cn/blog_migrate/1bdbb3b620a3fc71f7a270687a8194d4.png)
正文
对于DynamoDB的操作,官方提供了两种API来操作数据库,一种是纯java api
https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/GettingStarted.Java.01.htmldocs.aws.amazon.com一种是使用Spring注解:
https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/DynamoDBMapper.htmldocs.aws.amazon.com由于通常情况下项目都为spring项目,所以我们采用第二种方式来实现对dynamoDB进行操作。
虽然官方已经提供了大量api,但是手动调用时还是非常麻烦,所以我建议使用第三方库spring-data-dynamodb,该库对很多api进行了封装,方便许多:
spring-data-dynamodbgithub.com第一步:引入第三方包:
在maven中引入上述第三方库:
<dependency>
<groupId>com.github.derjust</groupId>
<artifactId>spring-data-dynamodb</artifactId>
<version>5.0.4</version>
</dependency>
注意,该版本与springboot 2.1x版本不兼容,需要使用springboot 2.0.9-release版
引入之后开始编写实体类,我们以user 类为例,首先我们来编写Id类:
UserId.java:
@ToString
id类一定要单独写出来,不能够直接写在实体类里面。
User.java:
@DynamoDBTable
注解说明:
@DynamoDBAutoGeneratedKey: 生成UUID
@DynamoDBHashKey(attributeName ="pk") 该属性为partition key,映射到表的pk属性上
@DynamoDBRangeKey(attributeName ="sk") 该属性为sort key,映射到表的sk属性上
@DynamoDBIgnore 由于DynamoDB在存储时会对所有以get为开头的方法进行映射(比如getName会将getName的结果映射到name属性上),而为了方便,我试用了Lombok来生成get函数,所以里面会有getUserId,这个函数,由于UserId是个复杂类,无法映射到数据库中,所以必须手动忽略。
有了这个实体类后,我们创建一个User实体,然后想办法存到数据库中:
@Component
可以看到,我们使用了userRepository的save方法进行了存储,接下来看UserRepository这个类:
UserRepository.java:
@EnableScan
没错,就是这么简单,定义一个继承了CrudRepository的接口之后,你就能使用了。
这里简单说一下具体原理:第三方库Spring-data-dynamodb使用aop的形式对CrudRepository中的操作进行拦截,然后使用DynamoDBTemplate类中相应的方法进行操作,比如save方法,对应到DynamoDBTemplate中就是:
@Override
可以看到其实最后依然是调用了官方api中dynamoDBMapper里的方法
findBy方法:
spring-data-dynamodb提供了一个轻便的api:findBy[属性名]。比如说,在UserRepository接口中,用户可以自定义自己的方法:
@EnableScan
且这些方法不需要用户自己实现,spring-data-dynamodb就会帮你实现这个方法,你要做的就是用就可以了:
@Component
打印结果:
![3b4018809890e0ab1b0eaaf5f9aa9783.png](https://i-blog.csdnimg.cn/blog_migrate/e52118ecb44c9ea7cf8d73ce51a5d8e9.png)
可是遗憾的是,如果我们通过debug进去看一下就会发现:
![095a9102182c57aa3764680fcaad01a8.png](https://i-blog.csdnimg.cn/blog_migrate/8013e9a1fa16da83a9628ad1120f9ab8.png)
Spring-data-dynamodb是通过AOP调用了dynamoDBMapper中的scan方法来做的查询,这是一个全表扫描操作,效率很慢,不建议使用。
自定义查询方法
虽然Spring-data-dynamodb做了多层封装,但是我们还是要自己实现很多操作,比如说对于GSI的查询操作。接下来,就说明一下如何通过官方api DynamoDBMapper实现自定义查询。
要在Spring-data-dynamodb的基础上实现自定义查询,首先我们需要一个接口,接口的命名方式为:xxxAdditionRepository,比如说用户就是UserAdditionRepository:
public
在这个里面,我们定义一个方法,通过GSI来查询User。
接下来,我们现在database里建立一个GSI
![b1242b3b20c8b5cd53e7161a25aa1266.png](https://i-blog.csdnimg.cn/blog_migrate/7c85d0ab0c2db97863d38bab6e1af914.jpeg)
可以看到,我们用firstName作为了GSI的partition key, lastName作为GSI的sort key
与之对应的,我们需要在User.java类的
getFirstName上加入注解,表示这个属性是GSI的partition key:
getLastName加入注解,表示这个属性是GSI的sort key:
![a217b6f9d1c81d43bc6dd5910f7add83.png](https://i-blog.csdnimg.cn/blog_migrate/33ecb84939cac3d192ee3bf86bc1c768.png)
现在我们再插入几个User实体
![50063215190a8c5d59cba34bd1ad2833.png](https://i-blog.csdnimg.cn/blog_migrate/d10058f73add790f578f05b9c8d40239.jpeg)
接下来我们新建一个类UserRepositoryImpl (注意,不是UserAddtionRepositoryImpl,这个命名有要求) 实现UserAddtionRepository接口:
@Repository
在这个方法中,我们可以灵活使用官方提供的DynamoDBMapper来实现任意操作:
https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.htmldocs.aws.amazon.com最后,让初始的UserRepository继承这个接口即可。
@EnableScan
接下来,测试结果:
List
![f2e0b5724796bb30aa9b0fc77efdb05d.png](https://i-blog.csdnimg.cn/blog_migrate/d5226cc57df99066a6a1d7e0eedaed30.png)
成功通过GSI查询到了数据。
以上是我目前学习到的DynamoDB所有的基本操作。