Flutter数据库sqlite插件drift和floor选型和切换方案
-
基本概述
-
数据操作插件
drift地址: pub.dev/packages/dr…
floor地址: pub.dev/packages/fl…
-
插件定位
两者的底层均是sqlite数据库,中间层是sqlite3,它们主要操作的是上层的CURD
-
官方数据对比
-
pub热度对比:
更新日期 | 点赞数 | 评分 | 流行度 | 平台支持 | |
---|---|---|---|---|---|
drift | 5月10日 👍🏻 | 1041 👍🏻 | 140 👍🏻 | 99% 👍🏻 | 全平台 👍🏻 |
floor | 4月25日 | 674 | 110 | 98% | Android/iOS/Mac |
从pub上的数据来看,流行度方面,2者相差不大,drift稍微领先一点;不过点赞和评分方面,drift占优。
-
Github对比:
数据收集日期:5月26日
最后提交日期 | 提交数 | Star | Issues | |
---|---|---|---|---|
drift | 5月25日 👍🏻 | 3054 👍🏻 | 2000+ 👍🏻 | 118 👍🏻 |
floor | 4月25日 | 256 | 824 | 102 |
5月期间,Flutter发布了3.10的新版本,drift紧跟Flutter3.10适配,floor一个月没有人提交代码
在Github上,drift优势比floor大,活跃度也高,出现问题反馈比较及时。
-
文档方面对比
drift文档地址:drift.simonbinder.eu/
floor文档地址:pinchbv.github.io/floor/
两者都提供英文文档,也提供文档搜索功能,区别不大
-
设计方面
两者都是基于sqlite3和build_runner来开发的,不过drift支持更多的平台,也支持加密数据库
-
drift数据库生成原理:
-
floor数据库生成原理:
table | model | dao | migration | |
---|---|---|---|---|
drift | 1.支持从sql生成 2. 支持从dart table类生成 | 1.支持从sql生成 2. 支持从dart table类生成 3. 支持使用自定义的model 类 | 1. 支持从sql生成dao 2.支持从dart dao 运行时生成sql语句(开发者不写SQL) > 直接运行sql,不用dao | 1. sql方式 2dart table类生成方式 |
floor | 支持从dart model 类生成 | NO | 支持从在dao中写sql生成CURD操作> 可以直接运行sql,不用dao | sql方式 |
总结来说:
-
drift支持sql和dart class 混合生成table、model、dao等代码;生成的model会生成比较方法,方便比较;无论哪种方式必须要有table
-
floor仅支持model中生成table、dao的具体查询必须要编写sql
-
2者都支持直接运行sql
-
代码示例:
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);
}
-
优缺点:
-
drift相对比floor的优势:
- NoSQL
- drift支持开箱即用的在非UI Isolate中进行数据库操作
- 支持多表关联查询:Drift支持NoSQL多表关联查询,可以更方便地处理复杂的数据结构。
- 支持自定义类型:Drift支持自定义类型,可以更好地处理复杂的数据类型。而Floor只支持基本数据类型(实验性中支持自定义类型)。
Drift支持多种开箱即用的列类型。您可以使用类型转换器type converters将自定义类存储在列中。
Dart type | Column | Corresponding SQLite type |
---|---|---|
int | integer() | INTEGER |
BigInt | int64() | INTEGER (useful for large values on the web) |
double | real() | REAL |
boolean | boolean() | INTEGER, which a CHECK to only allow 0 or 1 |
String | text() | TEXT |
DateTime | dateTime() | INTEGER (default) or TEXT depending on options |
Uint8List | blob() | BLOB |
Enum | intEnum() | INTEGER (more information available here). |
Enum | textEnum() | TEXT (more information available here). |
-
目前发现的坑(缺点):
drift:
- 其生成的model => 写入数据库的map 是根据model中的构造方法来生成的,在使用自定义model的时候,如果字段不在构造方法中,会不生成该字段的解析
floor:
- model生成table的时候不能使用minix
- dao部分sql生成不了
- 父类和子类如果存在同名属性,会在table中生成2条同名column
-
floor切换drift方案:
-
table层
-
方法一:支持把现有数据库DDL拿过来使用
- 优点:简单,快速
- 缺点:如果使用自定义model,需要修改生成的代码
-
方式二:编写Table类
- 优点:数据结构相对方式一比较清晰;无需修改生成的代码
- 缺点:需要一定的人力成本编写代码
-
model层
可以考虑使用现有Model,drift支持该特性 Custom row classes (simonbinder.eu)
-
dao层
-
方式一:使用现有代码的SQL
- 优点:较为简单
- 缺点:还是SQL
-
方式二:根据现有代码转换成NoSQL
- 优点:NoSQL,从代码角度保证SQL不错误
- 缺点:人力成本
-
migration方面
-
方式一:使用现有代码的SQL
- 优点:快速
- 缺点:还是SQL
-
方式二:根据现有代码转换成NoSQL
- 优点:代码清晰明了
- 缺点:人力成本
转载自:https://juejin.cn/post/7247045913980665911