Flutter 中 数据库框架

302 阅读2分钟

Flutter 中常用的数据库框架主要包括以下几种:

  1. SQFlite
  2. Moor (Drift)
  3. Hive
  4. ObjectBox

下面将详细介绍这几种数据库框架,并提供示例代码。

1. SQFlite

SQFlite 是 Flutter 中最常用的 SQLite 数据库插件。它提供了对 SQLite 数据库的完整支持,包括执行 SQL 查询、插入、更新和删除操作。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  sqflite: ^2.0.0+4
  path: ^1.8.0

示例代码

import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final database = openDatabase(
    join(await getDatabasesPath(), 'example.db'),
    onCreate: (db, version) {
      return db.execute(
        'CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',
      );
    },
    version: 1,
  );

  Future<void> insertDog(Dog dog) async {
    final db = await database;
    await db.insert(
      'dogs',
      dog.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future<List<Dog>> dogs() async {
    final db = await database;
    final List<Map<String, dynamic>> maps = await db.query('dogs');
    return List.generate(maps.length, (i) {
      return Dog(
        id: maps[i]['id'],
        name: maps[i]['name'],
        age: maps[i]['age'],
      );
    });
  }

  runApp(MyApp());
}

class Dog {
  final int id;
  final String name;
  final int age;

  Dog({required this.id, required this.name, required this.age});

  Map<String, dynamic> toMap() {
    return {'id': id, 'name': name, 'age': age};
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('SQFlite Example')),
        body: Center(child: Text('SQFlite Example')),
      ),
    );
  }
}

2. Moor (Drift)

Moor (Drift) 是一个更高级的 SQLite 包装库,提供了 Dart 原生支持,类型安全,并且使用简单。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  drift: ^2.0.0
  drift_sqflite: ^2.0.0
  path_provider: ^2.0.7
  path: ^1.8.0

dev_dependencies:
  drift_dev: ^2.0.0
  build_runner: ^2.0.6

示例代码

import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'dart:io';

part 'main.g.dart';

LazyDatabase _openConnection() {
  return LazyDatabase(() async {
    final dbFolder = await getApplicationDocumentsDirectory();
    final file = File(p.join(dbFolder.path, 'db.sqlite'));
    return NativeDatabase(file);
  });
}

@DriftDatabase(tables: [Todos])
class MyDatabase extends _$MyDatabase {
  MyDatabase() : super(_openConnection());

  @override
  int get schemaVersion => 1;

  Future<List<Todo>> getAllTodos() => select(todos).get();
  Future insertTodo<Todo>(Insertable<Todo> todo) => into(todos).insert(todo);
}

class Todos extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get title => text().withLength(min: 1, max: 50)();
  BoolColumn get completed => boolean().withDefault(Constant(false))();
}

void main() {
  final db = MyDatabase();
  runApp(MyApp(db: db));
}

class MyApp extends StatelessWidget {
  final MyDatabase db;

  MyApp({required this.db});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Drift Example')),
        body: FutureBuilder<List<Todo>>(
          future: db.getAllTodos(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              final todos = snapshot.data ?? [];
              return ListView.builder(
                itemCount: todos.length,
                itemBuilder: (context, index) {
                  final todo = todos[index];
                  return ListTile(
                    title: Text(todo.title),
                    trailing: Checkbox(
                      value: todo.completed,
                      onChanged: (newValue) {},
                    ),
                  );
                },
              );
            }
          },
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            db.insertTodo(TodosCompanion(
              title: Value('New Todo'),
              completed: Value(false),
            ));
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

3. Hive

Hive 是一个轻量级和快速的键值对数据库,特别适用于需要存储大量数据的应用。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  hive: ^2.0.0
  hive_flutter: ^1.1.0

示例代码

import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';

void main() async {
  await Hive.initFlutter();
  await Hive.openBox('myBox');
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Hive Example')),
        body: Center(
          child: ValueListenableBuilder(
            valueListenable: Hive.box('myBox').listenable(),
            builder: (context, Box box, widget) {
              return Text('Stored Value: ${box.get('key')}');
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            var box = Hive.box('myBox');
            box.put('key', 'Hello Hive');
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

4. ObjectBox

ObjectBox 是一个高性能的嵌入式数据库,支持 NoSQL 数据模型,非常适合移动设备。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  objectbox: ^2.0.0
  objectbox_flutter_libs: ^1.1.0

示例代码

import 'package:flutter/material.dart';
import 'package:objectbox/objectbox.dart';
import 'objectbox.g.dart';  // 需要使用 `objectbox` 生成

@Entity()
class Note {
  int id;
  String text;

  Note({
    this.id = 0,
    required this.text,
  });
}

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

class MyApp extends StatelessWidget {
  late final Store _store;
  late final Box<Note> _noteBox;

  MyApp() {
    _store = Store(getObjectBoxModel());
    _noteBox = _store.box<Note>();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ObjectBox Example')),
        body: FutureBuilder<List<Note>>(
          future: Future.value(_noteBox.getAll()),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              final notes = snapshot.data ?? [];
              return ListView.builder(
                itemCount: notes.length,
                itemBuilder: (context, index) {
                  final note = notes[index];
                  return ListTile(
                    title: Text(note.text),
                  );
                },
              );
            }
          },
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            final note = Note(
              text: 'New Note',
            );
            _noteBox.put(note);
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

这些示例代码展示了如何在 Flutter 中使用各种数据库框架进行数据存储和管理。每个框架都有其优点,选择合适的框架可以根据具体项目的需求来决定。