Flutter 数据库drift和floor

84 阅读4分钟

一、数据库选型floor与drift

1. 基本概述

1.数据操作插件

drift地址: pub.dev/packages/dr…
floor地址: pub.dev/packages/fl…

2. 插件定位

两者的底层均是sqlite数据库,中间层是sqlite3,它们主要操作的是上层的CURD

2. 官方数据对比

1.pub热度对比:

更新日期点赞数评分流行度平台支持
drift5月10日 👍🏻1041 👍🏻140 👍🏻99% 👍🏻全平台 👍🏻
floor4月25日67411098%Android/iOS/Mac

从pub上的数据来看,流行度方面,2者相差不大,drift稍微领先一点;不过点赞和评分方面,drift占优

2.Github对比:

数据收集日期:5月26日

最后提交日期提交数StarIssues
drift5月25日 👍🏻3054 👍🏻2000+ 👍🏻118 👍🏻
floor4月25日256824102

5月期间,Flutter发布了3.10的新版本,drift紧跟Flutter3.10适配,floor一个月没有人提交代码

在Github上,drift优势比floor大,活跃度也高,出现问题反馈比较及时。

3. 文档方面对比

drift文档地址:drift.simonbinder.eu/

floor文档地址:pinchbv.github.io/floor/

两者都提供英文文档,也提供文档搜索功能,区别不大

4.设计方面

两者都是基于sqlite3和build_runner来开发的,不过drift支持更多的平台,也支持加密数据库

1. drift数据库生成原理:

2. floor数据库生成原理:

tablemodeldaomigration
drift1.支持从sql生成 2. 支持从dart table类生成1.支持从sql生成 2. 支持从dart table类生成 3. 支持使用自定义的model 类1. 支持从sql生成dao 2.支持从dart dao 运行时生成sql语句(开发者不写SQL) > 直接运行sql,不用dao1. sql方式 2dart table类生成方式
floor支持从dart model 类生成NO支持从在dao中写sql生成CURD操作> 可以直接运行sql,不用daosql方式
总结来说:
1.drift支持sql和dart class 混合生成table、model、dao等代码;生成的model会生成比较方法,方便比较;无论哪种方式必须要有table
2. floor仅支持model中生成table、dao的具体查询必须要编写sql
3. 2者都支持直接运行sql

5.代码示例:

drift表和 dao 定义


///drift表定义
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()();
}
///drift dao定义
Future<List<Todo>> get allTodoEntries => select(todos).get();

Future<List<Todo>> limitTodos(int limit, {int offset}) {
  return (select(todos)..limit(limit, offset: offset)).get();
}

Future<List<Todo>> sortEntriesAlphabetically() {
  return (select(todos)..orderBy([(t) => OrderingTerm(expression: t.title)])).get();
}

Stream<Todo> entryById(int id) {
  return (select(todos)..where((t) => t.id.equals(id))).watchSingle();
}

floor表和 dao 定义

    ///floor表定义
    @Entity(tableName: 'person')
    class Person {
      @PrimaryKey(autoGenerate: true)
      final int id;

      @ColumnInfo(name: 'custom_name')
      final String name;

      Person(this.id, this.name);
    }
    ///floor dao定义
    @dao
    abstract class PersonDao {
      @Query('SELECT * FROM Person')
      Future<List<Person>> findAllPeople();

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

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

6. 优缺点:

1. drift相对比floor的优势:

2.NoSQL

3. drift支持开箱即用的在非 UI Isolate中进行数据库操作

4. 支持多表关联查询:Drift支持NoSQL多表关联查询,可以更方便地处理复杂的数据结构。

5. 支持自定义类型:Drift支持自定义类型,可以更好地处理复杂的数据类型。而Floor只支持基本数据类型(实验性中支持自定义类型)。

Drift支持多种开箱即用的列类型。您可以使用类型转换器type converters将自定义类存储在列中。

Dart typeColumnCorresponding SQLite type
intinteger()INTEGER
BigIntint64()INTEGER (useful for large values on the web)
doublereal()REAL
booleanboolean()INTEGER, which a CHECK to only allow 0 or 1
Stringtext()TEXT
DateTimedateTime()INTEGER (default) or TEXT depending on options
Uint8Listblob()BLOB
EnumintEnum()INTEGER (more information available here).
EnumtextEnum()TEXT (more information available here).

6. 目前发现的坑(缺点):

drift:

7.其生成的model => 写入数据库的map 是根据model中的构造方法来生成的,在使用自定义model的时候,如果字段不在构造方法中,会不生成该字段的解析

floor:

8.model生成table的时候不能使用minix

9. dao部分sql生成不了

10.父类和子类如果存在同名属性,会在table中生成2条同名column

7. floor切换drift方案:

1.table层

1. 方法一:支持把现有数据库DDL拿过来使用
 1.优点:简单,快速
 2. 缺点:如果使用自定义model,需要修改生成的代码
2. 方式二:编写Table类
1. 优点:数据结构相对方式一比较清晰;无需修改生成的代码
2.缺点:需要一定的人力成本编写代码

2. model层

可以考虑使用现有Model,drift支持该特性 Custom row classes (simonbinder.eu)

3.dao层

1.方式一:使用现有代码的SQL
1. 优点:较为简单
2.缺点:还是SQL
2.方式二:根据现有代码转换成NoSQL
1.优点:NoSQL,从代码角度保证SQL不错误
2.缺点:人力成本

4.migration方面

1. 方式一:使用现有代码的SQL
1.优点:快速
2. 缺点:还是SQL
2. 方式二:根据现有代码转换成NoSQL
1. 优点:代码清晰明了
2.缺点:人力成本