SpringBoot使用MongoTemplate详解

1.pom.xml引入Jar包

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.MongoDbHelper封装

java 复制代码
/**
 * MongoDB Operation class
 * @author HyoJung
 * @date 2024-03-05
 */
public class MongoDbHelper {
    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * Save Individual Objects
     *
     * @param t 实体类参数
     * @param <T> 实体类
     * @return
     */
    public <T> T save(T t) {
        return mongoTemplate.insert(t);
    }

    /**
     * Store the object to the specified collectionName
     * @param objectToSave
     * @param collectionName 类似SQL数据库的表名
     * @param <T>
     * @return
     */
    public <T> T save(T objectToSave, String collectionName){
        return mongoTemplate.insert(objectToSave,collectionName);
    }

    /**
     * 批量存储
     *
     * @param list
     * @param collectionName
     * @return
     */
    public <T> Collection<T> batchSave(Collection<T> list, String collectionName) {
        return mongoTemplate.insert(list,collectionName);
    }

    /**
     * Query Data
     *
     * @param query
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> List<T> find(Query query, Class<T> tClass) {
        return mongoTemplate.find(query, tClass);
    }

    /**
     * Collection specified by query data
     *
     * @param query
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> List<T> find(Query query, Class<T> tClass, String collectionName) {
        return mongoTemplate.find(query, tClass,collectionName);
    }

    /**
     * 分页查询
     * @param query query criteria
     * @param pageNum Current Page
     * @param pageSize Number of entries per page
     * @param sortField Sorted Field
     * @param sortType 1:asc;0:desc
     * @param tClass to class
     * @param collectionName collection name
     * @param <T>
     * @return
     */
    public <T> MongoPage findByPage(Query query,int pageNum,int pageSize,String sortField,int sortType, Class<T> tClass, String collectionName) {
        int count = (int) mongoTemplate.count(query, tClass, collectionName);
        if(sortType==1){
            query.with(Sort.by(Sort.Order.asc(sortField)));
        }else {
            query.with(Sort.by(Sort.Order.desc(sortField)));
        }
        //Set starting number
        query.skip((pageNum - 1) * pageSize);
        //Set the number of queries
        query.limit(pageSize);
        //Query the current page data set
        List<T> taskList = mongoTemplate.find(query, tClass,collectionName);
        int size=count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
        MongoPage page=new MongoPage();
        page.setTotal(count);
        page.setSize(size);
        page.setData(taskList);
        return page;
    }

    /**
     * 查询前几条数据
     * @param query
     * @param limitNum 前几条
     * @param sortField 排序字段
     * @param sortType 0:倒序;1:正序
     * @param tClass
     * @param collectionName
     * @param <T>
     * @return
     */
    public <T> List<T> findTop(Query query,Integer limitNum,String sortField,int sortType, Class<T> tClass, String collectionName){
        if(sortType==1){
            query.with(Sort.by(Sort.Order.asc(sortField)));
        }else {
            query.with(Sort.by(Sort.Order.desc(sortField)));
        }
        query.limit(limitNum);
        return mongoTemplate.find(query, tClass,collectionName);
    }

    /**
     * 查询一条数据
     * @param query
     * @param sortField
     * @param sortType
     * @param tClass
     * @param collectionName
     * @param <T>
     * @return
     */
    public <T> List<T> findOne(Query query,String sortField,int sortType, Class<T> tClass, String collectionName){
        if(sortType==1){
            query.with(Sort.by(Sort.Order.asc(sortField)));
        }else {
            query.with(Sort.by(Sort.Order.desc(sortField)));
        }
        //Set the number of queries
        query.limit(1);
        //Query the current page data set
        List<T> taskList = mongoTemplate.find(query, tClass,collectionName);
        return taskList;
    }

    /**
     * Query All
     *
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> List<T> findAll(Class<T> tClass) {
        return mongoTemplate.findAll(tClass);
    }

    /**
     * Query all specified collections
     *
     * @param tClass
     * @param collectionName
     * @param <T>
     * @return
     */
    public <T> List<T> findAll(Class<T> tClass,String collectionName) {
        return mongoTemplate.findAll(tClass,collectionName);
    }

    /**
     * create collection
     * @param collName
     * @param indexList
     * @return
     */
    public boolean createCollection(String collName, List<Map<String,Integer>> indexList){
        try {
            if (mongoTemplate.collectionExists(collName)) {
                return true;
            }
            //Index collection to be created
            List<IndexModel> indexModels = new ArrayList<>();
            for (Map<String, Integer> indexMap : indexList) {
                BasicDBObject index = new BasicDBObject();
                for (String key : indexMap.keySet()) {
                    index.put(key, indexMap.get(key));
                }
                indexModels.add(new IndexModel(index));
            }
            mongoTemplate.createCollection(collName).createIndexes(indexModels);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * Update the first result set returned by the query
     * @param query
     * @param update
     * @param collectionName
     * @return
     */
    public boolean updateFirst(Query query, Update update, String collectionName){
        try {
            mongoTemplate.updateFirst(query, update, collectionName);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * Update all returned result sets
     * @param query
     * @param update
     * @param collectionName
     * @return
     */
    public boolean updateMulti(Query query, Update update, String collectionName){
        try {
            mongoTemplate.updateMulti(query, update, collectionName);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * If the update object does not exist, add it
     * @param query
     * @param update
     * @param tClass
     * @param <T>
     * @param collectionName
     * @return
     */
    public <T> boolean upsert(Query query, Update update, Class<T> tClass,String collectionName){
        try {
            mongoTemplate.upsert(query, update, tClass,collectionName);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 存在则更新不存在则创建
     * @param query
     * @param update
     * @param collectionName
     * @return
     */
    public boolean upsert(Query query, Update update, String collectionName){
        try {
            mongoTemplate.upsert(query, update,collectionName);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 汇总查询
     * @param aggregation
     * @param tClass
     * @param collectionName
     * @param <T>
     * @return
     */
    public <T> List<T> groupQuery(Aggregation aggregation,Class<T> tClass,String collectionName){
        AggregationResults<T> maps = mongoTemplate.aggregate(aggregation, collectionName, tClass);
        return maps.getMappedResults();
    }

    /**
     * 查总条数
     * @param query
     * @param collectionName
     * @return
     */
    public long queryCount(Query query, String collectionName){
        return mongoTemplate.count(query, collectionName);
    }

    /**
     * @description: 删除消息数据
     * @param query
     * @param collectionName
     **/
    public long delete(Query query,String collectionName) {
        return this.mongoTemplate.remove(query,collectionName).getDeletedCount();
    }
}

MongoPage实体类

java 复制代码
/**
 * MongoDB paged query returns result set
 * @author HyoJung
 * @date 2024-03-05
 */
@Data
public class MongoPage {
    /**
     * Total number of data
     */
    private Integer total;

    /**
     * Page count
     */
    private Integer size;

    /**
     * Data result set per page
     */
    private Object data;
}

3.MongoDB命令说明

3.1.Insert默认集合插入

mongoDB命令:

XML 复制代码
db.comment.insert({_id:"4",nickname:"ww",content:"这位是谁啊",userId:3,createTime:......})

mongoTemplate对应的方法

java 复制代码
mongoTemplate.insert();

我们常用的方法是:

1.将一个实体对象插入指定表中

java 复制代码
/**
 * 将一个实体对象存储到指定的表中
 * @param objectToSave
 * @param collectionName 类似SQL数据库的表名
 * @param <T>
 * @return
 */
public <T> T insert(T objectToSave, String collectionName){
    return mongoTemplate.insert(objectToSave,collectionName);
}

2.将一个List批量插入指定表中

java 复制代码
/**
 * 将一个集合插入指定的表中
 *
 * @param list 对象集合
 * @param collectionName 表名
 * @return
 */
public <T> Collection<T> batchInsert(Collection<T> list, String collectionName) {
    return mongoTemplate.insert(list,collectionName);
}

3.2.save默认集合插入

mongoDB 命令:

XML 复制代码
db.comment.save({})

使用save进行插入时会根据id进行判断,如果要插入数据中的id在数据库存在,则会将旧的数据覆盖,如果不存在则插入数据。

mongoTemplate对应的方法

java 复制代码
mongoTemplate.save();

方法封装:

java 复制代码
/**
 * 将一个实体对象存储到指定的表中
 * @param objectToSave
 * @param collectionName 类似SQL数据库的表名
 * @param <T>
 * @return
 */
public <T> T save(T objectToSave, String collectionName){
    return mongoTemplate.save(objectToSave,collectionName);
}

3.3.insert与save的区别

在MongoTemplate中,save()和insert()方法有以下区别:

save()方法:save()方法用于插入新文档或更新现有文档。如果要保存的文档没有id字段,将插入一个新文档。如果文档具有id字段,MongoDB将尝试使用匹配的id值更新文档。如果找不到具有匹配id的文档,则插入一个新文档。

insert()方法:insert()方法用于向集合中插入新文档。如果要插入的文档已经具有id字段,并且集合中已经存在具有相同id值的文档,则会抛出异常。这确保插入的文档具有唯一的_id值。

总结:save()方法用于插入和更新操作,而insert()方法专门用于插入新文档,并确保_id字段的唯一性。

3.4.修改数据

3.4.1.修改符合条件的第一条数据

mongoDB 命令:

XML 复制代码
db.comment.update({},{})

mongoTemplate对应的方法

java 复制代码
mongoTemplate.updateFirst();

方法封装:

java 复制代码
/**
 * 修改符合条件的第一条数据
 * @param query
 * @param update
 * @param collectionName
 * @return
 */
public boolean updateFirst(Query query, Update update, String collectionName){
    try {
        mongoTemplate.updateFirst(query, update, collectionName);
        return true;
    }catch (Exception e){
        return false;
    }
}

3.4.2.修改符合条件的全部数据

mongoDB 命令:

XML 复制代码
db.comment.update({},{},{multi:true})

mongoTemplate对应的方法

java 复制代码
mongoTemplate.updateMulti();

方法封装:

java 复制代码
/**
 * 修改符合条件的全部数据
 * @param query
 * @param update
 * @param collectionName
 * @return
 */
public boolean updateMulti(Query query, Update update, String collectionName){
    try {
        mongoTemplate.updateMulti(query, update, collectionName);
        return true;
    }catch (Exception e){
        return false;
    }
}

mongoTemplate对应的方法的返回结果是UpdateResult,也可以通过此结果返回状态进行更深度的判断是否修改成功。

3.5.删除数据

3.5.1.删除满足条件的所有文档

mongoDB 命令:

XML 复制代码
db.comment.remove({})

mongoTemplate对应的方法:

java 复制代码
mongoTemplate.remove();

方法封装:

java 复制代码
/**
 * @description: 删除满足条件的所有文档
 * @param query
 * @param collectionName
 **/
public long delete(Query query,String collectionName) {
    return this.mongoTemplate.remove(query,collectionName).getDeletedCount();
}

如果query 条件为空时则删除当前集合所有的记录。

方法封装:

java 复制代码
/**
 * @description: 删除满足条件的所有文档
 * @param collectionName
 **/
public long delete(String collectionName) {
    return this.mongoTemplate.remove(new Query(),collectionName).getDeletedCount();
}

3.5.2.删除满足条件的单个文档并返回当前删除的数据

mongoTemplate对应的方法

java 复制代码
mongoTemplate.findAndRemove();

3.5.3.删除满足条件的所有文档并返回当前删除的数据集合

mongoTemplate对应的方法

XML 复制代码
mongoTemplate.findAllAndRemove();

3.6.查询数据

3.6.1.查询全部文档

mongoDB 命令:

XML 复制代码
db.comment.find()

mongoTemplate对应的方法

XML 复制代码
mongoTemplate.findAll();

3.6.2.查询指定id的文档

mongoDB 命令:

XML 复制代码
db.comment.find({_id:"id"})

mongoTemplate对应的方法

XML 复制代码
mongoTemplate.findById();

3.6.3.查询满足条件的一条文档

mongoDB 命令:

XML 复制代码
db.comment.findOne({})

mongoTemplate对应的方法

XML 复制代码
mongoTemplate.findOne();

3.6.4.查询满足条件的所有文档

mongoDB 命令:

XML 复制代码
db.comment.find({})

mongoTemplate对应的方法

XML 复制代码
mongoTemplate.find();

方法封装:

java 复制代码
/**
 * 查询指定文档下符合条件的记录
 *
 * @param query
 * @param tClass
 * @param <T>
 * @return
 */
public <T> List<T> find(Query query, Class<T> tClass, String collectionName) {
    return mongoTemplate.find(query, tClass,collectionName);
}

3.6.5.分页查询方法封装

java 复制代码
/**
 * Pagination query
 * @param query query criteria
 * @param pageNum Current Page
 * @param pageSize Number of entries per page
 * @param sortField Sorted Field
 * @param sortType 1:asc;0:desc
 * @param tClass to class
 * @param collectionName collection name
 * @param <T>
 * @return
 */
public <T> MongoPage findByPage(Query query,int pageNum,int pageSize,String sortField,int sortType, Class<T> tClass, String collectionName) {
    int count = (int) mongoTemplate.count(query, tClass, collectionName);
    if(sortType==1){
        query.with(Sort.by(Sort.Order.asc(sortField)));
    }else {
        query.with(Sort.by(Sort.Order.desc(sortField)));
    }
    //Set starting number
    query.skip((pageNum - 1) * pageSize);
    //Set the number of queries
    query.limit(pageSize);
    //Query the current page data set
    List<T> taskList = mongoTemplate.find(query, tClass,collectionName);
    int size=count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
    MongoPage page=new MongoPage();
    page.setTotal(count);
    page.setSize(size);
    page.setData(taskList);
    return page;
}

3.6.6.查询符合条件的前几条数据

java 复制代码
/**
 * 查询前几条数据
 * @param query
 * @param limitNum 前几条
 * @param sortField 排序字段
 * @param sortType 0:倒序;1:正序
 * @param tClass
 * @param collectionName
 * @param <T>
 * @return
 */
public <T> List<T> findTop(Query query,Integer limitNum,String sortField,int sortType, Class<T> tClass, String collectionName){
    if(sortType==1){
        query.with(Sort.by(Sort.Order.asc(sortField)));
    }else {
        query.with(Sort.by(Sort.Order.desc(sortField)));
    }
    query.limit(limitNum);
    return mongoTemplate.find(query, tClass,collectionName);
}

3.6.7.查询符合条件的总条数

java 复制代码
/**
 * 查总条数
 * @param query
 * @param collectionName
 * @return
 */
public long queryCount(Query query, String collectionName){
    return mongoTemplate.count(query, collectionName);
}

3.6.8.Query的更多用法

is查询

java 复制代码
Query query = new Query(); // where...is... 相当于 where ? = ? 
query.addCriteria(Criteria.where("数据库字段名").is("你的参数"));

in查询

java 复制代码
ArrayList<String> list = new ArrayList<>();
// list代表你的数据
Query query = Query.query(Criteria.where("数据库字段").in(list));

字符模糊查询

java 复制代码
Query query = Query.query(Criteria.where("name").regex("小"));

查询范围

java 复制代码
//此示例是查询指定terminalId某个时间段内的数据
Query query = new Query(Criteria.where("terminalId").is(terminalId).and("timestamp").gte(startTimestamp).lte(endTimestamp));

查询指定字段

java 复制代码
//查询指定terminalId某个时间段内的数据后,返回指定的字段fields(List<String>)
Query query = new Query(Criteria.where("terminalId").is(terminalId).and("timestamp").gte(startTimestamp).lte(endTimestamp));
Field findFields = query.fields();
if (!CollectionUtils.isEmpty(fields)) {
    fields.forEach(findFields::include);
}

指定字段不返回

java 复制代码
query.fields().exclude("field");

3.7.创建一个collection

java 复制代码
/**
 * create collection
 * @param collName
 * @param indexList
 * @return
 */
public boolean createCollection(String collName, List<Map<String,Integer>> indexList){
    try {
        if (mongoTemplate.collectionExists(collName)) {
            return true;
        }
        //Index collection to be created
        List<IndexModel> indexModels = new ArrayList<>();
        for (Map<String, Integer> indexMap : indexList) {
            BasicDBObject index = new BasicDBObject();
            for (String key : indexMap.keySet()) {
                index.put(key, indexMap.get(key));
            }
            indexModels.add(new IndexModel(index));
        }
        mongoTemplate.createCollection(collName).createIndexes(indexModels);
        return true;
    }catch (Exception e){
        return false;
    }
}

4.术语介绍

在MongoDB中,有别于常见的关系型数据库,一些术语略有不同,如下表所示:

相关推荐
wolf犭良12 分钟前
26、《Spring Boot OpenFeign:声明式服务调用与熔断降级深度实践》
java·spring boot·后端
@卡卡-罗特27 分钟前
Spring Boot笔记(上)
spring boot·笔记·后端
卡布奇诺-海晨1 小时前
JVM之Arthas的dashboard命令以及CPU飙高场景
java·spring boot
katasea2 小时前
关于Springboot 应配置外移和Maven个性化打包一些做法
spring boot·maven
Huooya2 小时前
springboot的外部配置加载顺序
spring boot·面试·架构
钢板兽3 小时前
Java后端高频面经——Spring、SpringBoot、MyBatis
java·开发语言·spring boot·spring·面试·mybatis
赵渝强老师3 小时前
【赵渝强老师】管理MongoDB的运行
数据库·mongodb
用户53866168248223 小时前
SpringBoot 业务中 通过嵌套异步的方式 提高业务表数据同步效率
java·spring boot
MickeyCV3 小时前
《苍穹外卖》SpringBoot后端开发项目重点知识整理(DAY1 to DAY3)
java·spring boot·后端·苍穹外卖
学编程的小程5 小时前
Spring Boot应用开发:从零到生产级实战指南
spring boot