Flutter-使用跨平台数据库Isar

1 概述

Isar是专门为Flutter打造的跨平台数据库(当前版本不支持web),支持ACID语义、全文搜索、复合索引和多条目索引等功能,单个NoSQL数据库实例即能支持存入数十万的数据并能保证高速的异步查询。

库:https://pub.dev/packages/isar

2 安装

pubspec.yaml文件中增加以下引用:

dependencies:
  isar:
  isar_flutter_libs:

dev_dependencies:
  isar_generator:
  build_runner:

3 定义表

import 'package:isar/isar.dart';
part 'table.g.dart';

// 类名即表名
@collection
class Email {
  Id id = Isar.autoIncrement; // 唯一自增ID;必须字段。
  String? title;
  DateTime? dateTime;

  @Index()
  int? attachmentSize; // 索引

  // 模拟类嵌套
  Recepient? recipient;
}

例如上面的代码table.dart,首先在头部加入part引用代码 part '类名.g.dart',这个文件稍后我们会通过代码生成器(build_runner)来生成。例如定义一个类Email,在类名上面增加@collection标记,这个类名就是数据库的表名。支持类的嵌套使用,被嵌套的类需要在类名上增加@embedded标记。

表定义完后(以及当以后再修改时),在控制台中运行以下命令生成该表的代码文件,例如table.g.dart

flutter pub run build_runner build

4 基本使用

这里简单介绍基本的代码,详细请参考官方文档:https://isar.dev/zh/tutorials/quickstart.html

本文的全部示例代码:https://github.com/tilongzs/flutter_study_demo/tree/master/database_isar_test

4.1 打开数据库

late Isar _isar; // Isar 实例

void openDB() async{
    final dir = "D:/";
    _isar = await Isar.open(
      [EmailSchema],
      directory: dir,
      name: 'testdb'
    );

    if(_isar == null){
      print('数据库打开失败');
    }else{
      print('数据库打开成功');
    }
  }

在Windows平台执行后会在D盘生成testdb.isar数据库文件。

4.2 增

Future<int> add() async{
    // 创建一行数据
    final newEmail = Email();
    newEmail.title = '邮件标题';
    final recipient = Recepient();
    recipient.name = 'mengmei';
    recipient.address = 'mm@mengmei.moe';
    newEmail.recipient = recipient;

    // 存入数据库
    await _isar.writeTxn(() async { // 读写操作的代码必须放置在isar.writeTxn()中
      _currentEmailID = await _isar.emails.put(newEmail);
      print('新增一行数据 id:${newEmail.id}');
    });

    return _currentEmailID;
  }

新增的一行数据使用唯一id标识该行数据,之后对该行数据的修改、删除等操作均使用该id。注意对数据的操作需要放置在isar.writeTxn()中。

4.3 删

删除一行数据

Future<bool> delete() async{
    if(_currentEmailID != 0){
      var ret = false;
      await _isar.writeTxn(() async { // 读写操作的代码必须放置在isar.writeTxn()中
        ret = await _isar.emails.delete(_currentEmailID);
        print('删除一行数据 id:$_currentEmailID ${ret}');
      });

      return ret;
    }

    print('先增加数据');
    return true;
  }

清空表

Future<void> clear() async{
    await _isar.writeTxn(() async { // 写操作的代码必须放置在isar.writeTxn()中
      _isar.emails.clear();
      print('清空表');
    });
  }

删除所有表

Future<void> deleteAllData() async{
    await _isar.writeTxn(() async { // 写操作的代码必须放置在isar.writeTxn()中
      _isar.clear();
      print('删除所有表');
    });
  }

4.4 改

Future<void> modify() async{
    // 使用唯一id查找数据
    final existingEmail = await _isar.emails.get(_currentEmailID);
    if(existingEmail == null){
      print('没有找到数据 id:$_currentEmailID');
    }else{
      // 修改数据
      existingEmail.title = '修改后的数据';
      existingEmail.dateTime = DateTime.now();
      await _isar.writeTxn(() async { // 写操作的代码必须放置在isar.writeTxn()中
        _currentEmailID = await _isar.emails.put(existingEmail);
        print('修改一行数据 id:$_currentEmailID title.title=${existingEmail.title} datetime:${existingEmail.dateTime}');
      });
    }
  }

4.5 查

使用唯一id查找数据

void find() async{
    if(_currentEmailID != 0){
      // 使用唯一id查找数据
      final existingEmail = await _isar.emails.get(_currentEmailID);
      if(existingEmail == null){
        print('没有找到数据 id:$_currentEmailID');
      }else{
        print('找到数据 id:$_currentEmailID title:${existingEmail.title} datetime:${existingEmail.dateTime}');
      }

      return;
    }

    print('先增加数据');
  }

使用索引查询where() https://isar.dev/zh/queries.html#where-%E5%AD%90%E5%8F%A5

void whereAttachmentSize() async{
    final result = await _isar.emails.where().attachmentSizeEqualTo(2).findAll();
    print('查找附件大小为2的所有数据 共${result.length}个');
    result.forEach((e) {
      print('查找到数据 id:${e.id} datetime:${e.dateTime}');
    });
  }

使用非索引查询filter() https://isar.dev/zh/queries.html#filter

void filterDatetime() async{
    final result = await _isar.emails.filter().dateTimeLessThan(DateTime.now()).findAll();
    print('查找比当前时间小的所有数据 共${result.length}个');
    result.forEach((e) {
      print('查找到数据 id:${e.id} datetime:${e.dateTime}');
    });
  }

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注