zoukankan      html  css  js  c++  java
  • JAVA AWS 根据Dynamodb增删改查数据

    前言

    dynamodb是AWS的一款非关系型数据库。适用于无需频繁增删改查且关联性不强的大数据,比如某个用户的历史订单信息等。

    历史订单可能不常查询但数据量很大,且只要有用户ID就可以查询出来,类似这种的可以使用非关系型数据库。

    这个例子未必恰当,仅想表达不是任何情况都要使用非关系型数据库,每种数据库都有其存在的意义。(曾经因为这个被坑的很惨)

    进入正题:

    可进入AWS官网查看Java Dynamodb的文档,但我觉得文档写的过大过多,不太好找,所以自己记录下。

    在AWS控制台创建表,创建过程中要制定分区键和排序键,若未创建排序键无法候补,只能删表重建。

    Dynamodb无法分库,因此表名要清楚明了。

    重要::虽然我很菜,写的也不够好,但我不接受任何批评,本文仅供有需要的人参考及自己记录用。

    实体常用注解:映射实体和表的关系,放在getter方法上

    @DynamoDBHashKey 注释分区键
    @DynamoDBRangeKey 注释排序键
    @DynamoDBAttribute 注释普通属性
    @DynamoDBIndexHashKey 注释二级索引分区键
    @DynamoDBIndexRangeKey 注释二级索引排序键
    @DynamoDBIgnore 忽略某个对象或属性
    // 分区键
    @DynamoDBHashKey(attributeName="user_id")
    public String getUserId() {
        return userId;
    }
    
    // 排序键
    @DynamoDBRangeKey(attributeName="event_id")
    public String getEventId() {
        return eventId;
    }
    
    // 二级索引
    @DynamoDBIndexHashKey(globalSecondaryIndexName= "user_name-index", attributeName= "user_name")
    public String getUserName() {
        return userName;
    }
    
    // 属性
    @DynamoDBAttribute(attributeName="user_gender")
    public String getUserGender() {
        return userGender;
    }
    
    // 忽略
    @DynamoDBIgnore
    public Student getStudent() {
        return student;
    }
    
    ...

    代码实现

    注意::

    ① withKeyConditionExpression 针对分区键、排序键的查询条件中,不支持使用contains模糊查询

    ② withFilterExpression 针对其他字段的过滤查询条件,结合limit使用,会先查询,后分页,导致数据变少

    因此Dynamodb无法在模糊查询的同时进行分页。

    Service层

    import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression;
    import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
    import com.amazonaws.services.dynamodbv2.datamodeling.QueryResultPage;
    import com.amazonaws.services.dynamodbv2.datamodeling.ScanResultPage;
    import com.amazonaws.services.dynamodbv2.model.AttributeValue;import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Service
    public class TestService {
    
        @Autowired
        public BaseDao baseDao;
    
        /**
         * Student表: 分区键student_id、二级索引student_name等
         * Teacher表: 分区键teacher_id、排序键student_id、二级索引teacher_name等
         *
         */
    
        /**
         * 插入数据
         */
        public void saveDemoData() {
            Student demoInfo = new Student();
            demoInfo.setStudentId("sId1");
            demoInfo.setStudentName("sName1");
    
            baseDao.saveItem(demoInfo);
        }
    
        /**
         * 更新数据
         */
        public void updateDemoData() {
            Student demoInfo = new Student();
            demoInfo.setStudentId("sId1");
            demoInfo.setStudentName("sName1");
    
            baseDao.updateItem(demoInfo);
        }
    
        /**
         * 删除数据
         */
        public void deleteDemoData() {
            Student demoInfo = new Student();
            demoInfo.setStudentId("sId1");
            demoInfo.setStudentName("sName1");
    
            baseDao.deleteItem(demoInfo);
        }
    
        /**
         * Query
         * 根据分区键查询
         */
        public Student getQueryResult() {
            Student demoInfo = (Student) baseDao.getQueryResult(Student.class, "sId1");
            System.out.println(demoInfo);
            return demoInfo;
        }
        
        /**
         * Query
         * 根据二级索引查询
         */
        public void getQueryIndexResult() {
            // 构建查询数据
            Map<String, AttributeValue> vals = new HashMap<>();
            vals.put(":v_student_name", new AttributeValue().withS("sName1"));
    
            DynamoDBQueryExpression<Student> exp = new DynamoDBQueryExpression<Student>()
                    .withKeyConditionExpression("student_name = :v_student_name") // 查询条件
                    .withIndexName("student_name-index") // 二级索引名称
                    .withExpressionAttributeValues(vals) // 查询条件赋值
                    .withConsistentRead(false); // 最终一致性,需设置成false
    
            QueryResultPage<Student> result = (QueryResultPage<Student>) baseDao.getQueryPageExpResult(Student.class, exp);
    
            System.out.println(result);
            // 总条数
            System.out.println("Result size ===>" + result.getResults().size());
            // 是否存在下一页
            System.out.println("Last evaluated key ===>" + result.getLastEvaluatedKey());
        }
        
    
        /**
         * Query 查询
         * 根据分区键、排序键查询数据
         */
        public void getQueryExpResult() {
            Map<String, AttributeValue> vals = new HashMap<String, AttributeValue>();
            vals.put(":v_teacher_id", new AttributeValue().withS("tId1"));
            vals.put(":v_student_id",new AttributeValue().withS("sId1"));
    
            DynamoDBQueryExpression<Teacher> queryExpression = new DynamoDBQueryExpression<Teacher>()
                .withKeyConditionExpression("teacher_id = :v_teacher_id and student_id > :v_student_id")
                .withExpressionAttributeValues(vals);
    
            List<Teacher> list = baseDao.getQueryExpResult(Teacher.class, queryExpression);
            System.out.println(list);
        }
        
        /**
         * Query 分页查询
         * 根据二级索引查询
         */
        public void getQueryPageExpResult() {
            // 构建查询数据
            Map<String, AttributeValue> vals = new HashMap<>();
            vals.put(":v_teacher_name", new AttributeValue().withS("tName1"));
    
            DynamoDBQueryExpression<Teacher> exp = new DynamoDBQueryExpression<Teacher>()
                    .withKeyConditionExpression("teacher_name = :v_teacher_name") // 查询条件
                    .withIndexName("teacher_name-index") // 二级索引名称
                    .withExpressionAttributeValues(vals) // 查询条件赋值
                    .withScanIndexForward(true)
                    .withConsistentRead(false)
                    .withLimit(3); // 分页条数
    
            // 下一页赋值
            Map<String, AttributeValue> startKey = new HashMap<>();
            startKey.put("teacher_id", new AttributeValue().withS("tId1"));
            startKey.put("student_id", new AttributeValue().withS("sId2"));
            exp.setExclusiveStartKey(startKey);
    
            QueryResultPage<Teacher> result = (QueryResultPage<Teacher>) baseDao.getQueryPageExpResult(Teacher.class, exp);
    
            // 返回结果
            List<Teacher> list = result.getResults();
            
            System.out.println("Result size ===>" + result.getResults().size());
            System.out.println("Last evaluated key ===>" + result.getLastEvaluatedKey());
    
        }
    
        /**
         * Scan 查询
         */
        public void getScanList() {
            Map<String, AttributeValue> vals = new HashMap<>();
            vals.put(":v_student_address", new AttributeValue().withS("地址1"));
    
            // 构建查询数据
            DynamoDBScanExpression exp = new DynamoDBScanExpression()
                    .withFilterExpression("contains(student_address,:v_student_address)")
                    .withExpressionAttributeValues(vals)
                    .withLimit(3);
    
            List<Student> b = (List<Student>) baseDao.getScanResult(Student.class, exp);
        }
    
        /**
         * Scan分页查询
         */
        public void getScanPageList() {
            Map<String, AttributeValue> vals = new HashMap<>();
            vals.put(":v_student_address", new AttributeValue().withS("地址1"));
    
            DynamoDBScanExpression exp = new DynamoDBScanExpression()
                    .withFilterExpression("contains(student_address,:v_student_address)")
                    .withExpressionAttributeValues(vals)
                    .withLimit(3);
    
             // 下一页赋值
            Map<String, AttributeValue> startKey = new HashMap<>();
            startKey.put("student_id", new AttributeValue().withS("sId1"));
            exp.setExclusiveStartKey(startKey);
    
            ScanResultPage<Student> result = baseDao.getScanPageResult(Student.class, exp);
    
            System.out.println("Result size ===>" + result.getResults().size());
            System.out.println("Last evaluated key ===>" + result.getLastEvaluatedKey());
        }
    
    }

    Dao层

    import com.amazonaws.regions.Regions;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
    import com.amazonaws.services.dynamodbv2.datamodeling.*;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public class BaseDao {
    
        static Regions region = Regions.CN_NORTHWEST_1;
        static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withRegion(region).build();
        static DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(client);
        
        /**
         * 插入数据
         */
        public void saveItem(Object clazz) {
            try {
                dynamoDBMapper.save(clazz);
            } catch (Exception e) {
                System.err.println("插入失败:" + e.getMessage());
            }
        }
        
        /**
         * 更新数据
         */
        public void updateItem(Object clazz) {
            try {
                dynamoDBMapper.save(clazz);
            } catch (Exception e) {
                System.err.println("更新失败:" + e.getMessage());
            }
        }
        
        /**
         * 删除数据
         */
        public void deleteItem(Object clazz) {
            try {
                dynamoDBMapper.delete(clazz);
            } catch (Exception e) {
                System.err.println("删除失败:" + e.getMessage());
            }
        }
        
        /**
         * Query
         * 根据分区键查询
         */
        public Object getQueryResult(Class<?> clazz, String pk) {
            return dynamoDBMapper.load(clazz, pk);
        }
        
        /**
         * Query
         * 根据分区键、排序键查询
         */
        public <T> List<T> getQueryExpResult(Class<?> clazz, DynamoDBQueryExpression queryExp) {
            return dynamoDBMapper.query(clazz, queryExp);
        }
        
        
        /**
         * Query 分页查询
         */
        public <T> QueryResultPage getQueryPageExpResult(Class<T> clazz, DynamoDBQueryExpression queryExp) {
            return dynamoDBMapper.queryPage(clazz, queryExp);
        }
        
        /**
         * Scan 查询
         */
        public List<?> getScanResult(Class<?> clazz, DynamoDBScanExpression scanExp) {
            return dynamoDBMapper.scan(clazz, scanExp);
        }
        
        /**
         * Scan 查询  分页查询
         */
        public <T> ScanResultPage getScanPageResult(Class<T> clazz, DynamoDBScanExpression scanExp) {
            return dynamoDBMapper.scanPage(clazz, scanExp);
        }
    }
  • 相关阅读:
    SSL JudgeOnline 1194——最佳乘车
    SSL JudgeOnline 1457——翻币问题
    SSL JudgeOnlie 2324——细胞问题
    SSL JudgeOnline 1456——骑士旅行
    SSL JudgeOnline 1455——电子老鼠闯迷宫
    SSL JudgeOnline 2253——新型计算器
    SSL JudgeOnline 1198——求逆序对数
    SSL JudgeOnline 1099——USACO 1.4 母亲的牛奶
    SSL JudgeOnline 1668——小车载人问题
    SSL JudgeOnline 1089——USACO 1.2 方块转换
  • 原文地址:https://www.cnblogs.com/aiyowei/p/15791410.html
Copyright © 2011-2022 走看看