Flutter for OpenHarmony文件存储与数据库操作完全指南

Flutter for OpenHarmony文件存储与数据库操作完全指南

### 文章目录

  • [Flutter for OpenHarmony文件存储与数据库操作完全指南](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [@[toc]](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [前言](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [一、文件系统操作](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [1.1 路径获取与管理](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [1.2 文件读写操作封装](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [1.3 目录操作封装](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [二、SQLite数据库操作](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [2.1 数据库辅助类实现](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [2.2 数据模型定义](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [2.3 DAO层实现](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [三、数据库事务与性能优化](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [3.1 事务处理](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [3.2 性能优化技巧](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [总结](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [核心要点回顾](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)
  • [最佳实践建议](#文章目录 Flutter for OpenHarmony文件存储与数据库操作完全指南 @[toc] 前言 一、文件系统操作 1.1 路径获取与管理 1.2 文件读写操作封装 1.3 目录操作封装 二、SQLite数据库操作 2.1 数据库辅助类实现 2.2 数据模型定义 2.3 DAO层实现 三、数据库事务与性能优化 3.1 事务处理 3.2 性能优化技巧 总结 核心要点回顾 最佳实践建议)

前言

做应用开发,数据存储是绕不开的话题。简单的配置用SharedPreferences就够了,但复杂的业务数据就需要数据库。

Flutter for OpenHarmony 提供了多种数据持久化方案,但在实际开发中,很多开发者会遇到以下问题:

  • SharedPreferences、SQLite、文件存储,该选哪个?
  • 如何设计数据库表结构和迁移策略?
  • 大量数据插入时性能太差怎么办?
  • 如何避免SQL注入等安全问题?
  • OpenHarmony平台存储路径有什么特殊之处?

这篇文章我将系统性地讲解Flutter for OpenHarmony中的数据存储方案,包括文件操作、SQLite数据库、以及性能优化技巧。

本文亮点:

  • 完整的文件操作封装实现
  • SQLite数据库从入门到精通
  • 数据库迁移最佳实践
  • 性能优化技巧(批量操作、索引优化)
  • OpenHarmony平台存储适配要点
  • 常见问题解决方案

一、文件系统操作

1.1 路径获取与管理

Flutter提供了path_provider插件来获取各种系统目录。

添加依赖:

yaml 复制代码
dependencies:
  path_provider: ^2.1.1
  path: ^1.8.0

实现路径管理:

dart 复制代码
import 'package:path_provider/path_provider.dart';
import 'dart:io';

/// 路径管理器
class PathManager {
  /// 获取临时目录
  /// 用于缓存临时数据,系统可能随时清理
  static Future<Directory> getTemporaryDirectory() async {
    return await getTemporaryDirectory();
  }

  /// 获取应用文档目录
  /// 用于存储用户数据,不会被系统清理
  static Future<Directory> getAppDocumentDirectory() async {
    return await getApplicationDocumentsDirectory();
  }

  /// 获取应用支持目录
  /// 用于存储应用配置、缓存等
  static Future<Directory> getAppSupportDirectory() async {
    return await getApplicationSupportDirectory();
  }

  /// 获取外部存储目录(需要权限)
  /// Android: /storage/emulated/0/Android/data/com.xxx.xxx/files
  static Future<Directory?> getExternalStorageDirectory() async {
    if (Platform.isAndroid || Platform.isIOS) {
      return await getExternalStorageDirectory();
    }
    return null;
  }

  /// 创建自定义目录
  static Future<Directory> createCustomDirectory(String dirName) async {
    final appDocDir = await getAppDocumentDirectory();
    final customDir = Directory('${appDocDir.path}/$dirName');

    if (!await customDir.exists()) {
      await customDir.create(recursive: true);
    }

    return customDir;
  }

  /// 获取所有可用路径信息
  static Future<Map<String, String>> getAllPaths() async {
    final paths = <String, String>{};

    paths['临时目录'] = (await getTemporaryDirectory()).path;
    paths['文档目录'] = (await getAppDocumentDirectory()).path;
    paths['支持目录'] = (await getAppSupportDirectory()).path;

    final externalDir = await getExternalStorageDirectory();
    if (externalDir != null) {
      paths['外部存储'] = externalDir.path;
    }

    return paths;
  }
}

1.2 文件读写操作封装

dart 复制代码
import 'dart:io';

/// 文件操作工具类
class FileHelper {
  /// 写入字符串到文件
  static Future<void> writeString(String path, String content) async {
    final file = File(path);
    await file.writeAsString(content);
  }

  /// 读取字符串文件
  static Future<String> readString(String path) async {
    final file = File(path);
    if (!await file.exists()) {
      throw FileSystemException('文件不存在', path);
    }
    return await file.readAsString();
  }

  /// 写入字节数据
  static Future<void> writeBytes(String path, List<int> bytes) async {
    final file = File(path);
    await file.writeAsBytes(bytes);
  }

  /// 读取字节数据
  static Future<List<int>> readBytes(String path) async {
    final file = File(path);
    if (!await file.exists()) {
      throw FileSystemException('文件不存在', path);
    }
    return await file.readAsBytes();
  }

  /// 检查文件是否存在
  static Future<bool> exists(String path) async {
    return await File(path).exists();
  }

  /// 删除文件
  static Future<void> delete(String path) async {
    final file = File(path);
    if (await file.exists()) {
      await file.delete();
    }
  }

  /// 获取文件大小
  static Future<int> getFileSize(String path) async {
    final file = File(path);
    if (!await file.exists()) {
      return 0;
    }
    return await file.length();
  }

  /// 复制文件
  static Future<void> copy(String sourcePath, String targetPath) async {
    final sourceFile = File(sourcePath);
    await sourceFile.copy(targetPath);
  }

  /// 重命名文件
  static Future<void> rename(String oldPath, String newPath) async {
    final file = File(oldPath);
    await file.rename(newPath);
  }
}

/// JSON文件操作
class JsonFileHelper {
  /// 写入JSON对象到文件
  static Future<void> writeJson(String path, Map<String, dynamic> data) async {
    final jsonString = const JsonEncoder.withIndent('  ').convert(data);
    await FileHelper.writeString(path, jsonString);
  }

  /// 从文件读取JSON对象
  static Future<Map<String, dynamic>> readJson(String path) async {
    final jsonString = await FileHelper.readString(path);
    final jsonData = jsonDecode(jsonString) as Map<String, dynamic>;
    return jsonData;
  }

  /// 写入JSON数组到文件
  static Future<void> writeJsonList(String path, List<dynamic> data) async {
    final jsonString = const JsonEncoder.withIndent('  ').convert(data);
    await FileHelper.writeString(path, jsonString);
  }

  /// 从文件读取JSON数组
  static Future<List<dynamic>> readJsonList(String path) async {
    final jsonString = await FileHelper.readString(path);
    final jsonData = jsonDecode(jsonString) as List<dynamic>;
    return jsonData;
  }
}

1.3 目录操作封装

dart 复制代码
/// 目录操作工具类
class DirectoryHelper {
  /// 创建目录
  static Future<void> createDirectory(String path) async {
    final dir = Directory(path);
    if (!await dir.exists()) {
      await dir.create(recursive: true);
    }
  }

  /// 列出目录下所有文件
  static Future<List<FileSystemEntity>> listFiles(String path) async {
    final dir = Directory(path);
    if (!await dir.exists()) {
      return [];
    }
    return dir.listSync();
  }

  /// 列出目录下所有文件(递归)
  static Future<List<File>> listFilesRecursively(String path) async {
    final dir = Directory(path);
    if (!await dir.exists()) {
      return [];
    }

    final files = <File>[];
    await for (final entity in dir.list(recursive: true)) {
      if (entity is File) {
        files.add(entity);
      }
    }
    return files;
  }

  /// 删除目录
  static Future<void> deleteDirectory(String path) async {
    final dir = Directory(path);
    if (await dir.exists()) {
      await dir.delete(recursive: true);
    }
  }

  /// 获取目录大小
  static Future<int> getDirectorySize(String path) async {
    final files = await listFilesRecursively(path);
    int totalSize = 0;

    for (final file in files) {
      totalSize += await file.length();
    }

    return totalSize;
  }

  /// 清空目录(删除目录下所有文件)
  static Future<void> clearDirectory(String path) async {
    final dir = Directory(path);
    if (!await dir.exists()) {
      return;
    }

    await for (final entity in dir.list()) {
      if (entity is File) {
        await entity.delete();
      } else if (entity is Directory) {
        await entity.delete(recursive: true);
      }
    }
  }
}

二、SQLite数据库操作

2.1 数据库辅助类实现

添加依赖:

yaml 复制代码
dependencies:
  sqflite: ^2.3.0
  path: ^1.8.0

实现数据库管理:

dart 复制代码
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

/// 数据库版本号
const int _databaseVersion = 1;

/// 数据库名称
const String _databaseName = 'app_database.db';

/// 数据库管理类
class DatabaseHelper {
  // 单例模式
  static final DatabaseHelper _instance = DatabaseHelper._internal();
  factory DatabaseHelper() => _instance;

  DatabaseHelper._internal();

  static Database? _database;

  /// 获取数据库实例
  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDatabase();
    return _database!;
  }

  /// 初始化数据库
  Future<Database> _initDatabase() async {
    // 获取数据库路径
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, _databaseName);

    // 打开数据库,如果不存在则创建
    return await openDatabase(
      path,
      version: _databaseVersion,
      onCreate: _onCreate,
      onUpgrade: _onUpgrade,
      onConfigure: _onConfigure,
    );
  }

  /// 数据库配置
  static Future<void> _onConfigure(Database db) async {
    // 启用外键约束
    await db.execute('PRAGMA foreign_keys = ON');
  }

  /// 创建数据库表
  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 UNIQUE,
        password TEXT NOT NULL,
        nickname TEXT,
        avatar TEXT,
        created_at INTEGER NOT NULL,
        updated_at INTEGER NOT NULL
      )
    ''');

    // 创建待办事项表
    await db.execute('''
      CREATE TABLE todos (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        description TEXT,
        is_completed INTEGER DEFAULT 0,
        priority INTEGER DEFAULT 0,
        due_date INTEGER,
        user_id INTEGER NOT NULL,
        created_at INTEGER NOT NULL,
        updated_at INTEGER NOT NULL,
        FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
      )
    ''');

    // 创建索引
    await _createIndexes(db);
  }

  /// 创建索引
  static Future<void> _createIndexes(Database db) async {
    // 用户表索引
    await db.execute('CREATE INDEX idx_users_username ON users(username)');
    await db.execute('CREATE INDEX idx_users_email ON users(email)');

    // 待办事项表索引
    await db.execute('CREATE INDEX idx_todos_user_id ON todos(user_id)');
    await db.execute('CREATE INDEX idx_todos_due_date ON todos(due_date)');
    await db.execute('CREATE INDEX idx_todos_is_completed ON todos(is_completed)');
  }

  /// 数据库升级
  Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
    if (oldVersion < 2) {
      // 版本1到版本2的升级
      await db.execute('ALTER TABLE users ADD COLUMN phone TEXT');
      await db.execute('ALTER TABLE users ADD COLUMN gender INTEGER DEFAULT 0');
    }

    if (oldVersion < 3) {
      // 版本2到版本3的升级
      await db.execute('ALTER TABLE todos ADD COLUMN tags TEXT');
    }

    // 更多版本升级...
  }

  /// 关闭数据库
  Future<void> close() async {
    final db = await database;
    await db.close();
    _database = null;
  }
}

2.2 数据模型定义

dart 复制代码
/// 用户模型
class User {
  final int? id;
  final String username;
  final String email;
  final String password;
  final String? nickname;
  final String? avatar;
  final DateTime createdAt;
  final DateTime updatedAt;

  User({
    this.id,
    required this.username,
    required this.email,
    required this.password,
    this.nickname,
    this.avatar,
    required this.createdAt,
    required this.updatedAt,
  });

  /// 从Map创建
  factory User.fromMap(Map<String, dynamic> map) {
    return User(
      id: map['id'] as int?,
      username: map['username'] as String,
      email: map['email'] as String,
      password: map['password'] as String,
      nickname: map['nickname'] as String?,
      avatar: map['avatar'] as String?,
      createdAt: DateTime.fromMillisecondsSinceEpoch(map['created_at'] as int),
      updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updated_at'] as int),
    );
  }

  /// 转换为Map
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'username': username,
      'email': email,
      'password': password,
      'nickname': nickname,
      'avatar': avatar,
      'created_at': createdAt.millisecondsSinceEpoch,
      'updated_at': updatedAt.millisecondsSinceEpoch,
    };
  }

  /// 复制并修改部分字段
  User copyWith({
    int? id,
    String? username,
    String? email,
    String? password,
    String? nickname,
    String? avatar,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return User(
      id: id ?? this.id,
      username: username ?? this.username,
      email: email ?? this.email,
      password: password ?? this.password,
      nickname: nickname ?? this.nickname,
      avatar: avatar ?? this.avatar,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }
}

/// 待办事项模型
class Todo {
  final int? id;
  final String title;
  final String? description;
  final bool isCompleted;
  final int priority;
  final DateTime? dueDate;
  final int userId;
  final DateTime createdAt;
  final DateTime updatedAt;
  final String? tags;

  Todo({
    this.id,
    required this.title,
    this.description,
    this.isCompleted = false,
    this.priority = 0,
    this.dueDate,
    required this.userId,
    required this.createdAt,
    required this.updatedAt,
    this.tags,
  });

  /// 从Map创建
  factory Todo.fromMap(Map<String, dynamic> map) {
    return Todo(
      id: map['id'] as int?,
      title: map['title'] as String,
      description: map['description'] as String?,
      isCompleted: (map['is_completed'] as int) == 1,
      priority: map['priority'] as int? ?? 0,
      dueDate: map['due_date'] != null
          ? DateTime.fromMillisecondsSinceEpoch(map['due_date'] as int)
          : null,
      userId: map['user_id'] as int,
      createdAt: DateTime.fromMillisecondsSinceEpoch(map['created_at'] as int),
      updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updated_at'] as int),
      tags: map['tags'] as String?,
    );
  }

  /// 转换为Map
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'is_completed': isCompleted ? 1 : 0,
      'priority': priority,
      'due_date': dueDate?.millisecondsSinceEpoch,
      'user_id': userId,
      'created_at': createdAt.millisecondsSinceEpoch,
      'updated_at': updatedAt.millisecondsSinceEpoch,
      'tags': tags,
    };
  }
}

2.3 DAO层实现

dart 复制代码
/// 用户数据访问对象
class UserDao {
  final DatabaseHelper _dbHelper = DatabaseHelper();

  /// 插入用户
  Future<int> insert(User user) async {
    final db = await _dbHelper.database;
    return await db.insert('users', user.toMap());
  }

  /// 批量插入用户
  Future<void> insertBatch(List<User> users) async {
    final db = await _dbHelper.database;
    final batch = db.batch();

    for (final user in users) {
      batch.insert('users', user.toMap());
    }

    await batch.commit(noResult: true);
  }

  /// 根据ID查询用户
  Future<User?> queryById(int id) async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'users',
      where: 'id = ?',
      whereArgs: [id],
    );

    if (maps.isEmpty) return null;
    return User.fromMap(maps.first);
  }

  /// 根据用户名查询用户
  Future<User?> queryByUsername(String username) async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'users',
      where: 'username = ?',
      whereArgs: [username],
    );

    if (maps.isEmpty) return null;
    return User.fromMap(maps.first);
  }

  /// 查询所有用户
  Future<List<User>> queryAll() async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query('users');
    return maps.map((map) => User.fromMap(map)).toList();
  }

  /// 分页查询用户
  Future<List<User>> queryByPage(int page, int pageSize) async {
    final db = await _dbHelper.database;
    final offset = (page - 1) * pageSize;

    final List<Map<String, dynamic>> maps = await db.query(
      'users',
      limit: pageSize,
      offset: offset,
      orderBy: 'created_at DESC',
    );

    return maps.map((map) => User.fromMap(map)).toList();
  }

  /// 更新用户
  Future<int> update(User user) async {
    final db = await _dbHelper.database;
    return await db.update(
      'users',
      user.toMap(),
      where: 'id = ?',
      whereArgs: [user.id],
    );
  }

  /// 删除用户
  Future<int> delete(int id) async {
    final db = await _dbHelper.database;
    return await db.delete(
      'users',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  /// 获取用户总数
  Future<int> getCount() async {
    final db = await _dbHelper.database;
    final result = await db.rawQuery('SELECT COUNT(*) as count FROM users');
    return Sqflite.firstIntValue(result) ?? 0;
  }
}

/// 待办事项数据访问对象
class TodoDao {
  final DatabaseHelper _dbHelper = DatabaseHelper();

  /// 插入待办事项
  Future<int> insert(Todo todo) async {
    final db = await _dbHelper.database;
    return await db.insert('todos', todo.toMap());
  }

  /// 根据ID查询待办事项
  Future<Todo?> queryById(int id) async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'todos',
      where: 'id = ?',
      whereArgs: [id],
    );

    if (maps.isEmpty) return null;
    return Todo.fromMap(maps.first);
  }

  /// 查询用户的所有待办事项
  Future<List<Todo>> queryByUserId(int userId) async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'todos',
      where: 'user_id = ?',
      whereArgs: [userId],
      orderBy: 'created_at DESC',
    );

    return maps.map((map) => Todo.fromMap(map)).toList();
  }

  /// 查询未完成的待办事项
  Future<List<Todo>> queryIncompleteTodos(int userId) async {
    final db = await _dbHelper.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'todos',
      where: 'user_id = ? AND is_completed = ?',
      whereArgs: [userId, 0],
      orderBy: 'due_date ASC',
    );

    return maps.map((map) => Todo.fromMap(map)).toList();
  }

  /// 更新待办事项
  Future<int> update(Todo todo) async {
    final db = await _dbHelper.database;
    return await db.update(
      'todos',
      todo.toMap(),
      where: 'id = ?',
      whereArgs: [todo.id],
    );
  }

  /// 标记待办事项为完成
  Future<int> markAsComplete(int id) async {
    final db = await _dbHelper.database;
    return await db.update(
      'todos',
      {
        'is_completed': 1,
        'updated_at': DateTime.now().millisecondsSinceEpoch,
      },
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  /// 删除待办事项
  Future<int> delete(int id) async {
    final db = await _dbHelper.database;
    return await db.delete(
      'todos',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  /// 删除用户的所有待办事项
  Future<int> deleteByUserId(int userId) async {
    final db = await _dbHelper.database;
    return await db.delete(
      'todos',
      where: 'user_id = ?',
      whereArgs: [userId],
    );
  }
}

三、数据库事务与性能优化

3.1 事务处理

dart 复制代码
/// 事务管理器
class TransactionManager {
  final DatabaseHelper _dbHelper = DatabaseHelper();

  /// 转账示例 - 使用事务保证数据一致性
  Future<void> transferMoney(
    int fromUserId,
    int toUserId,
    double amount,
  ) async {
    final db = await _dbHelper.database;

    await db.transaction((txn) async {
      // 1. 扣除转出用户余额
      await txn.update(
        'users',
        {'balance': -amount, 'updated_at': DateTime.now().millisecondsSinceEpoch},
        where: 'id = ?',
        whereArgs: [fromUserId],
      );

      // 2. 增加转入用户余额
      await txn.update(
        'users',
        {'balance': amount, 'updated_at': DateTime.now().millisecondsSinceEpoch},
        where: 'id = ?',
        whereArgs: [toUserId],
      );
    });
  }

  /// 批量插入 - 使用事务提升性能
  Future<void> batchInsert(List<User> users) async {
    final db = await _dbHelper.database;

    await db.transaction((txn) async {
      final batch = txn.batch();

      for (final user in users) {
        batch.insert('users', user.toMap());
      }

      await batch.commit(noResult: true);
    });
  }

  /// 带异常处理的事务
  Future<T> transaction<T>(
    Future<T> Function(Transaction) action,
  ) async {
    final db = await _dbHelper.database;

    return await db.transaction((txn) async {
      try {
        return await action(txn);
      } catch (e) {
        // 记录错误日志
        debugPrint('事务执行失败: $e');
        rethrow;
      }
    });
  }
}

3.2 性能优化技巧

dart 复制代码
/// 数据库性能优化工具
class DatabaseOptimizer {
  final DatabaseHelper _dbHelper = DatabaseHelper();

  /// 批量操作优化
  Future<void> optimizedBatchInsert(List<Todo> todos) async {
    final db = await _dbHelper.database;

    // 使用批量插入而非逐条插入
    await db.transaction((txn) async {
      final batch = txn.batch();

      for (final todo in todos) {
        batch.insert('todos', todo.toMap());
      }

      // noResult: true 提升性能(不返回结果)
      await batch.commit(noResult: true);
    });
  }

  /// 分页查询优化
  Future<List<Todo>> optimizedPaginatedQuery(
    int page,
    int pageSize,
  ) async {
    final db = await _dbHelper.database;
    final offset = (page - 1) * pageSize;

    // 只查询需要的字段
    final List<Map<String, dynamic>> maps = await db.query(
      'todos',
      columns: ['id', 'title', 'is_completed', 'due_date'],
      limit: pageSize,
      offset: offset,
      orderBy: 'created_at DESC',
    );

    return maps.map((map) => Todo.fromMap(map)).toList();
  }

  /// 使用索引优化查询
  Future<List<Todo>> indexedQuery(int userId) async {
    final db = await _dbHelper.database;

    // 确保user_id字段有索引
    final List<Map<String, dynamic>> maps = await db.query(
      'todos',
      where: 'user_id = ?',
      whereArgs: [userId],
      // 利用索引排序
      orderBy: 'due_date ASC',
    );

    return maps.map((map) => Todo.fromMap(map)).toList();
  }

  /// 清理数据表
  Future<void> vacuumDatabase() async {
    final db = await _dbHelper.database;
    await db.execute('VACUUM');
  }

  /// 分析表并更新统计信息
  Future<void> analyzeTable(String tableName) async {
    final db = await _dbHelper.database;
    await db.execute('ANALYZE $tableName');
  }
}

总结

本文系统性地讲解了Flutter for OpenHarmony中的文件存储和数据库操作,从基础API到性能优化。

核心要点回顾

技术点 关键内容 注意事项
文件存储 path_provider、File操作 注意路径权限
SQLite 单例模式、DAO层 防止内存泄漏
事务处理 保证数据一致性 及时回滚
性能优化 批量操作、索引 避免N+1查询
数据迁移 版本管理 向后兼容

最佳实践建议

  1. 使用单例模式管理数据库
  2. DAO层封装数据访问
  3. 复杂查询使用事务
  4. 批量操作提升性能
  5. 合理使用索引
  6. 做好数据库版本管理

相关资源:

欢迎加入开源鸿蒙跨平台社区 : 开源鸿蒙跨平台开发者社区

如果这篇文章对你有帮助,请点赞、收藏、分享,让更多开发者看到!


写于2025年 | Flutter for OpenHarmony系列教程

相关推荐
木辰風6 小时前
PLSQL自定义自动替换(AutoReplace)
java·数据库·sql
无限码力6 小时前
华为OD技术面真题 - 数据库MySQL - 3
数据库·mysql·华为od·八股文·华为od技术面八股文
2501_944525546 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 预算详情页面
android·开发语言·前端·javascript·flutter·ecmascript
heartbeat..6 小时前
Redis 中的锁:核心实现、类型与最佳实践
java·数据库·redis·缓存·并发
Prince-Peng6 小时前
技术架构系列 - 详解Redis
数据结构·数据库·redis·分布式·缓存·中间件·架构
雨季6666 小时前
Flutter 三端应用实战:OpenHarmony 简易“动态主题切换卡片”交互模式
flutter·ui·交互·dart
虾说羊6 小时前
redis中的哨兵机制
数据库·redis·缓存
_F_y6 小时前
MySQL视图
数据库·mysql
熊猫钓鱼>_>6 小时前
【开源鸿蒙跨平台开发先锋训练营】Day 19: 开源鸿蒙React Native动效体系构建与混合开发复盘
react native·华为·开源·harmonyos·鸿蒙·openharmony
2301_790300966 小时前
Python单元测试(unittest)实战指南
jvm·数据库·python