Flutter——数据库Drift开辟详细教程(三)

打印 上一主题 下一主题

主题 1826|帖子 1826|积分 5478

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
参考



  • https://drift.simonbinder.eu/dart_api/writes/#updating-with-sql-expressions
正文核心API

写入(更新、插入、删除)

1.更新和删除

   您可以利用生成的类来更新任何行的单个字段:
  1. Future moveImportantTasksIntoCategory(Category target) {
  2.   // for updates, we use the "companion" version of a generated class. This wraps the
  3.   // fields in a "Value" type which can be set to be absent using "Value.absent()". This
  4.   // allows us to separate between "SET category = NULL" (`category: Value(null)`) and not
  5.   // updating the category at all: `category: Value.absent()`.
  6.   return (update(todos)
  7.       ..where((t) => t.title.like('%Important%'))
  8.     ).write(TodosCompanion(
  9.       category: Value(target.id),
  10.     ),
  11.   );
  12. }
  13. Future updateTodo(Todo entry) {
  14.   // using replace will update all fields from the entry that are not marked as a primary key.
  15.   // it will also make sure that only the entry with the same primary key will be updated.
  16.   // Here, this means that the row that has the same id as entry will be updated to reflect
  17.   // the entry's title, content and category. As its where clause is set automatically, it
  18.   // cannot be used together with where.
  19.   return update(todos).replace(entry);
  20. }
  21. Future feelingLazy() {
  22.   // 删除id小于10的所有对象
  23.   return (delete(todos)..where((t) => t.id.isSmallerThanValue(10))).go();
  24. }
复制代码


  • 注意:假如您没有明确添加where更新或删除子句,则该语句将影响表中的所有行!
2.利用 SQL 表达式更新

   在某些情况下,您可能需要根据当前值更新多行。一种方案是先将受影响的行选择到 Dart 对象中,然后根据这些结果创建陪同对象并用于更新。假如更新可以用 SQL 描述,则可以利用更高效的方法Companion.custom:
  1. await db
  2.     .update(db.users)
  3.     .write(UsersCompanion.custom(username: db.users.username.lower()));
复制代码
这里,表name中users所有现有行的列均更改为小写。由于.lower()列的逐一更换功能已在数据库中实现,因此无需在语句执行过程中将行加载到 Dart 中。
3.插入件

   您可以非常轻松地将任何有效对象插入表中。由于某些值可能不存在(比方我们无需明确设置的默认值),我们再次利用配套版本。
  1. // returns the generated id
  2. Future<int> addTodo(TodosCompanion entry) {
  3.   return into(todos).insert(entry);
  4. }
复制代码
  生成的所有行类都会有一个可用于创建对象的构造函数:
  1. addTodo(
  2.   TodosCompanion(
  3.     title: Value('Important task'),
  4.     content: Value('Refactor persistence code'),
  5.   ),
  6. );
复制代码
假如某个列可空或具有默认值(包罗自增列),则可以省略该字段。所有其他字段必须已设置且非空。insert否则,该方法将抛出异常。
可以利用批处置惩罚高效地运行多个插入语句。为此,您可以利用insertAll中的方法batch:
  1. Future<void> insertMultipleEntries() async{
  2.   await batch((batch) {
  3.     // functions in a batch don't have to be awaited - just
  4.     // await the whole batch afterwards.
  5.     batch.insertAll(todos, [
  6.       TodosCompanion.insert(
  7.         title: 'First entry',
  8.         content: 'My content',
  9.       ),
  10.       TodosCompanion.insert(
  11.         title: 'Another entry',
  12.         content: 'More content',
  13.         // columns that aren't required for inserts are still wrapped in a Value:
  14.         category: Value(3),
  15.       ),
  16.       // ...
  17.     ]);
  18.   });
  19. }
复制代码
批处置惩罚与事务类似,所有更新操作都以原子方式举行,但批处置惩罚支持进一步优化,制止重复预备类似的 SQL 语句。这使得批处置惩罚非常得当批量插入或更新操作。
4.更新插入

Upserts 是较新版本的 sqlite3 中的一项功能,假如已经存在冲突的行,则它允许插入像更新一样运行。
当主键是其数据的一部分时,这允许我们创建或覆盖现有行:
  1. class Users extends Table {
  2.   TextColumn get email => text()();
  3.   TextColumn get name => text()();
  4.   @override
  5.   Set<Column> get primaryKey => {email};
  6. }
  7. Future<int> createOrUpdateUser(User user) {
  8.   return into(users).insertOnConflictUpdate(user);
  9. }
复制代码
当利用已存在的电子邮件地址举行呼叫时createOrUpdateUser(),该用户的姓名将被更新。否则,新的用户将被插入数据库。
插入操作也可以用于更高级的查询。比方,假设我们正在构建一个字典,并希望跟踪某个单词的出现次数。一个用于此目标的表可能如下所示
  1. class Words extends Table {
  2.   TextColumn get word => text()();
  3.   IntColumn get usages => integer().withDefault(const Constant(1))();
  4.   @override
  5.   Set<Column> get primaryKey => {word};
  6. }
复制代码
通过利用自定义的 upserts,我们可以插入一个新单词,大概usages 假如它已经存在则增加它的计数器:
  1. Future<void> trackWord(String word) {
  2.   return into(words).insert(
  3.     WordsCompanion.insert(word: word),
  4.     onConflict: DoUpdate(
  5.         (old) => WordsCompanion.custom(usages: old.usages + Constant(1))),
  6.   );
  7. }
复制代码
5.返回

您可以利用insertReturning插入一行或陪偕行,并立即获取插入的行。返回的行包含所有生成的默认值和递增 ID。
注意:此方法利用了RETURNINGsqlite3 3.35 版新增的语法,该语法在大多数操作系统上默认不可用。利用此方法时,请确保您拥有最新的 sqlite3 版本。以下情况也是如此sqlite3_flutter_libs。
比方,思量利用入门指南中的表格的以下代码片断:
  1. final row = await into(todos).insertReturning(TodosCompanion.insert(
  2.   title: 'A todo entry',
  3.   content: 'A description',
  4. ));
复制代码
返回row的 具有正确的id设置。假如表有其他默认值,包罗像 这样的动态值CURRENT_TIME,那么这些值也会在 所返回的行中设置insertReturning。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表