【本地数据库】介绍Isar的类定义和数据操作方法!!

以前,我发布了一篇关于Isar的基础文章。

这次,我将更详细地介绍Isar的类定义和数据操作方法。希望对你的开发有所帮助!

准备工作

使用Isar时,需要进行以下准备工作。

配置pubspec.yaml

// 请添加以下包。
dependencies:
  isar:
  isar_flutter_libs:

dev_dependencies:
  build_runner:
  isar_generator:

创建Isar实例

import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';

// 如果使用Riverpod
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// 自己创建的Isar提供者的存储位置
import 'package:myApp/email_repository.dart';


// 在main函数中创建
Future<void> main() async {
  // 指定本地数据库的保存位置
  final dir = await getApplicationSupportDirectory();

  // 创建Isar实例
  final isar = await Isar.open([EmailSchema], directory: dir.path);

  // 创建Isar实例
  runApp(ProviderScope(
    overrides: [
      emailIsarProvider.overrideWithValue(isar),
    ],
    child: const MyApp(),
  ));


// 参考)使用多个集合时
Future<void> main() async {
  // 指定本地数据库的保存位置
  final dir = await getApplicationSupportDirectory();

  // 创建Isar实例
  final isar = await Isar.open([UserSchema, EmailSchema], directory: dir.path);

  // 创建Isar实例
  runApp(ProviderScope(
    overrides: [
      userIsarProvider.overrideWithValue(isar),
      emailIsarProvider.overrideWithValue(isar),
    ],
    child: const MyApp(),
  ));
}

定义集合

在NoSQL中,数据以集合和文档的形式管理。与关系型数据库相比,关系如下。

 表 : 集合
 记录 : 文档

要定义Isar的集合,需要将数据结构定义为类。

基本集合定义

在Isar中,数据类使用@collection注解进行定义。以下是定义一个名为Email的集合的示例。

@collection
class Email {
  Email {
    Id? id;
    required title;
    required updatedAt;
  }
  Id? id; 
  final String title;
  @Index()  // 使用“@Index()”为下面的字段创建索引
  final DateTime updatedAt;
}

此类具有id、title和updatedAt三个字段。id字段用于唯一标识数据库中的每个条目。

id在Isar中会自动生成。当你将title和updatedAt添加到IsarDB时,id会自动生成。

实际存储的数据图像:

{
  "id": 1234, // 自动生成的id
  "title": "How to use Isar!!"
  "updatedAt": yyyy-mm-dd hh:mm
}

层次集合定义

有时,你可能需要将文档结构化为层次数据结构。这时可以使用@embedded注解定义子类。

@collection
class Email {
  Email {
    Id? id;
    required title;
    required updatedAt;
    required recipient;
  }
  Id? id; 
  final String title;
  @Index()
  final DateTime updatedAt;
  final Recipient? recipient;
}

@embedded
class Recipient {
  String? name;
  String? address;
}

在这个结构中,Recipient类被嵌入到Email类中。

数据图像:

{
  "id": 99999,
  "title": "How to use Isar!!",
  "recipient": {
    "name": "John Doe",
    "address": "john.doe@gmail.com"
  }
}

定义类后,需要运行build_runner以生成~.g.dart。请在终端中执行以下命令。

// 清理缓存
flutter pub run build_runner clean
// 生成代码
flutter pub run build_runner build --delete-conflicting-outputs

编写CRUD查询

接下来是使用Isar进行CRUD操作。

单个数据的插入和更新

要将新数据添加到数据库,需从集合定义中创建实例并将其保存到数据库。使用”put“方法。如果存在相同id的数据,则更新;如果不存在,则插入。

final Isar _isar; // 以下省略

final email = Email()
  ..title = "How to use Isar CRUD!!"
  ..recipient = Recipient()
      ..name = "Jane Doe"
      ..address = "jane.doe@gmail

.com";

await _isar.emails.put(email);
//emails是在生成文件(在本例中为email_dto.g.dart)中定义的集合类

多个数据的插入和更新

通常在处理多个数据时,使用writeTxn方法进行事务处理。插入或更新多个数据时,使用”putAll“方法。

await isar.writeTxn(() async {
  await isar.emails.putAll([email1, email2]);
});

删除单个数据

要删除数据,请指定要删除数据的id。使用”delete“方法。

await isar.emails.delete(emailId);

删除多个数据

要删除符合条件的多个数据,使用”deleteAll“方法。

await isar.emails.delete(emailId);

编写搜索查询

接下来介绍一些在数据库中搜索数据时的方便方法。

Where子句

要查找满足特定条件的数据,使用”where“方法。但where只能用于具有索引(带有@Index()注解)的字段。

使用where时,在”where()”和”findAll()”之间添加条件。

// 查找updatedAt为指定时间的文档
final results = isar.emails
    .where()
    .updatedAtEqualTo("2024-12-31 23:59")
    .findAll();

Where子句中可以使用以下条件。

使用Filter子句

要设置更复杂的条件,使用”filter“方法。filter可以用于没有索引的字段,但速度比where慢。(可能因为先获取数据再进行筛选)

使用filter时,在”filter()”和”findAll()”之间添加条件。

// 查找以"How"开头(不区分大小写)的文档
final filteredResults = isar.emails
    .filter()
    .titleStartsWith("How", caseSensitive: false)
    .findAll();

其他条件

除了上面的条件,还可以使用其他各种条件进行搜索。这些条件在~.g.dart文件中创建。

And和Or等逻辑运算符

可以使用And和Or指定多个条件。

// 查找以"How"开头并且updatedAt为指定时间的文档
final filteredResults = isar.emails
    .filter()
    .titleStartsWith("How")
    .and()
    .updatedAtEqualTo("2024-12-31 23:59")
    .findAll();

还可以使用其他常见的SQL运算符。

组合Where子句和Filter子句

通常会创建组合了Where和Filter的查询。

// 查找title大于"How"且updatedAt不为Null的文档
final filteredResults = isar.emails
    .titleGreaterThan("How")
    .filter()
    .updatedAtIsNotNull()
    .findAll();

由于Where的速度更快,应尽可能使用Where筛选目标,再使用Filter指定复杂条件。

Offset和Limit

要根据数据数量而非内容获取部分结果,设置”offset“和”limit“。offset是从开始不获取的数量,limit是获取的数量。

final paginatedResults = isar.emails
    .where()
    .findAll(offset: 10, limit: 5); // 从第11个开始获取5个

全体搜索

要获取数据库中的所有数据,只使用”findAll“。

final allEmails = await isar.emails
    .findAll();

最后

本文介绍了使用Flutter和Isar高效管理数据的基本方法。Isar还有很多便捷的功能,本次未能全部介绍,后续会继续撰写相关文章。

官方网站也有使用方法的说明,请参考!!
https://isar.dev/zh/crud.html

标题和URL已复制