Flutter数据库管理插件drift的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter数据库管理插件drift的使用

Drift简介

Drift 是一个为Flutter和Dart构建的反应式持久化库,它建立在SQLite之上。Drift具有以下特点:

  • Flexible(灵活):Drift允许你在SQL和Dart中编写查询,提供两种语言的流利API。你可以过滤和排序结果或使用联接来对多个表进行查询。甚至可以使用复杂的SQL特性如WITHWINDOW子句。
  • Feature rich(功能丰富):内置支持事务、模式迁移、复杂过滤器和表达式、批量更新和联接。我们甚至有一个内置的SQL IDE!
  • Modular(模块化):通过内置对DAO和SQL文件中的import的支持,Drift帮助你保持数据库代码的简洁。
  • Safe(安全):Drift基于你的表和查询生成类型安全的代码。如果你在查询中犯了错误,Drift会在编译时发现并提供有帮助且描述性的提示。
  • Fast(快速):即使Drift让你编写强大的查询,它的性能也能与键值存储相媲美。Drift是唯一一个带有内置线程支持的主要持久化库,允许你在隔离区之间运行数据库代码而无需额外的努力。
  • Reactive(反应式):将任何SQL查询变成自动更新的流!这包括跨多个表的复杂查询。
  • Cross-Platform support(跨平台支持):Drift适用于Android、iOS、macOS、Windows、Linux和Web。这个模板是一个可以在所有平台上工作的Flutter待办事项应用程序。

要开始使用drift,请阅读我们详细的文档

示例代码

下面是一个完整的示例demo,展示了如何使用drift创建一个简单的待办事项应用:

// For more information on using drift, please see https://drift.simonbinder.eu/docs/getting-started/
// A full cross-platform example is available here: https://github.com/simolus3/drift/tree/develop/examples/app

import 'package:drift/drift.dart';
import 'package:drift/native.dart';

part 'main.g.dart';

@DataClassName('TodoCategory')
class TodoCategories extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get name => text()();
}

@TableIndex(name: 'item_title', columns: {#title})
class TodoItems extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get title => text()();
  TextColumn get content => text().nullable()();
  IntColumn get categoryId => integer().references(TodoCategories, #id)();

  TextColumn get generatedText => text().nullable().generatedAs(
      title + const Constant(' (') + content + const Constant(')'))();
}

abstract class TodoCategoryItemCount extends View {
  TodoItems get todoItems;
  TodoCategories get todoCategories;

  Expression<int> get itemCount => todoItems.id.count();

  @override
  Query as() => select([
        todoCategories.name,
        itemCount,
      ]).from(todoCategories).join([
        innerJoin(todoItems, todoItems.categoryId.equalsExp(todoCategories.id))
      ]);
}

@DriftView(name: 'customViewName')
abstract class TodoItemWithCategoryNameView extends View {
  TodoItems get todoItems;
  TodoCategories get todoCategories;

  Expression<String> get title =>
      todoItems.title +
      const Constant('(') +
      todoCategories.name +
      const Constant(')');

  @override
  Query as() => select([todoItems.id, title]).from(todoItems).join([
        innerJoin(
            todoCategories, todoCategories.id.equalsExp(todoItems.categoryId))
      ]);
}

@DriftDatabase(tables: [
  TodoItems,
  TodoCategories,
], views: [
  TodoCategoryItemCount,
  TodoItemWithCategoryNameView,
])
class Database extends _$Database {
  Database(super.e);

  @override
  int get schemaVersion => 2;

  @override
  MigrationStrategy get migration {
    return MigrationStrategy(
      onCreate: (m) async {
        await m.createAll();

        // Add a bunch of default items in a batch
        await batch((b) {
          b.insertAll(todoItems, [
            TodoItemsCompanion.insert(title: 'A first entry', categoryId: 0),
            TodoItemsCompanion.insert(
              title: 'Todo: Checkout drift',
              content: const Value('Drift is a persistence library for Dart '
                  'and Flutter applications.'),
              categoryId: 0,
            ),
          ]);
        });
      },
    );
  }

  // The TodoItem class has been generated by drift, based on the TodoItems
  // table description.
  //
  // In drift, queries can be watched by using .watch() in the end.
  // For more information on queries, see https://drift.simonbinder.eu/docs/getting-started/writing_queries/
  Stream<List<TodoItem>> get allItems => select(todoItems).watch();
}

Future<void> main() async {
  // Create an in-memory instance of the database with todo items.
  final db = Database(NativeDatabase.memory());

  db.allItems.listen((event) {
    print('Todo-item in database: $event');
  });

  // Add category
  final categoryId = await db
      .into(db.todoCategories)
      .insert(TodoCategoriesCompanion.insert(name: 'Category'));

  // Add another entry
  await db.into(db.todoItems).insert(TodoItemsCompanion.insert(
      title: 'Another entry added later', categoryId: categoryId));

  final query = db.select(db.todoItems).join([
    innerJoin(db.todoCategories,
        db.todoCategories.id.equalsExp(db.todoItems.categoryId))
  ]);

  for (final row in await query.get()) {
    print('has row');
    print(row.read(db.todoItems.categoryId));
    print(row.read(db.todoCategories.name));
  }
}

代码说明

  1. 定义数据表

    • TodoCategoriesTodoItems 分别定义了类别表和待办事项表。
    • TodoItems 表中的 categoryId 列引用了 TodoCategories 表的 id 列。
  2. 定义视图

    • TodoCategoryItemCount 视图用于统计每个类别的待办事项数量。
    • TodoItemWithCategoryNameView 视图用于获取待办事项及其所属类别的名称。
  3. 定义数据库类

    • Database 类继承自 _Database,并指定了两个表和两个视图。
    • schemaVersion 定义了数据库版本号。
    • migration 方法定义了数据库创建时的操作,例如创建表和插入初始数据。
  4. 主函数

    • 创建了一个内存中的数据库实例。
    • 监听所有待办事项的变化,并打印出来。
    • 插入一个新的类别和一个新的待办事项。
    • 查询并打印所有待办事项及其类别信息。

通过这个示例,你可以了解如何使用drift来管理和操作SQLite数据库。更多详细信息请参考官方文档


更多关于Flutter数据库管理插件drift的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库管理插件drift的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用 Drift(以前称为 Floor)数据库管理插件的一个简要指南和代码示例。Drift 是一个强大的、基于 SQLite 的持久化库,为 Flutter 和 Dart 提供类型安全的 ORM(对象关系映射)。

1. 添加 Drift 依赖

首先,在你的 pubspec.yaml 文件中添加 Drift 的依赖:

dependencies:
  flutter:
    sdk: flutter
  drift: ^x.y.z  # 请使用最新版本号

然后运行 flutter pub get 来获取依赖。

2. 创建数据库 Schema

接下来,定义一个 Dart 数据类来表示你想要存储的数据模型,并创建一个 Drift 的数据访问对象(DAO)。

import 'package:drift/drift.dart';

part 'user_database.g.dart';

@DriftDatabase(
  tables: [Users],
  daos: [UserDao]
)
abstract class UserDatabase extends Database {
  UserDatabase() : super(
    _openConnection(), // 这里你需要定义如何打开数据库连接
  );

  // 定义数据库连接
  static Connection _openConnection() {
    // 在实际应用中,你可能需要更复杂的配置
    return NativeDatabaseConnection('path_to_your_database.db', loggingEnabled: true);
  }

  // 用户表定义
  @TypeConverters([/* 你的类型转换器,如果有的话 */])
  class Users extends Table {
    IntColumn get id => integer().primaryKey().autoIncrement()();
    TextColumn get name => text().notNull()();
  }
}

// 用户 DAO
@Dao(tables: [UserDatabase.Users])
abstract class UserDao {
  @Query('SELECT * FROM Users')
  Future<List<UserDatabase.Users>> getAllUsers();

  @Insert
  Future<void> insertUser(UserDatabase.Users user);

  @Update
  Future<void> updateUser(UserDatabase.Users user);

  @Delete
  Future<void> deleteUser(UserDatabase.Users user);
}

3. 生成 Drift 代码

在项目的根目录下运行以下命令以生成 Drift 的代码:

flutter pub run build_runner build

这将会生成 user_database.g.dart 文件,其中包含实现你定义的抽象类和表的代码。

4. 使用 Drift 数据库

现在你可以在你的 Flutter 应用中使用 Drift 数据库了。以下是一个简单的示例,展示如何插入和查询用户数据。

import 'package:flutter/material.dart';
import 'user_database.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Drift Example'),
        ),
        body: FutureBuilder<void>(
          future: useDatabase(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('Error: ${snapshot.error}'));
            } else {
              return Center(child: Text('Database operations completed!'));
            }
          },
        ),
      ),
    );
  }

  Future<void> useDatabase() async {
    final db = UserDatabase(_openConnection());
    final dao = db.userDao;

    // 插入新用户
    final newUser = db.users.create()..name = 'John Doe';
    await dao.insertUser(newUser);

    // 查询所有用户
    final users = await dao.getAllUsers();
    print('Users in database: ${users.map((user) => user.name).join(', ')}');

    // 关闭数据库连接
    await db.close();
  }

  // 这里你需要复制 _openConnection 方法到你的 main.dart 文件或者创建一个全局的数据库连接管理
  static Connection _openConnection() {
    return NativeDatabaseConnection('path_to_your_database.db', loggingEnabled: true);
  }
}

注意事项

  1. 路径管理:确保数据库文件路径正确,并且在不同的平台上可能需要不同的路径处理方式。
  2. 错误处理:在生产代码中,添加适当的错误处理和日志记录。
  3. 线程安全:确保数据库操作在正确的线程或异步环境中执行。

以上就是在 Flutter 中使用 Drift 数据库管理插件的基本步骤和代码示例。希望这对你有所帮助!

回到顶部