Lớp tiện ích thao tác MongoDB bằng MongoTemplate trong ứng dụng Spring Boot

Tổng quan

Lớp tiện ích dưới đây cung cấp các phương thức cơ bản để thao tác với MongoDB trong dự án Spring Boot, bao gồm: tạo chỉ mục, truy vấn điều kiện, phân trang, cập nhật dữ liệu và các phép toán aggregation.

Cài đặt lớp tiện ích


package com.example.mongo.util;

import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class MongoUtils {

    private static MongoTemplate template;

    @Autowired
    public void setMongoTemplate(MongoTemplate mongoTemplate) {
        template = mongoTemplate;
    }

    // Lưu danh sách bản ghi vào collection
    public static <T> void saveBatch(String collection, List<T> records) {
        records.forEach(record -> template.save(record, collection));
    }

    // Tạo chỉ mục hợp nhất
    public static void createCompoundIndex(String collection, String indexName, Map<String, Sort.Direction> fields) {
        Index index = new Index().named(indexName);
        fields.forEach((field, direction) -> index.on(field, direction));
        template.indexOps(collection).ensureIndex(index);
    }

    // Truy vấn phân trang có điều kiện
    public static <T> Map<String, Object> findPaginated(Class<T> clazz, String collection, 
                                                            Map<String, Object> filters, 
                                                            int page, int size, 
                                                            String sortField, Sort.Direction direction) {
        Criteria criteria = buildCriteria(filters);
        long total = template.count(Query.query(criteria), clazz, collection);
        
        Query query = Query.query(criteria)
                          .skip((page-1)*size)
                          .limit(size)
                          .with(Sort.by(direction, sortField));
                          
        List<T> results = template.find(query, clazz, collection);
        
        Map<String, Object> response = new HashMap<>();
        response.put("data", results);
        response.put("total", total);
        response.put("pages", (int)Math.ceil((double)total/size));
        return response;
    }

    // Cập nhật nhiều bản ghi theo điều kiện
    public static void updateMultiple(String collection, String matchField, Object matchValue, 
                                  Map<String, Object> updateFields) {
        Query query = Query.query(Criteria.where(matchField).is(matchValue));
        Update update = new Update();
        updateFields.forEach((k, v) -> update.set(k, v));
        template.updateMulti(query, update, collection);
    }

    // Tính tổng giá trị trường số
    public static Double calculateSum(String collection, Class<?> clazz, 
                                  Map<String, Object> filters, String sumField) {
        Criteria criteria = buildCriteria(filters);
        MatchOperation match = Aggregation.match(criteria);
        GroupOperation group = Aggregation.group().sum(sumField).as("total");
        
        return template.aggregate(Aggregation.newAggregation(match, group), 
                               collection, Map.class)
                      .getMappedResults()
                      .stream()
                      .findFirst()
                      .map(result -> (Double)result.get("total"))
                      .orElse(0.0);
    }

    private static Criteria buildCriteria(Map<String, Object> filters) {
        Criteria criteria = new Criteria();
        if (filters == null || filters.isEmpty()) return criteria;
        
        List<Criteria> conditions = new ArrayList<>();
        filters.forEach((key, value) -> 
            conditions.add(Criteria.where(key).is(value)));
        
        return criteria.andOperator(conditions.toArray(new Criteria[0]));
    }
}

Lớp mô hình phân trang


package com.example.mongo.model;

import java.util.List;

public class PaginationResult<T> {
    private List<T> data;
    private long totalItems;
    private int totalPages;
    private int currentPage;

    // Constructor, Getter/Setter
}

Ví dụ sử dụng


// Lưu dữ liệu
List<Product> products = Arrays.asList(new Product("Laptop"), new Product("Smartphone"));
MongoUtils.saveBatch("products", products);

// Tạo chỉ mục
Map<String, Sort.Direction> indexFields = new HashMap<>();
indexFields.put("category", Sort.Direction.ASC);
indexFields.put("price", Sort.Direction.DESC);
MongoUtils.createCompoundIndex("products", "category_price_index", indexFields);

// Truy vấn phân trang
Map<String, Object> filters = Map.of("status", "active");
var result = MongoUtils.findPaginated(Product.class, "products", 
                                     filters, 1, 10, "price", Sort.Direction.DESC);

Thẻ: spring-boot MongoDB Java Database rest-api

Đăng vào ngày 15 tháng 7 lúc 13:48