Flutter 开发系列(十):深入掌握本地存储与数据库操作

在 Flutter 中实现本地存储是构建应用的重要一环,尤其是在需要持久化用户数据、缓存信息、或应用设置的情况下。本篇将介绍如何在 Flutter 中使用 SQLite 和 shared_preferences 两种方式进行本地存储,涵盖适用场景、常用方法、以及具体代码示例,帮助开发者为应用数据选择合适的存储方案。
在这里插入图片描述


目录

  1. SQLite 与 shared_preferences 简介
  2. 使用 shared_preferences 进行简单数据存储
    • 存储用户偏好设置示例
  3. 使用 SQLite 实现复杂数据持久化
    • 表设计与数据库操作示例
  4. 扩展:选择合适的存储方案

1. SQLite 与 shared_preferences 简介

  • shared_preferences:用于存储轻量数据(如布尔值、字符串和整数),通常适用于用户设置和少量配置信息。
  • SQLite:适合复杂结构和较大数据量的持久化存储,支持增删改查和数据关系的管理。适合存储较多的用户数据,比如任务列表、笔记等。

2. 使用 shared_preferences 进行简单数据存储

shared_preferences 插件可以帮助在本地持久化简单数据,以下为基本的设置和使用流程:

安装 shared_preferences 插件

pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.15

存储和读取数据示例

在以下示例中,我们将存储和读取用户的登录状态和用户名。

import 'package:shared_preferences/shared_preferences.dart';

class PreferencesService {
  // 保存登录状态
  Future<void> saveLoginStatus(bool isLoggedIn) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isLoggedIn', isLoggedIn);
  }

  // 获取登录状态
  Future<bool> getLoginStatus() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool('isLoggedIn') ?? false;
  }

  // 保存用户名
  Future<void> saveUsername(String username) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('username', username);
  }

  // 获取用户名
  Future<String?> getUsername() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString('username');
  }
}

示例用法

在应用的登录页面中,可以调用 saveLoginStatus 方法来存储登录状态,登录时也可以获取并显示用户名:

final preferencesService = PreferencesService();

// 存储登录状态
await preferencesService.saveLoginStatus(true);

// 获取登录状态
bool isLoggedIn = await preferencesService.getLoginStatus();
print("用户登录状态: $isLoggedIn");

// 存储用户名
await preferencesService.saveUsername("flutter_user");

// 获取用户名
String? username = await preferencesService.getUsername();
print("用户名: $username");

3. 使用 SQLite 实现复杂数据持久化

对于需要保存大量数据和表结构的应用,SQLite 是更适合的方案。在 Flutter 中,sqflite 插件是 SQLite 的一个封装,能够轻松操作数据库。

安装 sqflite 插件

pubspec.yaml 文件中添加 sqflitepath 依赖:

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

创建数据库和表

假设我们需要一个简单的任务列表应用,其中包含每个任务的 ID、标题和完成状态。以下示例展示了如何创建和操作数据库。

创建 DatabaseHelper
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('tasks.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);

    return await openDatabase(path, version: 1, onCreate: _createDB);
  }

  Future _createDB(Database db, int version) async {
    const taskTable = '''
    CREATE TABLE tasks (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      title TEXT NOT NULL,
      isCompleted INTEGER NOT NULL
    )
    ''';
    await db.execute(taskTable);
  }
}
数据操作方法

DatabaseHelper 类添加用于增删改查的函数,例如创建任务、更新任务状态、获取任务列表等:

class DatabaseHelper {
  // 创建任务
  Future<void> createTask(String title) async {
    final db = await instance.database;
    await db.insert('tasks', {'title': title, 'isCompleted': 0});
  }

  // 获取任务列表
  Future<List<Map<String, dynamic>>> getTasks() async {
    final db = await instance.database;
    return await db.query('tasks');
  }

  // 更新任务完成状态
  Future<void> updateTask(int id, bool isCompleted) async {
    final db = await instance.database;
    await db.update(
      'tasks',
      {'isCompleted': isCompleted ? 1 : 0},
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  // 删除任务
  Future<void> deleteTask(int id) async {
    final db = await instance.database;
    await db.delete(
      'tasks',
      where: 'id = ?',
      whereArgs: [id],
    );
  }
}

示例用法

final dbHelper = DatabaseHelper.instance;

// 创建新任务
await dbHelper.createTask("学习 Flutter");

// 获取任务列表
List<Map<String, dynamic>> tasks = await dbHelper.getTasks();
print("任务列表: $tasks");

// 更新任务状态
await dbHelper.updateTask(1, true);

// 删除任务
await dbHelper.deleteTask(1);

4. 扩展:选择合适的存储方案

需求存储方式适用场景
简单数据存储shared_preferences适合存储用户偏好、登录状态等轻量数据
复杂数据持久化SQLite适合存储大量或结构复杂的数据,如任务列表、联系人等

总结

使用 shared_preferences 存储轻量数据或配置项,使用 sqflite 进行更复杂的数据管理,是 Flutter 中常见的本地存储策略。在实际应用中,可以根据数据的复杂度和持久化需求来选择合适的存储方案。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐