Flutter 5 大本地数据库解决方案


原文 https://levelup.gitconnected.com/top-5-local-database-solutions-for-flutter-development-6351cd494070

前言

这里列出了最流行的数据库解决方案以及代码示例。


选择正确的数据管理系统对于提高效率和可 extension 性以及影响可用性和用户体验至关重要。尽管 flutter 仍然处于早期阶段,但是有很多数据管理解决方案可供选择,其中一些已经可以投入生产。我将概述用于在本地维护数据的最常见的数据库管理系统。

正文

Sqflite

Sqflite 是一个著名的 SQLite flutter 插件。这是一个具有良好交易和批量支持的关系数据库。当数据库打开时,它会自动管理版本控制。它还包括用于常见 CRUD 操作的帮助器。后台线程处理所有数据库操作。它与 ACID 兼容,因此几乎支持所有 SQL 标准。如果您喜欢将自己的 SQL 查询编写为字符串,那么这个简单的插件将满足您的数据管理需求。

// open the databaseDatabase database = await openDatabase(path, version: 1,    onCreate: (Database db, int version) async {  // When creating the db, create the table  await db.execute(      'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)');});

// Insert some records in a transactionawait database.transaction((txn) async {  int id1 = await txn.rawInsert(      'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');  print('inserted1: $id1');  int id2 = await txn.rawInsert(      'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)',      ['another name', 12345678, 3.1416]);  print('inserted2: $id2');});

// Update some recordint count = await database.rawUpdate(    'UPDATE Test SET name = ?, value = ? WHERE name = ?',    ['updated name', '9876', 'some name']);print('updated: $count');

// Get the recordsList<Map> list = await database.rawQuery('SELECT * FROM Test');List<Map> expectedList = [  {'name': 'updated name', 'id': 1, 'value': 9876, 'num': 456.789},  {'name': 'another name', 'id': 2, 'value': 12345678, 'num': 3.1416}];

正如您从示例中看到的,我发现阅读这段代码并不容易。随着应用程序的增长,维护此代码将变得非常繁琐。因为 sqflite 是一个基本的数据库管理系统(DBMS)插件,所以我相信您应该构建自己的结构并将其包装在 sqflite 周围,就像大多数用于 flutter 的关系数据库管理系统包一样。

SQLite 通常是一个自包含的、无服务器的、轻量级的解决方案。它的性能是有争议的,但它可以让你的工作与一个耀眼的快速内存数据库。基础软件包包括移动平台支持。没有网络支持,但 sqflite_common_ffi 可以用来支持桌面平台。

floor

Floor 是一个非常有用的 SQLite 抽象,它包含一个对象映射器。它依赖于 sqflite,并在此基础上增加了类型安全等特性。它支持 sqflite 支持的所有内容,包括内存数据库。

虽然它充当 sqflite 的包装器,但它引入了更高级的概念,如 DAO 和实体。实体可以用来将内存中的对象映射到数据记录,而 DAO 允许您访问和操作数据。清楚地分隔实体、 DAO 和数据库总是一个好主意。您还可以为您的 DAO 编写好的测试,并确保您的查询通过这种方式得到验证。

@entityclass Person {  @primaryKey  final int id;

  final String name;

  Person(this.id, this.name);}

前面的代码示例演示如何创建实体。地板是指导创建适当的数据库表使用注释。这是一种非常用户友好的设计数据库的方法。让我们来看看如何构建 DAO。

@daoabstract class PersonDao {  @Query('SELECT * FROM Person')  Future<List<Person>> findAllPersons();

  @Query('SELECT * FROM Person WHERE id = :id')  Stream<Person?> findPersonById(int id);

  @insert  Future<void> insertPerson(Person person);}

您所要做的就是提供一个具有适当注释的抽象类。遗憾的是,没有查询 API,因此仍然必须以字符串形式提供 SQL 查询。这种方法对我来说特别没有吸引力,因为这些查询没有可用的语法检查。您仍然可以测试和验证这些查询。

final personDao = database.personDao;final person = Person(1, 'Frank');

await personDao.insertPerson(person);final result = await personDao.findPersonById(1);

地板是生成必要的代码在一个建设者的帮助下。因此,所有的 DAO 都存储在数据库中。要插入一个人,您可以调用 database. person. insert tPerson (person)。老实说,我不认为通过数据库对象访问所有 DAO 是一个好主意。然而,这种丑陋可以通过使用依赖注入(DI) container 来避免。

总的来说,地板是一个有前途的平方弗莱特包装与许多有用的功能。有关详细信息,请参阅他们的文档。它通过示例和图表清楚地展示了所有特性。

Drift (Moor)

Moor 无疑是功能最丰富的 Flutter 关系数据库解决方案。它也是 sqflite 的包装器,但是它提供了更强大的功能,并且包含一个查询 API。尽管 Web 支持是实验性的,但它支持所有潜在的平台。此外,它还为事务、模式迁移、复杂的筛选器和表达式以及批处理提供了极好的支持。

它为 DAO 和实体(如 floor)提供了类似的支持,但是它是以一种高度模块化的方式进行的,允许您轻松地将它与 DI container 绑定结合起来。此解决方案的另一个优秀特性是内置的线程支持,它允许您在不需要额外工作的情况下跨隔离区运行数据库代码。最后,值得注意的是,它包含一个用于 SQL 查询的集成 IDE。多酷啊!

让我们看一些代码示例,以便您可以将其与 floor 进行比较。下面是一个如何定义表的示例。

class Todos extends Table {  IntColumn get id => integer().autoIncrement()();  TextColumn get title => text().withLength(min: 6, max: 32)();  TextColumn get content => text().named('body')();  IntColumn get category => integer().nullable()();}

我们不使用注释,而是 extension Table 类,并为该列的数据类型使用特定的列类型。在这里,我们可以为单独的列配置各种属性,比如空性、外键和约束。说到桌子的定义,我必须承认我喜欢地板的方式。它只是对我来说更具可读性,并且注释的使用是一个绝妙的概念。

这就是 DAO 的定义方式。

@DriftAccessor(tables: [Todos])class TodosDao extends DatabaseAccessor<MyDatabase> with _$TodosDaoMixin {  // this constructor is required so that the main database can create an instance  // of this object.  TodosDao(MyDatabase db) : super(db);

  Stream<List<TodoEntry>> todosInCategory(Category category) {    if (category == null) {      return (select(todos)..where((t) => isNull(t.category))).watch();    } else {      return (select(todos)..where((t) => t.category.equals(category.id)))          .watch();    }  }}

毫无疑问,您首先注意到的是查询 API,而不是基于文本的 sql 查询。就个人而言,我喜欢查询 API,因为随着项目的 extension ,您会发现一些过滤器或数据访问方法可能会被简化。您可以在不牺牲查询可读性的情况下减少代码复制。我明白,通过 SQLite 语法学习另一种 API 可能不是最舒服的选择,但它绝对是值得的。我很欣赏这样的想法,即完整的数据库逻辑可以用 Dart 编写,并且在编译过程中可以检测到可能的错误。

当我需要使用关系型本地数据库时,漂移是我的第一选择。它只是提供了一种更有效的开发和伸缩方式。因为该插件使用代码生成,所以我相信实体和 DAO 声明可能更加用户友好。该项目仍在积极开发中,每个新版本都比前一个版本有所改进。

hive

Hive 是一个非常强大和有前途的 NoSQL 数据库。它与所有平台兼容,包括网络。我没有第一手的知识,但是快速的搜索显示读写速度的基准是非常令人印象深刻的。它有很强的内置加密。将其视为一个映射,其中对象以键-值对的形式存储。

因为它是一个 NoSQL 数据库,术语“ table”被替换为术语“ box”(kind of)。因此,您的数据被组织在这些框中。因为 NoSQL 具有很强的适应性,所以您可以为每个值定义任何类型的结构。因此,框的存在并不意味着存在一致的数据模型。如果您的应用程序需要为相同类型的实体提供灵活的数据列,那么这可能是一个重要的好处。

在使用框之前,必须首先打开它,以便将数据从本地存储加载到内存中以便进行即时访问。因此,您可以在不使用“ wait”的情况下进行查询,并且在 widget 的构建方法中使用它将非常简单。如果你不需要立即访问,你可以随时使用懒箱。

var box = Hive.box('products');

box.put('name', 'foo');

var name = box.get('name');

print('Product Name: $name');

您可以看到如何使用上面的 Hive 创建一个盒子。这不难理解。Hive 为所有基本类型提供了基本支持,但大多数情况下,您希望存储的是实体或实体的子集。为此,必须首先创建 TypeAdapter。这里有一个例子:

@HiveType(typeId: 0)class Product extends HiveObject {

  @HiveField(0)  String name;

  @HiveField(1)  int price;

  @HiveField(2)  String color;}

将 HiveObjects 视为实体。不过,在这种情况下,您可以 extension Product 并将其存储在同一个框中。下面是如何使用 Product 类的示例。

var box = await Hive.openBox('products');

var product = Product()  ..name = 'Foo'  ..price = 10  ..color = 'orange';box.add(product);

print(box.getAt(0)); // Foo - 10 - orange

product.price = 12;product.save();

print(box.getAt(0)) // Foo - 12 - orange

在我看来,蜂巢是小规模和灵活应用程序的理想选择。它易于学习并适应变化。我很高兴能把它用在一个副业上。

sembast

Sembast 是另一个用于 Flutter (和 Dart )应用程序的 NoSQL 数据库,它支持所有可能的平台,包括 web (通过 Sembast web 包)。Sembast 由于其有前途的功能而在这个名单上,但我不相信它还在那里。它以类似于 Hive 的方式管理数据库,但有一些不同之处。我没有看到任何对实体的支持,我认为这在数据模式可读性方面是有益的。您仍然可以使用自己的类型,但它们必须是正确编码/解码的 JSON。

// File path to a file in the current directoryString dbPath = 'sample.db';DatabaseFactory dbFactory = databaseFactoryIo;

// We use the database factory to open the databaseDatabase db = await dbFactory.openDatabase(dbPath);

若要使用数据库,必须使用。分贝 extension 。此文件将用于所有数据库操作,并将根据需要进行更新。如果你不想使用这个选项,你仍然可以通过 sqflite 使用 Sembast。

// dynamically typed storevar store = StoreRef.main();// Easy to put/get simple values or map// A key can be of type int or String and the value can be anything as long as it can// be properly JSON encoded/decodedawait store.record('title').put(db, 'Simple application');await store.record('version').put(db, 10);await store.record('settings').put(db, {'offline': true});

// read valuesvar title = await store.record('title').get(db) as String;var version = await store.record('version').get(db) as int;var settings = await store.record('settings').get(db) as Map;

// ...and deleteawait store.record('version').delete(db);

在上面,您可以看到如何保存和读取记录。API 学起来很简单,但我更喜欢 Hive 语法而不是 Sembast 语法,因为它省去了在读取数据时“等待”的需要。但是,你仍然可以探索森巴斯特。值得注意的是,Sembast 支持“触发器”和“数据加密”这两个有用的特性可以帮助提高数据的安全性和一致性。

shared_preferences

如果您的应用程序不是数据关键型的,那么您就不需要花费大量时间学习额外的库。共享首选项使用特定于平台的存储 API 来存储和读取键值对。因为数据可以异步地保存到磁盘上,所以这个插件不应该用来存储关键数据。

_incrementCounter() async {  SharedPreferences prefs = await SharedPreferences.getInstance();  int counter = (prefs.getInt('counter') ?? 0) + 1;  print('Pressed $counter times.');  await prefs.setInt('counter', counter);}

正如您所看到的,使用该插件是简单和直接的。

关系数据库或 NoSQL

我觉得有义务解释关系数据库管理系统和 NoSQL 解决方案之间的区别。它们都有优点和缺点,但这不是重点。因为我们不能说一个比另一个好。归根结底就是你的需要。

「关系数据库 Relational DBMS:」

  • 数据一致性
  • 数据模式不太可能发生显著变化
  • 存储实际数据和数值数据

「NoSQL:」

  • 数量庞大,数据混乱
  • 灵活的模式定义,实时数据,更容易伸缩
  • 没有连接,查询速度更快,但数据复制更多

这些是两个数据库系统的关键特性。当涉及到使用本地数据库进行开发时,您应该彻底理解应用程序的数据需求。

如果您正在开发同时具有数字产品和实体产品的商店应用程序,那么这些产品可能具有多种特性。即使是同一类别的产品也可以有不同的特点。在这种情况下,您需要一个 NoSQL 数据库,否则最终会得到一大堆可为空的列。

考虑另一个示例应用程序,比如加密货币投资组合应用程序。当然,您的应用程序将依赖于第三方 API。这些 API 经常更改。您可以使用 NoSQL 数据库,而不是每次都更改模式,这比使用关系型 DBMS 更容易适应更改。我相信你明白这一点,但是你可以关于这一主题的文章,以帮助你为未来的项目做出更好的决策。

Conclusion

结论

我试图简化用于 flutter 开发的最流行的本地数据库解决方案的基本原理。这些都是非常棒的软件包,背后都有非常聪明的头脑。试着通过给他们星级或者为他们的知识库做贡献来帮助他们。我希望这篇文章对你决定下一个数据库解决方案有帮助。

最后一个想法。我很了解「幻界」和「伊萨」的数据库我知道他们正在崛起。这里没有列出它们,因为它们最近才发布了 alpha 版本。

谢谢你宝贵的时间。

结束语

如果本文对你有帮助,请转发让更多的朋友阅读。

也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。

祝你有一个美好的一天~


© 猫哥

  • 微信 ducafecat

  • https://wiki.ducafecat.tech

  • https://video.ducafecat.tech

本文由 mdnice 多平台发布

Flutter 5 大本地数据库解决方案相关推荐

  1. Navicat连接本地数据库报错问题解决方案

    Navicat连接本地数据库报错问题解决方案 参考文章: (1)Navicat连接本地数据库报错问题解决方案 (2)https://www.cnblogs.com/wjah110/p/9811448. ...

  2. JSP大作业数据库_本地MySQL【种种问题】

    JSP大作业数据库MySQL第1部分.zip: 链接:https://pan.baidu.com/s/1ZHwxAnATQSSjC-F6EpxeUw 提取码:30kw JSP大作业数据库MySQL第二 ...

  3. 前沿分享|阿里云数据库解决方案架构师 王宏宇:云原生数据仓库AnalyticDB在零售行业的深度应用和业务价值

    简介:本篇内容为2021云栖大会-云原生数据仓库AnalyticDB技术与实践峰会分论坛中,阿里云数据库解决方案架构师 王宏宇关于"云原生数据仓库AnalyticDB在零售行业的深度应用和业 ...

  4. 使用Guardium大数据智能解决方案释放Guardium数据的价值

    编辑的注解:本文反映了由于宣布JSonar的SonarG解决方案已作为IBM Guardium产品组合的一部分(名称为Guardium Big Data Intelligence)从IBM获得的结果, ...

  5. 城市交通大数据可视化解决方案

    作者 | 网络大数据 如今,城市交通拥堵状况日益严重.虽说智能交通布局在不断地完善,但交通管理仍旧收效甚微.数据独立存储难以融合应用.数据内在规律难寻.数据缺乏深度挖掘等诸多问题,其困难重重,该如何解 ...

  6. Oracle数据库解决方案集锦

    前言 大家好,在进入正题之前,首先想说一下为什么会有这篇文章.经常有用户或者销售来问我,我们Oracle有没有数字化转型的方案?有没有数据底座,湖仓一体的方案?有没有大数据,数据治理的方案?诸如此类. ...

  7. 华为大企业信息安全解决方案简介

    from:http://support.huawei.com/ecommunity/bbs/10151893.html 华为大企业信息安全解决方案主要面向大企业客户,立足于企业信息安全的主要痛点,诠释 ...

  8. 数据挑战上升,传统商业数据库性能和容量瓶颈,怎么破?看「DaoCloud 道客」联合 PingCAP 发布企业级云原生数据库解决方案

    01 数据浪潮席卷而来 随着大数据.物联网和 5G 等技术的兴起与逐步普及,企业业务数据剧增,基于互联网的高频访问场景成为常态.业务侧对 IT 系统整体的响应速度及稳定性要求更为严苛,尤其数据库这个关 ...

  9. 重磅!分布式数据库解决方案Apache ShardingSphere毕业成为顶级项目

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 全球最大的开源软件基金会 Apache 软件基金会(以下简称 Ap ...

最新文章

  1. 深度学习环境配置指南:Pytorch、TensorFlow、Keras
  2. java的虚引用_你不可不知的Java引用类型之——虚引用
  3. 原创“.NET研究”企业级控件库之图片浏览控件
  4. 【python】一个简单的贪婪爬虫
  5. 面向对象编程(第四篇)
  6. Linux中添加pycharm源,linux下python+pycharm安装
  7. Golang实现一个密码生成器
  8. redis和php有什么,redis主要用来做什么
  9. Java 多线程 简单实例 (Thread)
  10. SQL CHECKSUM 关键字
  11. 新浪微博批量删除微博的方法
  12. FILD FLD FSTP
  13. ROS-Navigation之map_server笔记及程序解析
  14. 如何找到自己正确需要的抖音搜索关键词
  15. JS脚本defer的作用 (转自一路前行)
  16. 【推荐系统论文精读系列】(一)--Amazon.com Recommendations
  17. 僵尸进程zombie与孤儿进程orphan
  18. HTTP基本使用方法
  19. 如何在xp系统中安装python(安装anachonda)
  20. Telerik Silverlight 之Charting控件的使用

热门文章

  1. AutoLeaders控制组——C语言指针和字符串学习笔记
  2. 总结一下php合并数组的几种方法
  3. 长城数艺:推进文化艺术品数字化发展,引领书画数字藏品
  4. IPVS之NAT转发模式
  5. js延时刷新本页面代码
  6. xrea mysql密码_Xrea日本老牌免费空间开放申请:1GB空间可绑域名
  7. frp+nginx+xposed搭建xp模块集群
  8. 看看三星的两款新Gear智能手表
  9. 还敢用智能手表吗?三星Gear Live会泄露用户数据
  10. 银行应用软件:零售银行业务中谁才是赢家