专业编程基础技术教程

网站首页 > 基础教程 正文

Flutter Isar 数据库使用快速入门

ccvgpt 2025-01-10 11:59:20 基础教程 3 ℃

Isar是德国巴伐利亚的一条河流名,本文介绍的Isar数据库是一个用Dart语言编写,专门为Flutter设计的高性能NoSQL数据库。

接下来,让我们一步一步学习在Flutter下使用Isar数据库。

Flutter Isar 数据库使用快速入门

添加依赖

使用下面两条命令添加依赖,第二行的 build_runner 是代码生成器,在第三步时会用到。

flutter pub add isar isar_flutter_libs
flutter pub add -d isar_generator build_runner

pubspec.yaml里面会添加以下依赖:

dependencies:
  isar: ^3.1.0+1
  isar_flutter_libs: ^3.1.0+1
dev_dependencies:
  build_runner: ^2.4.8 

声明一个collection

相当于创建一个表结构,id为自增字段,相当于索引,还有一个字符串类型字段name,和一个整型字段age。

import 'package:isar/isar.dart';

//.g.这行代表需要generate生成文件,生成的文件是user.dart的一部分
part 'user.g.dart'; 

@collection //用 @collection 给你的 Collection 类添加注解,代表这是一个表结构
class User {
  Id id = Isar.autoIncrement; // 你也可以用 id = null 来表示 id 是自增的

  String? name;
  
  int? age;
}

运行代码生成器 build_runner

dart run build_runner build //纯Dart项目使用这个命令来执行
flutter pub run build_runner build //Flutter项目使用这个命令,这个命令已弃用。
//Deprecated. Use `dart run` instead.

运行命令后会在user.dart所在的文件夹生成一个user.g.dart的文件,文件里有提示不要手动修改。

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart'; //user.dart的一部分

// **************************************************************************
// IsarCollectionGenerator
// **************************************************************************

// coverage:ignore-file
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types

extension GetUserCollection on Isar {
  IsarCollection<User> get users => this.collection();//这个地方的users就是以后的Isar.users
}
// 自动生成的UserSchema,创建Isar实例时要作为参数传入
const UserSchema = CollectionSchema(
  name: r'User',
  id: -7838171048429979076,
  properties: {
    r'age': PropertySchema(
      id: 0,
      name: r'age',
      type: IsarType.long,
    ),
    r'name': PropertySchema(
      id: 1,
      name: r'name',
      type: IsarType.string,
    )
  },

创建一个 Isar 实例

final dir = await getApplicationDocumentsDirectory();
//需要导入 import 'package:path_provider/path_provider.dart';
final isar = await Isar.open(
  [UserSchema], //上面user.g.dart文件自动生成
  directory: dir.path, //数据库路径
);
//UserSchema需要导入前面的user.dart

读写操作

第一种写法,通过事务writeTxn(Transaction)

事务就是“应用所有修改或什么都不修改”:在一个成功执行的事务里执行所有修改,或什么都不修改来保证数据的一致性。关于事务,官网的介绍:https://isar.dev/zh/transactions.html

下面用到了..级联操作符,可以参考我写的另外一篇文章。

final newUser = User()..name = 'Jane Doe'..age = 36;

await isar.writeTxn(() async {
  await isar.users.put(newUser); // 将新用户数据写入到 Isar
});

final existingUser = await isar.users.get(newUser.id); // 通过 Id 读取用户数据

await isar.writeTxn(() async {
  await isar.users.delete(existingUser.id!); // 通过 Id 删除指定用户
});

另外一种写法:

final newEmail = Email()..title = 'Amazing new database';

await isar.writeAsync(() {
  isar.emails.put(newEmail); // insert & update
});

final existingEmail = isar.emails.get(newEmail.id!); // get

await isar.writeAsync(() {
  isar.emails.delete(existingEmail.id!); // delete
});

CRUD增删改查操作

官网关于CRUD的介绍,https://isar.dev/zh/crud.html

  1. 通过 Id 来获取数据对象,我们可以通过以下代码来访问 Id 为 123 的菜单。
final recipe = await isar.recipes.get(123);
  1. 除了通过 Id 来获取对象数据,你也可以通过 .where() 和 .filter() 来查询匹配指定条件的多个对象,其返回的是数组 List:
final allRecipes = await isar.recipes.where().findAll();

final favouires = await isar.recipes.filter()
  .isFavoriteEqualTo(true)
  .findAll();

3.插入对象,Isar 的put() 方法会创建或者覆盖对象数据,取决于该对象是否已经存在于数据库里。

final pancakes = Recipe()
  ..name = 'Pancakes'
  ..lastCooked = DateTime.now()
  ..isFavorite = true;

await isar.writeTxn(() async {
  await isar.recipes.put(pancakes);
})

4.修改对象,collection.put(object) 方法兼有创建和修改的功能。如果一个object的 Id 是 null (或者不存在),它就会被创建;否则,它就会被修改。

await isar.writeTxn(() async {
  pancakes.isFavorite = false;
  await isar.recipes.put(recipe);
});

5.删除对象,用 collection.delete(id) 方法。这个方法会返回指定对象是否被删除(即返回布尔值)。

await isar.writeTxn(() async {
  final success = await isar.recipes.delete(123);
  print('Recipe deleted: $success');
});
//相似地,也有对应的批量删除方法,其返回结果是被删除对象的数量:
await isar.writeTxn(() async {
  final count = await isar.recipes.deleteAll([1, 2, 3]);
  print('We deleted $count recipes');
});
//如果你不知道你想删除对象的 Id,你可以先通过指定条件来查询:
await isar.writeTxn(() async {
  final count = await isar.recipes.filter()
    .isFavoriteEqualTo(false)
    .deleteAll();
  print('We deleted $count recipes');
});

查询

https://isar.dev/zh/queries.html

final importantEmails = isar.emails
  .where()
  .titleStartsWith('Important') // use index
  .limit(10)
  .findAll()

final specificEmails = isar.emails
  .filter()
  .recipient((q) => q.nameEqualTo('David')) // query embedded objects
  .or()
  .titleMatches('*university*', caseSensitive: false) // title containing 'university' (case insensitive)
  .findAll()

Tags:

最近发表
标签列表