SpringBoot使用MongoTemplate详解

news2024/11/25 4:27:42

1.pom.xml引入Jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.MongoDbHelper封装

/**
 * 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实体类

/**
 * 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命令:

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

mongoTemplate对应的方法

mongoTemplate.insert();

我们常用的方法是:

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

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

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

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

3.2.save默认集合插入

mongoDB 命令:

db.comment.save({})

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

mongoTemplate对应的方法

mongoTemplate.save();

方法封装:

/**
 * 将一个实体对象存储到指定的表中
 * @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 命令:

db.comment.update({},{})

mongoTemplate对应的方法

mongoTemplate.updateFirst();

方法封装:

/**
 * 修改符合条件的第一条数据
 * @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 命令:

db.comment.update({},{},{multi:true})

mongoTemplate对应的方法

mongoTemplate.updateMulti();

方法封装:

/**
 * 修改符合条件的全部数据
 * @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 命令:

db.comment.remove({})

mongoTemplate对应的方法:

mongoTemplate.remove();

方法封装:

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

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

方法封装:

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

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

mongoTemplate对应的方法

mongoTemplate.findAndRemove();

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

mongoTemplate对应的方法

mongoTemplate.findAllAndRemove();

3.6.查询数据

3.6.1.查询全部文档

mongoDB 命令:

db.comment.find()

mongoTemplate对应的方法

mongoTemplate.findAll();

3.6.2.查询指定id的文档

mongoDB 命令:

db.comment.find({_id:"id"})

mongoTemplate对应的方法

mongoTemplate.findById();

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

mongoDB 命令:

db.comment.findOne({})

mongoTemplate对应的方法

mongoTemplate.findOne();

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

mongoDB 命令:

db.comment.find({})

mongoTemplate对应的方法

mongoTemplate.find();

方法封装:

/**
 * 查询指定文档下符合条件的记录
 *
 * @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.分页查询方法封装

/**
 * 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.查询符合条件的前几条数据

/**
 * 查询前几条数据
 * @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.查询符合条件的总条数

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

3.6.8.Query的更多用法

is查询

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

in查询

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

字符模糊查询

Query query = Query.query(Criteria.where("name").regex("小"));

查询范围

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

查询指定字段

//查询指定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);
}

指定字段不返回

query.fields().exclude("field");

3.7.创建一个collection

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1493479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

群晖 NAS 安装 Ghost Blog

通过群晖的 docker 容器下载 ghost 映像&#xff0c;并配置后启动。 一、下载映像文件 由于网络环境&#xff0c;无法直接连接 docker 的映像服务器&#xff0c;因此使用境内代理&#xff0c;通过 url 方式下载。 打开 docker 控制台&#xff0c;点击左边导航栏的 “映像”&…

2024大厂Android面试真题集锦,算法真题解析:美团+Tencent+字节跳动+阿里+360+拼多多

前言 IT行业薪水高&#xff0c;这是众所周知的&#xff0c;所以很多人大学都选择IT相关专业&#xff0c;即使非该专业的人&#xff0c;毕业了也想去一个培训机构镀镀金&#xff0c;进入这一行业。 但是有关这个行业35岁就退休的说法&#xff0c;也一直盛传。 加上这几年不断…

苹果曝出两个 iOS 系统 0-Day 漏洞

最近&#xff0c;苹果公司发布了紧急安全更新&#xff0c;解决了两个 iOS 零日漏洞。这些漏洞存在于 iOS 内核&#xff08;CVE-2024-23225&#xff09;和 RTKit&#xff08;CVE-2024-23296&#xff09;中&#xff0c;威胁攻击者可利用其绕过内核内存保护&#xff0c;这就给了具…

MySQL 表锁问题

MySQL 表锁解决 查看哪些表被锁&#xff0c;字段 In_use 表示有多少线程在使用这张表&#xff0c;字段 name_locked 表示表格是否被锁&#xff0c;0 代表锁定状态 mysql> show OPEN TABLES where In_use > 0; -------------------------------------------------------…

音视频学习笔记——ffmpeg解码流程

✊✊&#x1f308;大家好&#xff01;本篇文章主要记录自己在进行音视频学习中&#xff0c;整理的部分ffmpeg解码相关的内容重点&#x1f607;。 首先重新梳理了ffmpeg解码流程&#xff0c;重点学习avcodec_send_packet()、avcodec_receive_frame()在解码中的应用&#xff0c;以…

【QT】重载的信号槽/槽函数做lambda表达式

重载的信号槽 函数指针&#xff1a; int fun(int a,long b) int (*funp)(int, long) fun; 实现回调函数就需要函数指针 信号重载 派生类槽函数发送两个信号 派生类给父类发两个信号 void (SubWidget::*mysigsub)() &SubWidget::sigSub;connect(&subw,mysigsub,t…

网络编程:select、poll

.1、select完成TCP并发服务器 程序代码&#xff1a; #include <myhead.h> #define SER_IP "192.168.125.234" //服务端IP #define SER_PORT 8888 //服务端端口号int main(int argc, const char *argv[]) {//1.创建用于连接的套接字int sfds…

1-安装rabbitmq

rabbitmq官网&#xff1a; https://www.rabbitmq.com/docs/download 本机环境&#xff1a;mac&#xff0c;使用orbstack提供的docker 使用docker部署rabbitmq docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.13-management 然后报错&#xf…

bun 单元测试

bun test Bun 附带了一个快速、内置、兼容 Jest 的测试运行程序。测试使用 Bun 运行时执行&#xff0c;并支持以下功能。 TypeScript 和 JSX生命周期 hooks快照测试UI 和 DOM 测试使用 --watch 的监视模式使用 --preload 预加载脚本 Bun 旨在与 Jest 兼容&#xff0c;但并非所…

SD-WAN: 灵活部署,助力云服务

随着Office 365、Salesforce、Webex和SAP等云托管应用程序的迅速发展&#xff0c;企业正加速将业务关键应用程序迁移到云端。这种转变需要为遍布各地的员工提供安全可靠的云服务网络连接。本文将介绍SD-WAN如何助力企业的云服务访问。 传统的网络架构&#xff0c;特别是基于MPL…

【AI视野·今日Robot 机器人论文速览 第八十二期】Tue, 5 Mar 2024

AI视野今日CS.Robotics 机器人学论文速览 Tue, 5 Mar 2024 Totally 63 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;双臂机器人拧瓶盖, (from 伯克利) website: https://toruowo.github.io/bimanual-twist &#x1f4da;水下抓取器, (from …

总结:大模型技术栈---算法与原理

原文地址&#xff1a;大模型技术栈-算法与原理 1. tokenizer方法 word-level char-level subword-level BPE WordPiece UniLM SentencePiece ByteBPE2. position encoding 绝对位置编码 ROPE AliBi 相对位置编码 Transformer-XL T5/TUPE DeBERTa3. 注意力机制 Mamba,H3,Hyena…

Linux下下载安装JDK配置Java环境变量

Linux下下载安装JDK配置Java环境变量 1. 下载JDK 下载链接&#xff1a;(https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) 2. 上传至服务器并解压 可通过shell工具进行上传&#xff0c;我这里是上传安装在/opt目录 解压jdk-17.0.10_linux-x64_b…

【外汇天眼】外汇交易策略:最容易获利的行情,原来是这一段!

不随便抄底抓顶 不能仅因为价格大跌而抄底&#xff0c;是对市场风险的尊重。 市场走势是有理由的&#xff0c;每轮下跌背后都有其深刻的基本面。 我在看书时印象深刻的是一位国外著名炒手谈到他的经历。 有一年咖啡丰收&#xff0c;价格跌得惨不忍睹&#xff0c;甚至到了一袋…

阿里二面,redis宕机了,如何快速恢复数据

背景 有个同学阿里二面&#xff0c;面试官问&#xff1a;redis宕机了&#xff0c;如何恢复数据&#xff1f; 这位同学当时一脸懵&#xff0c;不知道如何回答。 分析分析这个问题&#xff0c;redis宕机&#xff0c;要想恢复数据&#xff0c;首先redis的数据有没有做持久化&…

【AI视野·今日CV 计算机视觉论文速览 第302期】Tue, 5 Mar 2024

AI视野今日CS.CV 计算机视觉论文速览 Tue, 5 Mar 2024 Totally 177 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Brand Visibility in Packaging: A Deep Learning Approach for Logo Detection, Saliency-Map Prediction, and Logo Plac…

图论例题解析

1.图论基础概念 概念 &#xff08;注意连通非连通情况&#xff0c;1节点&#xff09; 无向图&#xff1a; 度是边的两倍&#xff08;没有入度和出度的概念&#xff09; 1.完全图&#xff1a; 假设一个图有n个节点&#xff0c;那么任意两个节点都有边则为完全图 2.连通图&…

计算机网络——24路由器组成

路由器组成 路由器的结构概况 高层面(非常简化的)通用路由器体系架构 路由&#xff1a;运行路由选择算法&#xff0f;协议 (RIP, OSPF, BGP) - 生成 路由表转发&#xff1a;从输入到输出链路交换数据报 - 根据路由表进行分组的转发 输入端口功能 分布式交换&#xff1a; 根…

【风格迁移】对比度保持连贯性损失 CCPL:解决图像局部失真、视频帧间的连贯性和闪烁

对比度保持连贯性损失 CCPL&#xff1a;解决图像局部失真、视频帧间的连贯性和闪烁 提出背景解法&#xff1a;对比度保持连贯性损失&#xff08;CCPL&#xff09; 局部一致性假设 对比学习机制 邻域调节策略 互信息最大化对比学习&#xff1a;在无需标签的情况下有效学习区分…

Yolov8改进交流

YOLO v8改进 YOLOv8的改进&#xff0c;我接触的主要分为网络改进和代码改进&#xff0c;网络改进就是以注意力、主干为主&#xff0c;代码改进就是类似于Iou&#xff0c;类别权重等修改。 以下是yolov8的原始模型。 # Ultralytics YOLO &#x1f680;, AGPL-3.0 license # YO…