Nitrite数据库(Java)使用和中文文档
2026/8/3 3:55:38 网站建设 项目流程

Nitrite是一种无服务器、嵌入式且自包含的 NoSQL 数据库。它不需要安装,只需要导入jar包即可使用。适合小型桌面/嵌入式项目。

在Java 桌面项目中需要保存数据到本地,还需要对这些数据做增删改查。最先想到的是用sqlite,但是本人不太想用jdbc去写sql,使用mybatis这些框架又很麻烦,谷歌的Room又不能直接在java客户端用。经过一番寻找试错,最后选择了Nitrite。

使用Nitrite很方便,导入jar包即可使用。

Nitrite官网: https://nitrite.dizitart.com

Nitrite项目地址:https://github.com/nitrite/nitrite-java

可以参考我写的demo:

github:https://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.version>4.3.2</nitrite.version> </properties> <dependencies> <dependency> <groupId>org.dizitart</groupId> <artifactId>nitrite</artifactId> <version>${nitrite.version}</version> </dependency> <dependency> <groupId>org.dizitart</groupId> <artifactId>nitrite-mvstore-adapter</artifactId> <version>${nitrite.version}</version> </dependency> <dependency> <groupId>org.dizitart</groupId> <artifactId>nitrite-jackson-mapper</artifactId> <version>${nitrite.version}</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.dizitart</groupId> <artifactId>nitrite-bom</artifactId> <version>${nitrite.version}</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement>

创建实体类

创建测试用的实体类 Project、Version、VersionVO,Version类的属性 projectId 用来存储Project类的id,VersionVO用于保存Version和Project关联查询的数据

Project.java

import 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.java

import 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.java

import java.util.List; /** * @author liuming */ public class VersionVO { private Long id; private String name; private String nameEn; private List<Project> 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 List<Project> getProjectList() { return this.projectList; } /** * 设置 * * @param projectList */ public void setProjectList(List<Project> projectList) { this.projectList = projectList; if(this.projectList!=null && !this.projectList.isEmpty()){ this.project=this.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 instance=new NitriteDataManager(); /** 数据库名 */ private final static String DB_NAME="data.db"; /** 数据库对象 */ private static Nitrite db; /** id字段的名称 */ private final static String ID_NAME="id"; private NitriteDataManager(){ } public static NitriteDataManager getInstance(){ if(db==null){ instance.initDb(null); } return instance; } /** * 初始化数据库 * @param path 数据库文件路径 */ public static void initDb(String path){ if(StringUtils.isBlank(path)){ path=System.getProperty("user.dir")+File.separator+DB_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(); db=null; } /** * 新增或删除。此方法针对id字段做了处理,如果为long和int类型且值为null,自动用当前id的最大值生成id,效果类似id自增 * @param t 数据 * @return * @param <T> */ public <T> int insertOrUpdate(T t){ try{ Class cls=t.getClass(); ObjectRepository repository=db.getRepository(cls); //如果存在id字段,并且id为空且id类型为 long/int/Long/Integer ,自动生成一个id Field field=cls.getDeclaredField(ID_NAME); if(field!=null){ Class type=field.getType(); if(type== Long.class || type==Integer.class || type==long.class || type==int.class){ field.setAccessible(true); Object obj=field.get(t); if(obj==null){ long id=generateId(repository,field,t); if(type==Long.class || type==long.class) { field.set(t, id); }else{ field.set(t, (int)id); } } field.setAccessible(false); } } WriteResult result=repository.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 cls=t.getClass(); try{ ObjectRepository repository=db.getRepository(cls); WriteResult result=repository.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(ids==null || ids.length==0){ return 0; } try{ ObjectRepository repository=db.getRepository(cls); WriteResult result=repository.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> List<T> queryAll(Class<T> cls){ try{ ObjectRepository repository=db.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> List<T> queryList(Class<T> cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repository=db.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(Class<T> cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repository=db.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(Class<T> cls,Long id){ try{ ObjectRepository repository=db.getRepository(cls); return (T)repository.getById(id); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException("查询数据失败"); } } /** * 获取查询的游标 * @param cls 类 * @param filter 过滤器 * @param findOptions 查询选项 * @return */ public <T> Cursor<T> getQueryCursor(Class<T> cls,Filter filter,FindOptions findOptions){ try{ ObjectRepository repository=db.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> ObjectRepository<T> 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 path=System.getProperty("user.dir")+File.separator+"data-2.db"; // //设置数据库存储路径,并使用MVStore存储数据,创建Nitrite对象 // NitriteDataManager.initDb(path); /** ----------- 添加/修改 数据 -------- **/ NitriteDataManager nm=NitriteDataManager.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"); List<Project> projectList=nm.queryAll(Project.class); for (Project project:projectList){ System.out.println(project); } System.out.println("Project 根据 sex 和 age 排序"); FindOptions findOptions=FindOptions.orderBy("sex", SortOrder.Descending); //多列排序需要用findOptions.orderBy()对象获取SortableFields对象,再往SortableFields中添加排序数据 findOptions.orderBy().addField("age",SortOrder.Ascending); //如果需要做分页查询,使用如下代码。skip是跳过多少行,limit是拿多少条数据 // findOptions.skip(1L).limit(1L); projectList=nm.queryList(Project.class,null,findOptions); for (Project project:projectList){ System.out.println(project); } System.out.println("根据Id查询Version"); //根据id查询数据 Version version=nm.queryById(Version.class,1L); System.out.println(version); //通过条件查询数据。此处使用正则匹配。此方式会扫描整个集合以查找匹配的文档,不使用索引。 // List<Version> versionList=nm.queryList(Version.class,FluentFilter.where("name").regex(".*?版本.*?"),null); //通过条件查询数据。此处使用text过滤器。需要为属性添加全局索引。 List<Version> versionList=nm.queryList(Version.class,FluentFilter.where("name").text("*版本*"),null); System.out.println("按条件查询 name 中包含 \"版本\" 的结果:"); for(Version v:versionList){ System.out.println(v); } //联接查询,join Cursor<Project> projectCursor=nm.getQueryCursor(Project.class,null,null); Cursor<Version> versionCursor=nm.getQueryCursor(Version.class,null,null); Lookup lookup = new Lookup(); lookup.setLocalField("projectId"); lookup.setForeignField("id"); //查出来的是个list,不是单个对象,需要手动处理一下,可以参考 VersionVO 的 setProjectList 方法 lookup.setTargetField("projectList"); RecordStream stream=versionCursor.join(projectCursor,lookup, VersionVO.class); System.out.println("关联查询的结果:"); List<VersionVO> voList=stream.toList(); for (VersionVO vo:voList){ System.out.println(vo); } /**-------- 删除Project数据 ----- **/ projectList=nm.queryAll(Project.class); System.out.println("删除前 Project数据条数:"+projectList.size()); nm.delete(Project.class,new Long[]{1L,2L,3L}); System.out.println("Project 数据删除完成"); projectList=nm.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 version1=new Version(); version1.setName("是版本1"); version1.setNameEn("Version 1"); version1.setProjectId(1L); version1.setDate("2026"); nm.insertOrUpdate(version1); Version version2=new Version(); version2.setName("是版本2"); version2.setNameEn("Version 2"); version2.setProjectId(2L); version2.setDate("2027"); nm.insertOrUpdate(version2); Version version3=new 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 project1=new Project(); project1.setAge(7); project1.setName("项目1"); project1.setSex(0); project1.setDate("数据1"); nm.insertOrUpdate(project1); Project project2=new Project(); project2.setAge(8); project2.setName("项目2"); project2.setSex(0); project2.setDate("数据2"); nm.insertOrUpdate(project2); Project project3=new Project(); project3.setAge(9); project3.setName("项目3"); project3.setSex(1); project3.setDate("数据3"); nm.insertOrUpdate(project3); System.out.println("Project数据添加完成"); } }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询