JAVA AWS added, deleted, modified and queried data according to Dynamodb

Posted by haku on Wed, 12 Jan 2022 03:36:12 +0100

preface

dynamodb is a non relational database of AWS. It is applicable to big data without frequent addition, deletion, modification and query and with weak relevance, such as the historical order information of a user.

Historical orders may not be queried frequently, but the amount of data is large, and they can be queried as long as there is a user ID. for similar orders, non relational databases can be used.

This example may not be appropriate. I just want to express that non relational databases should not be used in any case. Each database has its own meaning. (I was badly hurt because of this)

Get to the point:

You can check the Java Dynamodb document on the AWS official website, but I think the document is too large and too much to find, so I record it myself.

When creating a table on the AWS console, partition keys and sorting keys shall be formulated during the creation process. If the sorting key is not created, it cannot be used as a candidate, and the table can only be deleted and rebuilt.

Dynamodb cannot separate libraries, so the table name should be clear.

 

Important: Although I am a good cook and my writing is not good enough, I do not accept any criticism. This article is only for reference and recording by those in need.

Common annotation of entities: mapping the relationship between entities and tables, which is placed on the getter method

@DynamoDBHashKey annotation partition key
@Dynamodrangekey annotation sort key
@DynamoDBAttribute annotation common attribute
@DynamoDBIndexHashKey annotation secondary index partition key
@DynamoDBIndexRangeKey annotation secondary index sort key
@Dynamodignore ignores an object or property
// Partition key
@DynamoDBHashKey(attributeName="user_id")
public String getUserId() {
    return userId;
}

// Sort key
@DynamoDBRangeKey(attributeName="event_id")
public String getEventId() {
    return eventId;
}

// Secondary index
@DynamoDBIndexHashKey(globalSecondaryIndexName= "user_name-index", attributeName= "user_name")
public String getUserName() {
    return userName;
}

// attribute
@DynamoDBAttribute(attributeName="user_gender")
public String getUserGender() {
    return userGender;
}

// ignore
@DynamoDBIgnore
public Student getStudent() {
    return student;
}

...

code implementation

be careful::

① withKeyConditionExpression does not support the use of contains fuzzy query in the query criteria for partition keys and sorting keys

② withFilterExpression the filter query criteria for other fields, combined with limit, will query first and then page, resulting in less data

Therefore, Dynamodb cannot page at the same time as fuzzy query.

Service layer

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 com.systron.common.dao.BaseDao;
import com.systron.models.Student;
import com.systron.models.Teacher;
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 Table: partition key student_id, secondary index student_name et al
     * Teacher Table: partition key teacher_id, sort key student_id, secondary index, teacher_name et al
     *
     */

    /**
     * insert data
     */
    public void saveDemoData() {
        Student demoInfo = new Student();
        demoInfo.setStudentId("sId1");
        demoInfo.setStudentName("sName1");

        baseDao.saveItem(demoInfo);
    }

    /**
     * Update data
     */
    public void updateDemoData() {
        Student demoInfo = new Student();
        demoInfo.setStudentId("sId1");
        demoInfo.setStudentName("sName1");

        baseDao.updateItem(demoInfo);
    }

    /**
     * Delete data
     */
    public void deleteDemoData() {
        Student demoInfo = new Student();
        demoInfo.setStudentId("sId1");
        demoInfo.setStudentName("sName1");

        baseDao.deleteItem(demoInfo);
    }

    /**
     * Query
     * Query by partition key
     */
    public Student getQueryResult() {
        Student demoInfo = (Student) baseDao.getQueryResult(Student.class, "sId1");
        System.out.println(demoInfo);
        return demoInfo;
    }
    
    /**
     * Query
     * Query according to secondary index
     */
    public void getQueryIndexResult() {
        // Building query data
        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") // query criteria
                .withIndexName("student_name-index") // Secondary index name
                .withExpressionAttributeValues(vals) // Query condition assignment
                .withConsistentRead(false); // Final consistency, set to false

        QueryResultPage<Student> result = (QueryResultPage<Student>) baseDao.getQueryPageExpResult(Student.class, exp);

        System.out.println(result);
        // Total number
        System.out.println("Result size ===>" + result.getResults().size());
        // Does the next page exist
        System.out.println("Last evaluated key ===>" + result.getLastEvaluatedKey());
    }
    

    /**
     * Query query
     * Query data according to partition key and sorting key
     */
    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 Paging query
     * Query according to secondary index
     */
    public void getQueryPageExpResult() {
        // Building query data
        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") // query criteria
                .withIndexName("teacher_name-index") // Secondary index name
                .withExpressionAttributeValues(vals) // Query condition assignment
                .withScanIndexForward(true)
                .withConsistentRead(false)
                .withLimit(3); // Number of pages

        // Next page assignment
        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);

        // Return results
        List<Teacher> list = result.getResults();
        
        System.out.println("Result size ===>" + result.getResults().size());
        System.out.println("Last evaluated key ===>" + result.getLastEvaluatedKey());

    }

    /**
     * Scan query
     */
    public void getScanList() {
        Map<String, AttributeValue> vals = new HashMap<>();
        vals.put(":v_student_address", new AttributeValue().withS("Address 1"));

        // Building query data
        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 Paging query
     */
    public void getScanPageList() {
        Map<String, AttributeValue> vals = new HashMap<>();
        vals.put(":v_student_address", new AttributeValue().withS("Address 1"));

        DynamoDBScanExpression exp = new DynamoDBScanExpression()
                .withFilterExpression("contains(student_address,:v_student_address)")
                .withExpressionAttributeValues(vals)
                .withLimit(3);

         // Next page assignment
        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 layer

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);
    
    /**
     * insert data
     */
    public void saveItem(Object clazz) {
        try {
            dynamoDBMapper.save(clazz);
        } catch (Exception e) {
            System.err.println("Insert failed:" + e.getMessage());
        }
    }
    
    /**
     * Update data
     */
    public void updateItem(Object clazz) {
        try {
            dynamoDBMapper.save(clazz);
        } catch (Exception e) {
            System.err.println("Update failed:" + e.getMessage());
        }
    }
    
    /**
     * Delete data
     */
    public void deleteItem(Object clazz) {
        try {
            dynamoDBMapper.delete(clazz);
        } catch (Exception e) {
            System.err.println("Delete failed:" + e.getMessage());
        }
    }
    
    /**
     * Query
     * Query by partition key
     */
    public Object getQueryResult(Class<?> clazz, String pk) {
        return dynamoDBMapper.load(clazz, pk);
    }
    
    /**
     * Query
     * Query by partition key and sorting key
     */
    public <T> List<T> getQueryExpResult(Class<?> clazz, DynamoDBQueryExpression queryExp) {
        return dynamoDBMapper.query(clazz, queryExp);
    }
    
    
    /**
     * Query Paging query
     */
    public <T> QueryResultPage getQueryPageExpResult(Class<T> clazz, DynamoDBQueryExpression queryExp) {
        return dynamoDBMapper.queryPage(clazz, queryExp);
    }
    
    /**
     * Scan query
     */
    public List<?> getScanResult(Class<?> clazz, DynamoDBScanExpression scanExp) {
        return dynamoDBMapper.scan(clazz, scanExp);
    }
    
    /**
     * Scan Query paging query
     */
    public <T> ScanResultPage getScanPageResult(Class<T> clazz, DynamoDBScanExpression scanExp) {
        return dynamoDBMapper.scanPage(clazz, scanExp);
    }
}

 

Topics: Java Database AWS dynamodb