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);
        }
    }
  • 相关阅读:
    jQuery+ajax实现文件上传
    Jquery异步上传文件
    jQuery插件综合应用(三)发布文章页面
    jQuery插件综合应用(二)文字为主的页面
    网站开发常用jQuery插件总结(13)定位插件scrollto
    网站开发常用jQuery插件总结(12)固定元素插件scrolltofixed
    网站开发常用jQuery插件总结(11)折叠插件Akordeon
    网站开发常用jQuery插件总结(十)菜单插件superfish
    网站开发常用jQuery插件总结(九)侧边栏插件pageslide
    网站开发常用jQuery插件总结(八)标签编辑插件Tagit
  • 原文地址:https://www.cnblogs.com/aiyowei/p/15791410.html
Copyright © 2011-2022 走看看