Flutter开发实战之数据持久化方案

第9章:数据持久化方案

9.1 数据持久化概述

在移动应用开发中,数据持久化就像是给应用装上了"记忆"。想象一下,如果每次打开微信都要重新登录,所有聊天记录都消失了,这样的应用还有什么价值呢?数据持久化让我们的应用能够"记住"用户的设置、保存重要数据,即使应用关闭重启,这些信息依然存在。

Flutter提供了多种数据持久化方案,每种方案都有其适用场景:

  • SharedPreferences:适合存储简单的配置信息,如用户偏好设置
  • 文件存储:适合存储文档、图片等文件数据
  • SQLite:适合存储结构化的关系型数据
  • Hive:轻量级、高性能的NoSQL数据库
  • ObjectBox:面向对象的高性能数据库

让我们深入了解每种方案的特点和使用方法。

9.2 SharedPreferences:轻量级存储的首选

9.2.1 什么是SharedPreferences

SharedPreferences就像是应用的"便签本",专门用来记录一些简单的配置信息。比如用户是否第一次打开应用、主题颜色偏好、语言设置等。它的特点是使用简单、读写快速,但只能存储基本数据类型。

9.2.2 基础使用

首先在pubspec.yaml中添加依赖:

dependencies:
  shared_preferences: ^2.2.2

让我们通过一个实际例子来学习:

import 'package:shared_preferences/shared_preferences.dart';

class UserPreferences {
   
   
  static SharedPreferences? _preferences;
  
  // 初始化
  static Future<void> init() async {
   
   
    _preferences = await SharedPreferences.getInstance();
  }
  
  // 保存用户名
  static Future<void> setUsername(String username) async {
   
   
    await _preferences?.setString('username', username);
  }
  
  // 获取用户名
  static String getUsername() {
   
   
    return _preferences?.getString('username') ?? '';
  }
  
  // 保存是否首次启动
  static Future<void> setFirstLaunch(bool isFirst) async {
   
   
    await _preferences?.setBool('first_launch', isFirst);
  }
  
  // 检查是否首次启动
  static bool isFirstLaunch() {
   
   
    return _preferences?.getBool('first_launch') ?? true;
  }
  
  // 保存主题模式
  static Future<void> setThemeMode(int mode) async {
   
   
    await _preferences?.setInt('theme_mode', mode);
  }
  
  // 获取主题模式
  static int getThemeMode() {
   
   
    return _preferences?.getInt('theme_mode') ?? 0;
  }
}

9.2.3 实战案例:用户设置管理

让我们创建一个完整的用户设置管理系统:

class SettingsScreen extends StatefulWidget {
   
   
  
  _SettingsScreenState createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
   
   
  bool _notificationsEnabled = true;
  bool _darkModeEnabled = false;
  String _language = 'zh-CN';
  
  
  void initState() {
   
   
    super.initState();
    _loadSettings();
  }
  
  // 加载设置
  void _loadSettings() async {
   
   
    final prefs = await SharedPreferences.getInstance();
    setState(() {
   
   
      _notificationsEnabled = prefs.getBool('notifications') ?? true;
      _darkModeEnabled = prefs.getBool('dark_mode') ?? false;
      _language = prefs.getString('language') ?? 'zh-CN';
    });
  }
  
  // 保存设置
  void _saveSetting(String key, dynamic value) async {
   
   
    final prefs = await SharedPreferences.getInstance();
    if (value is bool) {
   
   
      await prefs.setBool(key, value);
    } else if (value is String) {
   
   
      await prefs.setString(key, value);
    }
  }
  
  
  Widget build(BuildContext context) {
   
   
    return Scaffold(
      appBar: AppBar(title: Text('设置')),
      body: ListView(
        children: [
          SwitchListTile(
            title: Text('推送通知'),
            subtitle: Text('接收应用通知'),
            value: _notificationsEnabled,
            onChanged: (value) {
   
   
              setState(() {
   
   
                _notificationsEnabled = value;
              });
              _saveSetting('notifications', value);
            },
          ),
          SwitchListTile(
            title: Text('深色模式'),
            subtitle: Text('使用深色主题'),
            value: _darkModeEnabled,
            onChanged: (value) {
   
   
              setState(() {
   
   
                _darkModeEnabled = value;
              });
              _saveSetting('dark_mode', value);
            },
          ),
          ListTile(
            title: Text('语言设置'),
            subtitle: Text(_language == 'zh-CN' ? '简体中文' : 'English'),
            trailing: Icon(Icons.arrow_forward_ios),
            onTap: () {
   
   
              // 显示语言选择对话框
              _showLanguageDialog();
            },
          ),
        ],
      ),
    );
  }
  
  void _showLanguageDialog() {
   
   
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('选择语言'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            RadioListTile<String>(
              title: Text('简体中文'),
              value: 'zh-CN',
              groupValue: _language,
              onChanged: (value) {
   
   
                setState(() {
   
   
                  _language = value!;
                });
                _saveSetting('language', value!);
                Navigator.pop(context);
              },
            ),
            RadioListTile<String>(
              title: Text('English'),
              value: 'en-US',
              groupValue: _language,
              onChanged: (value) {
   
   
                setState(() {
   
   
                  _language = value!;
                });
                _saveSetting('language', value!);
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

9.3 文件系统:处理复杂数据的利器

9.3.1 文件存储的应用场景

文件存储适合保存以下类型的数据:

  • 用户生成的文档(如笔记、草稿)
  • 下载的图片、音频、视频文件
  • 导出的数据文件(CSV、JSON等)
  • 缓存数据

9.3.2 获取存储路径

Flutter通过path_provider插件提供了多个存储目录:

dependencies:
  path_provider: ^2.1.1
import 'package:path_provider/path_provider.dart';
import 'dart:io';

class FileStorageHelper {
   
   
  // 获取应用文档目录(私有,用户不可见)
  static Future<String> getDocumentsPath() async {
   
   
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }
  
  // 获取临时目录(系统可能清理)
  static Future<String> getTempPath() async {
   
   
    final directory = await getTemporaryDirectory();
    return directory.path;
  }
  
  // 获取外部存储目录(Android,用户可见)
  static Future<String?> getExternalStoragePath() async {
   
   
    final directory = await getExternalStorageDirectory();
    return directory?.path;
  }
  
  // 获取应用支持目录(存放应用数据)
  static Future<String> getSupportPath() async {
   
   
    final directory = await getApplicationSupportDirectory();
    return directory.path;
  }
}

9.3.3 文件读写操作

让我们创建一个通用的文件管理类:

class FileManager {
   
   
  // 写入文本文件
  static Future<bool> writeTextFile(String fileName, String content) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      await file.writeAsString(content);
      return true;
    } catch (e) {
   
   
      print('写入文件失败: $e');
      return false;
    }
  }
  
  // 读取文本文件
  static Future<String?> readTextFile(String fileName) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      if (await file.exists()) {
   
   
        return await file.readAsString();
      }
      return null;
    } catch (e) {
   
   
      print('读取文件失败: $e');
      return null;
    }
  }
  
  // 写入二进制文件
  static Future<bool> writeBinaryFile(String fileName, List<int> bytes) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      await file.writeAsBytes(bytes);
      return true;
    } catch (e) {
   
   
      print('写入二进制文件失败: $e');
      return false;
    }
  }
  
  // 删除文件
  static Future<bool> deleteFile(String fileName) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      if (await file.exists()) {
   
   
        await file.delete();
        return true;
      }
      return false;
    } catch (e) {
   
   
      print('删除文件失败: $e');
      return false;
    }
  }
  
  // 检查文件是否存在
  static Future<bool> fileExists(String fileName) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      return await file.exists();
    } catch (e) {
   
   
      return false;
    }
  }
  
  // 获取文件大小
  static Future<int> getFileSize(String fileName) async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final file = File('$path/$fileName');
      if (await file.exists()) {
   
   
        return await file.length();
      }
      return 0;
    } catch (e) {
   
   
      return 0;
    }
  }
  
  // 列出目录中的所有文件
  static Future<List<String>> listFiles() async {
   
   
    try {
   
   
      final path = await FileStorageHelper.getDocumentsPath();
      final directory = Directory(path);
      final files = await directory.list().toList();
      return files
          .where((entity) => entity is File)
          .map((file) => file.path.split('/').last)
          .toList();
    } catch (e) {
   
   
      print('列出文件失败: $e');
      return [];
    }
  }
}

9.3.4 实战案例:笔记本应用

让我们创建一个简单的笔记本应用:

class Note {
   
   
  final String id;
  final String title;
  final String content;
  final DateTime createdAt;
  final DateTime updatedAt;
  
  Note({
   
   
    required this.id,
    required this.title,
    required this.content,
    required this.createdAt,
    required this.updatedAt,
  });
  
  Map<String, dynamic> toJson() {
   
   
    return {
   
   
      'id': id,
      'title': title,
      'content': content,
      'createdAt': createdAt.toIso8601String(),
      'updatedAt': updatedAt.toIso8601String(),
    };
  }
  
  factory Note.fromJson(Map<String, dynamic> json) {
   
   
    return Note(
      id: json['id'],
      title: json['title'],
      content: json['content'],
      createdAt: DateTime.parse(json['createdAt']),
      updatedAt: DateTime.parse(json['updatedAt']),
    );
  }
}

class NotesManager {
   
   
  static const String _notesFileName = 'notes.json';
  
  // 保存所有笔记
  static Future<bool> saveNotes(List<Note> notes) async {
   
   
    try {
   
   
      final jsonList = notes.map((note) => note.toJson()).toList();
      final jsonString = jsonEncode(jsonList);
      return await FileManager.writeTextFile(_notesFileName, jsonString);
    } catch (e) {
   
   
      print('保存笔记失败: $e');
      return false;
    }
  }
  
  // 加载所有笔记
  static Future<List<Note>> loadNotes() async {
   
   
    try {
   
   
      final jsonString = await FileManager.readTextFile(_notesFileName);
      if (jsonString != null) {
   
   
        final List<dynamic> jsonList = jsonDecode(jsonString);
        return jsonList.map((json) => Note.fromJson(json)).toList();
      }
      return [];
    } catch (e) {
   
   
      print('加载笔记失败: $e');
      return [];
    }
  }
  
  // 添加笔记
  static Future<bool> addNote(Note note) async {
   
   
    final notes = await loadNotes();
    notes.add(note);
    return await saveNotes(notes);
  }
  
  // 更新笔记
  static Future<bool> updateNote(Note updatedNote) async {
   
   
    final notes = await loadNotes();
    final index = notes.indexWhere((note) => note.id == updatedNote.id);
    if (index != -1) {
   
   
      notes[index] = updatedNote;
      return await saveNotes(notes);
    }
    return false;
  }
  
  // 删除笔记
  static Future<bool> deleteNote(String noteId) async {
   
   
    final notes = await loadNotes();
    notes.removeWhere((note) => note.id == noteId);
    return await saveNotes(notes);
  }
}

9.4 SQLite:结构化数据的专业选择

9.4.1 SQLite简介

SQLite是一个轻量级的关系型数据库,特别适合移动应用。它支持SQL查询、事务处理、索引等高级功能,是处理复杂关系数据的首选方案。

9.4.2 集成SQLite

首先添加依赖:

dependencies:
  sqflite: ^2.3.0

9.4.3 数据库设计与创建

让我们创建一个任务管理应用的数据库:

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

class DatabaseHelper {
   
   
  static Database? _database;
  static const String _databaseName = 'task_manager.db';
  static const int _databaseVersion = 1;
  
  // 单例模式
  static DatabaseHelper? _instance;
  DatabaseHelper._();
  static DatabaseHelper get instance {
   
   
    _instance ??= DatabaseHelper._();
    return _instance!;
  }
  
  // 获取数据库实例
  Future<Database> get database async {
   
   
    _database ??= await _initDatabase();
    return _database!;
  }
  
  // 初始化数据库
  Future<Database> _initDatabase() async {
   
   
    String path = join(await getDatabasesPath(), _databaseName);
    return await openDatabase(
      path,
      version: _databaseVersion,
      onCreate: _onCreate,
      onUpgrade: _onUpgrade,
    );
  }
  
  // 创建表
  Future<void> _onCreate(Database db, int version) async {
   
   
    // 用户表
    await db.execute('''
      CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT NOT NULL UNIQUE,
        email TEXT NOT NULL,
        created_at TEXT NOT NULL
      )
    ''');
    
    // 分类表
    await db.execute('''
      CREATE TABLE categories (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        color INTEGER NOT NULL,
        created_at TEXT NOT NULL
      )
    ''');
    
    // 任务表
    await db.execute('''
      CREATE TABLE tasks (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        description TEXT,
        category_id INTEGER,
        priority INTEGER NOT NULL DEFAULT 1,
        is_completed INTEGER NOT NULL DEFAULT 0,
        due_date TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (category_id) REFERENCES categories (id)
      )
    ''');
    
    // 创建索引
    await db.execute('''
      CREATE INDEX idx_tasks_category ON tasks(category_id)
    ''');
    
    await db.execute('''
      CREATE INDEX idx_tasks_completed ON tasks(is_completed)
    ''');
  }
  
  // 数据库升级
  Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
   
   
    if (oldVersion < 2) {
   
   
      // 假设版本2添加了新字段
      await db.execute('''
        ALTER TABLE tasks ADD COLUMN reminder_time TEXT
      ''');
    }
  }
}

9.4.4 数据模型定义

定义数据模型类:

class Task {
   
   
  final int? id;
  final String title;
  final String? description;
  final int? categoryId;
  final int priority;
  final bool isCompleted;
  final DateTime? dueDate;
  final DateTime createdAt;
  final DateTime updatedAt;
  
  Task({
   
   
    this.id,
    required this.title,
    this.description,
    this.categoryId,
    this.priority = 1,
    this.isCompleted = false,
    this.dueDate,
    required this.createdAt,
    required this.updatedAt,
  });
  
  Map<String, dynamic> toMap() {
   
   
    return {
   
   
      'id': id,
      'title': title,
      'description': description,
      'category_id': categoryId,
      'priority': priority,
      'is_completed': isCompleted ? 1 : 0,
      'due_date': dueDate?.toIso8601String(),
      'created_at': createdAt.toIso8601String(),
      'updated_at': updatedAt.toIso8601String(),
    };
  }
  
  factory Task.fromMap(Map<String, dynamic> map) {
   
   
    return Task(
      id: map['id'],
      title: map['title'],
      description: map['description'],
      categoryId: map['category_id'],
      priority: map['priority'],
      isCompleted: map['is_completed'] == 1,
      dueDate: map['due_date'] != null ? DateTime.parse(map['due_date']) : null,
      createdAt: DateTime.parse(map['created_at']),
      updatedAt: DateTime.parse(map['updated_at']),
    );
  }
  
  Task copyWith({
   
   
    int? id,
    String? title,
    String? description,
    int? categoryId,
    int? priority,
    bool? isCompleted,
    DateTime? dueDate,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
   
   
    return Task(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      categoryId: categoryId ?? this.categoryId,
      priority: priority ?? this.priority,
      isCompleted: isCompleted ?? this.isCompleted,
      dueDate: dueDate ?? this.dueDate,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }
}

class Category {
   
   
  final int? id;
  final String name;
  final int color;
  final DateTime createdAt;
  
  Category({
   
   
    this.id,
    required this.name,
    required this.color,
    required this.createdAt,
  });
  
  Map<String, dynamic> toMap() {
   
   
    return {
   
   
      'id': id,
      'name': name,
      'color': color,
      'created_at': createdAt.toIso8601String(),
    };
  }
  
  factory Category.fromMap(Map<String, dynamic> map) {
   
   
    return Category(
      id: map['id'],
      name: map['name'],
      color: map['color'],
      createdAt: DateTime.parse(map['created_at']),
    );
  }
}

9.4.5 数据访问层(DAO)

创建数据访问对象来处理数据库操作:

class TaskDao {
   
   
  static Future<Database> get _db async => await DatabaseHelper.instance.database;
  
  // 插入任务
  static Future<int> insertTask(Task task) async {
   
   
    final db = await _db;
    return await db.insert('tasks', task.toMap());
  }
  
  // 获取所有任务
  static Future<List<Task>> getAllTasks() async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'tasks',
      orderBy: 'created_at DESC',
    );
    return List.generate(maps.length, (i) => Task.fromMap(maps[i]));
  }
  
  // 根据ID获取任务
  static Future<Task?> getTaskById(int id) async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'tasks',
      where: 'id = ?',
      whereArgs: [id],
    );
    if (maps.isNotEmpty) {
   
   
      return Task.fromMap(maps.first);
    }
    return null;
  }
  
  // 根据分类获取任务
  static Future<List<Task>> getTasksByCategory(int categoryId) async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'tasks',
      where: 'category_id = ?',
      whereArgs: [categoryId],
      orderBy: 'created_at DESC',
    );
    return List.generate(maps.length, (i) => Task.fromMap(maps[i]));
  }
  
  // 获取未完成的任务
  static Future<List<Task>> getIncompleteTasks() async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'tasks',
      where: 'is_completed = ?',
      whereArgs: [0],
      orderBy: 'due_date ASC',
    );
    return List.generate(maps.length, (i) => Task.fromMap(maps[i]));
  }
  
  // 更新任务
  static Future<int> updateTask(Task task) async {
   
   
    final db = await _db;
    return await db.update(
      'tasks',
      task.toMap(),
      where: 'id = ?',
      whereArgs: [task.id],
    );
  }
  
  // 标记任务为完成
  static Future<int> markTaskCompleted(int id) async {
   
   
    final db = await _db;
    return await db.update(
      'tasks',
      {
   
   
        'is_completed': 1,
        'updated_at': DateTime.now().toIso8601String(),
      },
      where: 'id = ?',
      whereArgs: [id],
    );
  }
  
  // 删除任务
  static Future<int> deleteTask(int id) async {
   
   
    final db = await _db;
    return await db.delete(
      'tasks',
      where: 'id = ?',
      whereArgs: [id],
    );
  }
  
  // 搜索任务
  static Future<List<Task>> searchTasks(String keyword) async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'tasks',
      where: 'title LIKE ? OR description LIKE ?',
      whereArgs: ['%$keyword%', '%$keyword%'],
      orderBy: 'created_at DESC',
    );
    return List.generate(maps.length, (i) => Task.fromMap(maps[i]));
  }
  
  // 获取任务统计信息
  static Future<Map<String, int>> getTaskStats() async {
   
   
    final db = await _db;
    
    final totalResult = await db.rawQuery('SELECT COUNT(*) as count FROM tasks');
    final completedResult = await db.rawQuery('SELECT COUNT(*) as count FROM tasks WHERE is_completed = 1');
    final pendingResult = await db.rawQuery('SELECT COUNT(*) as count FROM tasks WHERE is_completed = 0');
    
    return {
   
   
      'total': totalResult.first['count'] as int,
      'completed': completedResult.first['count'] as int,
      'pending': pendingResult.first['count'] as int,
    };
  }
}

class CategoryDao {
   
   
  static Future<Database> get _db async => await DatabaseHelper.instance.database;
  
  // 插入分类
  static Future<int> insertCategory(Category category) async {
   
   
    final db = await _db;
    return await db.insert('categories', category.toMap());
  }
  
  // 获取所有分类
  static Future<List<Category>> getAllCategories() async {
   
   
    final db = await _db;
    final List<Map<String, dynamic>> maps = await db.query(
      'categories',
      orderBy: 'name ASC',
    );
    return List.generate(maps.length, (i) => Category.fromMap(maps[i]));
  }
  
  // 更新分类
  static Future<int> updateCategory(Category category) async {
   
   
    final db = await _db;
    return await db.update(
      'categories',
      category.toMap(),
      where: 'id = ?',
      whereArgs: [category.id],
    );
  }
  
  // 删除分类
  static Future<int> deleteCategory(int id) async {
   
   
    final db = await _db;
    // 首先检查是否有任务使用这个分类
    final taskCount = await db.rawQuery(
      'SELECT COUNT(*) as count FROM tasks WHERE category_id = ?',
      [id],
    );
    
    if ((taskCount.first['count'] as int) > 0) {
   
   
      throw Exception('无法删除分类:还有任务正在使用此分类');
    }
    
    return await db.delete(
      'categories',
      where: 'id = ?',
      whereArgs: [id],
    );
  }
}

9.5 Hive:高性能NoSQL数据库

9.5.1 Hive的优势

Hive是一个专为Flutter设计的轻量级、超快速的键值数据库。它的主要优势包括:

  • 性能优异:比SQLite快很多倍
  • 使用简单:不需要SQL语句
  • 类型安全:支持Dart的强类型
  • 跨平台:支持所有Flutter平台
  • 加密支持:内置数据加密功能

9.5.2 集成Hive

添加依赖:

dependencies:
  hive: ^2.2.3
  hive_flutter: ^1.1.0

dev_dependencies:
  hive_generator: ^2.0.1
  build_runner: ^2.4.7

9.5.3 数据模型定义

使用Hive的TypeAdapter来定义数据模型:

import 'package:hive/hive.dart';

part 'user_model.g.dart'; // 生成的代码文件

(typeId: 0)
class User extends HiveObject {
   
   
  (0)
  late String id;
  
  (1)
  late String name;
  
  (2)
  late String email;
  
  (3)
  late DateTime createdAt;
  
  (4)
  String? avatarUrl;
  
  (5)
  late bool isActive;
  
  User({
   
   
    required this.id,
    required this.name,
    required this.email,
    required this.createdAt,
    this.avatarUrl,
    this.isActive = true,
  });
  
  
  String toString() {
   
   
    return 'User{id: $id, name: $name, email: $email}';
  }
}

(typeId: 1)
class Product extends HiveObject {
   
   
  (0)
  late String id;
  
  (1)
  late String name;
  
  (2)
  late String description;
  
  (3)
  late double price;
  
  (4)
  late int stock;
  
  (5)
  late List<String> images;
  
  (6)
  late DateTime createdAt;
  
  (7)
  late DateTime updatedAt;
  
  Product({
   
   
    required this.id,
    required this.name,
    required this.description,
    required this.price,
    required this.stock,
    required this.images,
    required this.createdAt,
    required this.updatedAt,
  });
}

运行代码生成器:

flutter packages pub run build_runner build

9.5.4 Hive初始化和管理

创建Hive管理类:

import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';

class HiveManager {
   
   
  static bool _isInitialized = false;
  
  // 初始化Hive
  static Future<void> initialize() async {
   
   
    if (_isInitialized) return;
    
    // 初始化Hive
    await Hive.initFlutter();
    
    // 注册适配器
    Hive.registerAdapter(UserAdapter());
    Hive.registerAdapter(ProductAdapter());
    
    _isInitialized = true;
  }
  
  // 打开所有需要的Box
  static Future<void> openBoxes() async {
   
   
    await Hive.openBox<User>('users');
    await Hive.openBox<Product>('products');
    await Hive.openBox('settings'); // 用于存储基本类型
    await Hive.openBox('cache');
  }
  
  // 关闭所有Box
  static Future<void> closeBoxes() async {
   
   
    await Hive.close();
  }
  
  // 清除所有数据
  static Future<void> clearAllData() async {
   
   
    await Hive.box<User>('users').clear();
    await Hive.box<Product>('products').clear();
    await Hive.box('settings').clear();
    await Hive.box('cache').clear();
  }
}

9.5.5 数据操作

创建数据仓库类:

class UserRepository {
   
   
  static Box<User> get _box => Hive.box<User>('users');
  
  // 添加用户
  static Future<void> addUser(User user) async {
   
   
    await _box.put(user.id, user
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值