[英]Flutter Sqflite multiple table models
我已经阅读了许多关于如何在 Flutter 中实现 Sqflite 的教程和示例。 其他所有示例都是仅使用一个模型或数据库表完成的。 如这些教程中所定义:
https://pub.dartlang.org/packages/sqflite
https://www.developerlibs.com/2018/07/flutter-sqlite-database-example.html
http://camposha.info/flutter/sqflite-insert-select-show
据我所知,我们需要创建与表一样多的模型和助手。 对于每个数据库表,将有一个 model.dart 文件和一个 helper.dart 文件。
我的问题是,有什么办法可以让所有模型都只有一个助手吗?
更新
在 helper.dart 文件中有一个未来的“插入”。 我怎样才能对所有模型使用相同的插入未来?
Future<Todo> insert(Todo todo) async {
todo.id = await db.insert(tableTodo, todo.toMap());
return todo;
}
我提出了一些相反的意见,但我只记得在我的上一个项目中我做了类似的事情,它是针对Firebase Database的,但它与sqflite非常相似。
我创建了一个带有key
的BaseItem
抽象类,所有模型都将派生自该类。
我还创建了一个BaseProvider
抽象类,它需要一个 BaseItem 并将定义访问模型的简单方法。
upsert
和delete
方法位于FirebaseBaseProvider
中,它扩展BaseProvider
。
我将在此处粘贴部分内容(删除了很多内容以使其更易于理解):
abstract class BaseItem {
const BaseItem({this.key});
final String key;
}
abstract class BaseProvider<T extends BaseItem> {
Future<List<T>> find();
Future<BaseKey> upsert(T item);
Future<int> delete(T item);
}
abstract class FirebaseBaseProvider<T extends BaseItem> {
// Abstract methods which need to be implemented
T fromMap(BaseKey key, dynamic map);
Map<String, dynamic> toJson(BaseKey key, T item);
Future<DatabaseReference> getReference(BaseKey base) async { ... }
BaseKey compileKey(T item, {String useKey}) { ... }
Future<List<T>> find() async {
List<T> result = new List();
// my implementation doesnt work like this,
// as it's firebase based, but this would
// be the place in a Sqflite implementation to use
// fromMap and load the items
return result;
}
Future<BaseKey> upsert(T item) async {
if (item == null) return null;
BaseKey key = compileKey(item);
(await getReference(key)).set(toJson(key, item));
return key;
}
Future<int> delete(T item) async {
if (item == null) return null;
if (item.key != null && item.key != "") {
(await getReference(compileKey(item))).remove();
}
return 0;
}
}
然后,为了实现News
模型或任何其他模型,我将通过简单地定义其内容来创建它,如下所示:
class News extends BaseItem {
News({String key, this.creation, this.messageSubject, this.messageBody}) : super(key: key);
final DateTime creation;
final String messageSubject;
final String messageBody;
bool operator ==(o) => o is News && (o.key == key);
int get hashCode => key.hashCode;
}
它将需要其特定的提供者,该提供者将仅实现toJson
和fromMap
方法,如下所示:
class NewsProvider extends FirebaseBaseProvider<News> {
@override
Map<String, dynamic> toJson(BaseKey key, News news) {
return {
"creation": news.creation,
"messageSubject": news.messageSubject,
"messageBody": news.messageBody,
};
}
@override
News fromMap(BaseKey key, dynamic map) {
DateTime creation = map["creation"] == null ? null : DateTime.tryParse(map["creation"] as String);
return new News(
key: key.child.key,
creation: creation,
messageSubject: map["messageSubject"] as String,
messageBody: map["messageBody"] as String,
);
}
}
最后, NewProvider
提供了find
、 upsert
和delete
方法,但它们的实现依赖于抽象类,如您所愿,所有模型只需实现它们的一个。
当然,我的实现比这复杂得多,因为 Firebase 需要不同的方法来获取/加载项目,而且find
方法最终必须在每个特定于模型的提供程序中有所不同。 但是,还有很多可以简化。
我在评论中所说的是,最后一个类,具有toJson
和fromMap
特定实现的特定NewsProvider
也可以通过在News
模型类中使用注释来概括,但这带来了很多问题和晦涩 -在我的意见,当然- 这是不值得的。
我有一个关于创建表的类似问题,所有示例都只创建一个表。 我发现这个网页创建了两个表,每个命令都有一个等待。
像这样:
Future _onCreate(Database db, int version) async {
await db.execute("CREATE TABLE table1 (id INTEGER, valuex TEXT)");
await db.execute("CREATE TABLE table2 (id INTEGER, valuey TEXT)");
await db.execute("CREATE TABLE table3 (id INTEGER, valuez TEXT)");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.