Nitrite数据库(Java)使用和中文文档
Nitrite是一种无服务器、嵌入式且自包含的 NoSQL 数据库。它不需要安装只需要导入jar包即可使用。适合小型桌面/嵌入式项目。在Java 桌面项目中需要保存数据到本地还需要对这些数据做增删改查。最先想到的是用sqlite但是本人不太想用jdbc去写sql使用mybatis这些框架又很麻烦谷歌的Room又不能直接在java客户端用。经过一番寻找试错最后选择了Nitrite。使用Nitrite很方便导入jar包即可使用。Nitrite官网 https://nitrite.dizitart.comNitrite项目地址https://github.com/nitrite/nitrite-java可以参考我写的demogithubhttps://github.com/lieyanfeimao/nitrite-test码云https://gitee.com/edadmin/nitrite-test.git中文文档可以在下述网盘中的java技术文档/nitrite-嵌入式NoSql数据库中拿到(帮助文档只对java部分进行了详细修正)百度云盘 百度网盘 请输入提取码 提取码: aptd微云 文件分享Nitrite使用maven引入Nitrite 支持以对象的方式操作文档需要引入nitrite-jackson-mapper否则需要自己实现对象到文档的互相转换。properties nitrite.version4.3.2/nitrite.version /properties dependencies dependency groupIdorg.dizitart/groupId artifactIdnitrite/artifactId version${nitrite.version}/version /dependency dependency groupIdorg.dizitart/groupId artifactIdnitrite-mvstore-adapter/artifactId version${nitrite.version}/version /dependency dependency groupIdorg.dizitart/groupId artifactIdnitrite-jackson-mapper/artifactId version${nitrite.version}/version /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.dizitart/groupId artifactIdnitrite-bom/artifactId version${nitrite.version}/version scopeimport/scope typepom/type /dependency /dependencies /dependencyManagement创建实体类创建测试用的实体类 Project、Version、VersionVOVersion类的属性 projectId 用来存储Project类的idVersionVO用于保存Version和Project关联查询的数据Project.javaimport org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; /** * author liuming */ Entity(value project,indices { //全文索引 Index(fields name,type IndexType.FULL_TEXT) }) public class Project { Id private Long id; private String name; private Integer age; private Integer sex; private String date; Override public String toString() { return Project{ id id , name name \ , age age , sex sex , date date \ }; } /** * 获取 Id * * return id Id */ public Long getId() { return this.id; } /** * 设置 Id * * param id Id */ public void setId(Long id) { this.id id; } /** * 获取 * * return name */ public String getName() { return this.name; } /** * 设置 * * param name */ public void setName(String name) { this.name name; } /** * 获取 * * return age */ public Integer getAge() { return this.age; } /** * 设置 * * param age */ public void setAge(Integer age) { this.age age; } /** * 获取 * * return sex */ public Integer getSex() { return this.sex; } /** * 设置 * * param sex */ public void setSex(Integer sex) { this.sex sex; } /** * 获取 * * return date */ public String getDate() { return this.date; } /** * 设置 * * param date */ public void setDate(String date) { this.date date; } }Version.javaimport org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; /** * author liuming */ Entity(value version,indices { //全文索引 Index(fields name,type IndexType.FULL_TEXT) }) public class Version { Id private Long id; private String name; private String nameEn; private String date; private Long projectId; Override public String toString() { return Version{ id id , name name \ , nameEn nameEn \ , date date \ , projectId projectId }; } /** * 获取 Id * * return id Id */ public Long getId() { return this.id; } /** * 设置 Id * * param id Id */ public void setId(Long id) { this.id id; } /** * 获取 * * return name */ public String getName() { return this.name; } /** * 设置 * * param name */ public void setName(String name) { this.name name; } /** * 获取 * * return nameEn */ public String getNameEn() { return this.nameEn; } /** * 设置 * * param nameEn */ public void setNameEn(String nameEn) { this.nameEn nameEn; } /** * 获取 * * return projectId */ public Long getProjectId() { return this.projectId; } /** * 设置 * * param projectId */ public void setProjectId(Long projectId) { this.projectId projectId; } /** * 获取 * * return date */ public String getDate() { return this.date; } /** * 设置 * * param date */ public void setDate(String date) { this.date date; } }VersionVO.javaimport java.util.List; /** * author liuming */ public class VersionVO { private Long id; private String name; private String nameEn; private ListProject projectList; private Project project; Override public String toString() { return VersionVO{ id id , name name \ , nameEn nameEn \ , project project }; } /** * 获取 * * return id */ public Long getId() { return this.id; } /** * 设置 * * param id */ public void setId(Long id) { this.id id; } /** * 获取 * * return name */ public String getName() { return this.name; } /** * 设置 * * param name */ public void setName(String name) { this.name name; } /** * 获取 * * return nameEn */ public String getNameEn() { return this.nameEn; } /** * 设置 * * param nameEn */ public void setNameEn(String nameEn) { this.nameEn nameEn; } /** * 获取 * * return projectList */ public ListProject getProjectList() { return this.projectList; } /** * 设置 * * param projectList */ public void setProjectList(ListProject projectList) { this.projectList projectList; if(this.projectList!null !this.projectList.isEmpty()){ this.projectthis.projectList.get(0); } } /** * 获取 * * return project */ public Project getProject() { return this.project; } /** * 设置 * * param project */ public void setProject(Project project) { this.project project; } }增删改查Nitrite默认将数据存储在内存中如需存储到磁盘需要在创建Nitrite对象时添加MVStoreModule模块。Nitrite文档是JSON形式的键值对格式不是Java对象为了方便的进行对象和Nitrite文档互相转换需要添加JacksonMapperModule模块。之后我们就可以通过 ObjectRepository 以操作Java对象的形式操作Nitrite文档。测试代码(TestMain.java)如下public class TestMain { public static void main(String[] args) { //数据库文件存储路径将在项目根目录生成一个>public class NitriteDataManager { private final static NitriteDataManager instancenew NitriteDataManager(); /** 数据库名 */ private final static String DB_NAMEdata.db; /** 数据库对象 */ private static Nitrite db; /** id字段的名称 */ private final static String ID_NAMEid; private NitriteDataManager(){ } public static NitriteDataManager getInstance(){ if(dbnull){ instance.initDb(null); } return instance; } /** * 初始化数据库 * param path 数据库文件路径 */ public static void initDb(String path){ if(StringUtils.isBlank(path)){ pathSystem.getProperty(user.dir)File.separatorDB_NAME; } MVStoreModule storeModule MVStoreModule.withConfig() .filePath(path) .build(); db Nitrite.builder() .loadModule(storeModule) .loadModule(new JacksonMapperModule()) .openOrCreate(); } /** * 关闭数据库 */ public void closeDb(){ if(db!null) db.close(); dbnull; } /** * 新增或删除。此方法针对id字段做了处理如果为long和int类型且值为null自动用当前id的最大值生成id效果类似id自增 * param t 数据 * return * param T */ public T int insertOrUpdate(T t){ try{ Class clst.getClass(); ObjectRepository repositorydb.getRepository(cls); //如果存在id字段并且id为空且id类型为 long/int/Long/Integer 自动生成一个id Field fieldcls.getDeclaredField(ID_NAME); if(field!null){ Class typefield.getType(); if(type Long.class || typeInteger.class || typelong.class || typeint.class){ field.setAccessible(true); Object objfield.get(t); if(objnull){ long idgenerateId(repository,field,t); if(typeLong.class || typelong.class) { field.set(t, id); }else{ field.set(t, (int)id); } } field.setAccessible(false); } } WriteResult resultrepository.update(t,true); db.commit(); return result.getAffectedCount(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(保存数据失败); } } /** * 删除数据 * param t 数据对象 * return * param T */ public T int delete(T t){ Class clst.getClass(); try{ ObjectRepository repositorydb.getRepository(cls); WriteResult resultrepository.remove(t); db.commit(); return result.getAffectedCount(); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(删除数据失败); } } /** * 删除数据 * param cls 类型 * param id 数据id * return * param T */ public T int delete(Class cls,Long id){ return delete(cls,new Long[]{id}); } /** * 删除数据 * param cls 类型 * param ids 数据id组 * return * param T */ public T int delete(Class cls,Long[] ids){ if(idsnull || ids.length0){ return 0; } try{ ObjectRepository repositorydb.getRepository(cls); WriteResult resultrepository.remove(FluentFilter.where(ID_NAME).in(ids)); db.commit(); return result.getAffectedCount(); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(删除数据失败); } } /** * 查询所有数据 * param cls * return * param T */ public T ListT queryAll(ClassT cls){ try{ ObjectRepository repositorydb.getRepository(cls); return repository.find().toList(); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(查询数据失败); } } /** * 查询数据 * param cls 类 * param filter 过滤器 * param findOptions 查询选项 * return * param T */ public T ListT queryList(ClassT cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repositorydb.getRepository(cls); return repository.find(filter,findOptions).toList(); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(查询数据失败); } } /** * 查询单条数据 * param cls 类 * param filter 过滤器 * param findOptions 查询选项 * return * param T */ public T T queryOne(ClassT cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repositorydb.getRepository(cls); return (T)(repository.find(filter,findOptions).firstOrNull()); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(查询数据失败); } } /** * 根据id查询数据 * param cls * param id * return * param T */ public T T queryById(ClassT cls,Long id){ try{ ObjectRepository repositorydb.getRepository(cls); return (T)repository.getById(id); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(查询数据失败); } } /** * 获取查询的游标 * param cls 类 * param filter 过滤器 * param findOptions 查询选项 * return */ public T CursorT getQueryCursor(ClassT cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repositorydb.getRepository(cls); return repository.find(filter,findOptions); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(查询数据失败); } } /** * 生成id * return */ private T long generateId(ObjectRepository repository,Field field,T t) throws Exception { synchronized (t.getClass()) { Object object repository.find(FindOptions.orderBy(ID_NAME, SortOrder.Descending)).firstOrNull(); if (object ! null) { return (Long.parseLong(field.get(object).toString())) 1; } } return 1L; } /** * 获取db对象 * return */ public Nitrite getDb(){ return db; } /** * 获取 ObjectRepository * param cls * return * param T */ public T ObjectRepositoryT getRepository(Class cls){ return db.getRepository(cls); } }使用封装的操作类增删改查接下来我们使用封装的 NitriteDataManager 进行增删改查操作。测试类(TestNitriteDataManagerMain.java)public class TestNitriteDataManagerMain { public static void main(String[] args) { /******* NitriteDataManager在初始化时会自动在项目根目录创建一个data.db文件.如果需要自定义数据库文件路径可以使用 initDb(path)方法。 *****/ // //数据库文件存储目录将在项目根目录生成一个 data-2.db // String pathSystem.getProperty(user.dir)File.separatordata-2.db; // //设置数据库存储路径并使用MVStore存储数据创建Nitrite对象 // NitriteDataManager.initDb(path); /** ----------- 添加/修改 数据 -------- **/ NitriteDataManager nmNitriteDataManager.getInstance(); //添加Project数据。与TestMain中代码有所区别的事这里不需要设置id,id会自动生成。 //用作id字段的名称必须为 id 否则不会自动生成由 NitriteDataManager 中的 ID_NAME 确定 addProject(nm); //添加Version数据。与TestMain中代码有所区别的事这里不需要设置id,id会自动生成。 //用作id字段的名称必须为 id 否则不会自动生成由 NitriteDataManager 中的 ID_NAME 确定 addVersion(nm); /** ----------- 查询数据 -------- **/ //查询所有Project数据 System.out.println(查询所有Project); ListProject projectListnm.queryAll(Project.class); for (Project project:projectList){ System.out.println(project); } System.out.println(Project 根据 sex 和 age 排序); FindOptions findOptionsFindOptions.orderBy(sex, SortOrder.Descending); //多列排序需要用findOptions.orderBy()对象获取SortableFields对象再往SortableFields中添加排序数据 findOptions.orderBy().addField(age,SortOrder.Ascending); //如果需要做分页查询使用如下代码。skip是跳过多少行limit是拿多少条数据 // findOptions.skip(1L).limit(1L); projectListnm.queryList(Project.class,null,findOptions); for (Project project:projectList){ System.out.println(project); } System.out.println(根据Id查询Version); //根据id查询数据 Version versionnm.queryById(Version.class,1L); System.out.println(version); //通过条件查询数据。此处使用正则匹配。此方式会扫描整个集合以查找匹配的文档不使用索引。 // ListVersion versionListnm.queryList(Version.class,FluentFilter.where(name).regex(.*?版本.*?),null); //通过条件查询数据。此处使用text过滤器。需要为属性添加全局索引。 ListVersion versionListnm.queryList(Version.class,FluentFilter.where(name).text(*版本*),null); System.out.println(按条件查询 name 中包含 \版本\ 的结果); for(Version v:versionList){ System.out.println(v); } //联接查询,join CursorProject projectCursornm.getQueryCursor(Project.class,null,null); CursorVersion versionCursornm.getQueryCursor(Version.class,null,null); Lookup lookup new Lookup(); lookup.setLocalField(projectId); lookup.setForeignField(id); //查出来的是个list不是单个对象需要手动处理一下可以参考 VersionVO 的 setProjectList 方法 lookup.setTargetField(projectList); RecordStream streamversionCursor.join(projectCursor,lookup, VersionVO.class); System.out.println(关联查询的结果); ListVersionVO voListstream.toList(); for (VersionVO vo:voList){ System.out.println(vo); } /**-------- 删除Project数据 ----- **/ projectListnm.queryAll(Project.class); System.out.println(删除前 Project数据条数projectList.size()); nm.delete(Project.class,new Long[]{1L,2L,3L}); System.out.println(Project 数据删除完成); projectListnm.queryAll(Project.class); System.out.println(删除后 Project数据条数projectList.size()); //批量删除 nm.delete(Version.class,new Long[]{1L,2L,3L}); System.out.println(Version 数据删除完成); } /** * 添加或删除 Version 数据 * param nm */ public static void addVersion(NitriteDataManager nm){ Version version1new Version(); version1.setName(是版本1); version1.setNameEn(Version 1); version1.setProjectId(1L); version1.setDate(2026); nm.insertOrUpdate(version1); Version version2new Version(); version2.setName(是版本2); version2.setNameEn(Version 2); version2.setProjectId(2L); version2.setDate(2027); nm.insertOrUpdate(version2); Version version3new Version(); version3.setName(第三条数据); version3.setNameEn(Version 3); version3.setProjectId(3L); version3.setDate(2028); nm.insertOrUpdate(version3); System.out.println(Version 数据添加完成); } /** * 添加 Project 数据 * param nm */ public static void addProject(NitriteDataManager nm){ Project project1new Project(); project1.setAge(7); project1.setName(项目1); project1.setSex(0); project1.setDate(数据1); nm.insertOrUpdate(project1); Project project2new Project(); project2.setAge(8); project2.setName(项目2); project2.setSex(0); project2.setDate(数据2); nm.insertOrUpdate(project2); Project project3new Project(); project3.setAge(9); project3.setName(项目3); project3.setSex(1); project3.setDate(数据3); nm.insertOrUpdate(project3); System.out.println(Project数据添加完成); } }

相关新闻

3步解决Mac读写NTFS硬盘难题:Nigate免费开源跨平台文件传输工具终极指南

3步解决Mac读写NTFS硬盘难题:Nigate免费开源跨平台文件传输工具终极指南

3步解决Mac读写NTFS硬盘难题:Nigate免费开源跨平台文件传输工具终极指南 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, …

2026/10/3 3:37:25 阅读更多 →
突破性GitHub加速方案:如何将国内访问速度提升10倍的智能路由技术

突破性GitHub加速方案:如何将国内访问速度提升10倍的智能路由技术

突破性GitHub加速方案:如何将国内访问速度提升10倍的智能路由技术 【免费下载链接】Fast-GitHub 国内Github下载很慢,用上了这个插件后,下载速度嗖嗖嗖的~! 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 在当…

2026/10/13 13:56:45 阅读更多 →
Ngrok内网穿透实战:快速搭建临时HTTPS地址调试Webhook

Ngrok内网穿透实战:快速搭建临时HTTPS地址调试Webhook

1. 项目概述:为什么我们需要一个临时的外网访问地址?做开发或者运维的朋友,肯定都遇到过这个场景:你本地的服务跑得好好的,比如一个调试中的Web API,或者一个临时的管理后台,但你需要让外部的某…

2026/10/8 18:24:40 阅读更多 →

最新新闻

Q-Learning MATLAB源码解析与调参实战:从Q表到收敛自检

Q-Learning MATLAB源码解析与调参实战:从Q表到收敛自检

简介:这是一份以Matlab编写的Q-Learning强化学习算法源代码及逐段注释文档,适合初学者通过“王子寻找公主”的161网格游戏直观理解无模型条件下的决策流程。代码完整覆盖环境建模、可移动矩阵与奖赏矩阵设定、贝尔曼方程更新、ε-greedy策略选择等核心环…

2026/10/14 17:21:45 阅读更多 →
Vivado下带阻滤波器设计:从FIR系数到板上调试全攻略

Vivado下带阻滤波器设计:从FIR系数到板上调试全攻略

上个月调一块ADC采集板卡时遇到一个很典型的故障:传感器信号里始终叠着一段50Hz左右的工频干扰,不严重,但偏偏落在我关心的频段旁边,想用低通滤掉又怕把靠近它的有效成分一并削掉。当时项目里正好在用Vivado做整条信号链路&#x…

2026/10/14 17:21:45 阅读更多 →
用架构决策记录(ADR)文档化敏捷软件开发转型:完整示例与实战指南

用架构决策记录(ADR)文档化敏捷软件开发转型:完整示例与实战指南

【免费下载链接】architecture-decision-record Architecture decision record (ADR) examples for software planning, IT leadership, and template documentation 项目地址: https://gitcode.com/gh_mirrors/ar/architecture-decision-record 点击查看 免费下载 …

2026/10/14 17:21:45 阅读更多 →
盘点主流大厂SRC规则:哪些漏洞更容易通过审核拿奖励

盘点主流大厂SRC规则:哪些漏洞更容易通过审核拿奖励

盘点主流大厂 SRC 规则:哪些漏洞更容易通过审核拿奖励 刚入坑 SRC 的新手,基本都踩过类似的坑:埋头挖洞、熬夜提交一堆漏洞,结果却不太理想——要么直接被厂商驳回,要么定级很低,只能拿到一点象征性的奖励…

2026/10/14 17:21:44 阅读更多 →
T3 Stack全栈开发实战:TypeScript、Next.js与tRPC的完整链路

T3 Stack全栈开发实战:TypeScript、Next.js与tRPC的完整链路

1. 从项目代号说起:t3code 到底是个什么项目第一次看到"t3code"这个名字,是在一个开发者社群的讨论帖里。当时大家正在聊个人项目的命名习惯,有人晒出了自己的仓库列表,其中一个文件夹就叫 t3code,旁边备注是…

2026/10/14 17:21:44 阅读更多 →
AWC 0017 Beta题单复盘:贪心、DP与线段树全解析

AWC 0017 Beta题单复盘:贪心、DP与线段树全解析

这周刷了一套 AWC 0017 Beta 的题单,从 A 到 E 五题完整走了一遍。先说结论:这是一场难度梯度非常舒服的周赛题单,A 题考的是最基础的取模与整数溢出意识,B 题是差分数组的板子题,C 题是经典的“截止日期 奖励最大化”…

2026/10/14 17:20:44 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →