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中,有别于常见的关系型数据库,一些术语略有不同,如下表所示:

相关推荐
cnsxjean7 小时前
SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
java·前端·spring boot·分布式·后端·中间件·架构
《源码好优多》8 小时前
基于Java Springboot汽配销售管理系统
java·开发语言·spring boot
ℳ₯㎕ddzོꦿ࿐8 小时前
Spring Boot集成MyBatis-Plus:自定义拦截器实现动态表名切换
spring boot·后端·mybatis
尘浮生9 小时前
Java项目实战II基于Java+Spring Boot+MySQL的智能停车计费系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·微信小程序·maven
hai4058710 小时前
Spring Boot整合Redis Stack构建本地向量数据库相似性查询
数据库·spring boot·redis
years_GG10 小时前
【Git多人开发与协作之团队的环境搭建】
spring boot·深度学习·vue·github·团队开发·个人开发
小钟不想敲代码10 小时前
第4章 Spring Boot自动配置
java·spring boot·后端
代码小鑫10 小时前
A046-基于SpringBoot的论坛系统的设计与实现
java·开发语言·数据库·spring boot·毕业设计
我的运维人生11 小时前
Spring Boot应用开发实战:构建RESTful API服务
spring boot·后端·restful·运维开发·技术共享
黄昏_13 小时前
在Springboot项目中实现将文件上传至阿里云 OSS
java·spring boot·后端·阿里云