软件教程 2025年08月6日
0 收藏 0 点赞 875 浏览 2736 个字
摘要 :

文章目录 单例模式与类的定义 获取数据库实例 显式初始化数据库 数据库初始化的具体逻辑 数据库的创建与升级 创建数据库表结构 处理数据库升级 总结 Flutter开发过程……




  • 单例模式与类的定义
  • 获取数据库实例
  • 显式初始化数据库
  • 数据库初始化的具体逻辑
  • 数据库的创建与升级
    • 创建数据库表结构
    • 处理数据库升级
  • 总结

Flutter开发过程中,对数据的存储和管理很重要。SQLite作为轻量级数据库,常被用于移动应用的数据持久化。今天咱们就来聊聊如何用单例模式编写一个数据库管理类,实现对SQLite数据库的高效管理。

单例模式与类的定义

在Flutter里,咱们创建了一个DatabaseHelper类,专门用来管理数据库的初始化和访问。这里用到了单例模式,简单来说,单例模式就是让这个类在整个应用里只有一个实例,这样能避免重复创建,节省资源。

来看代码:

static final DatabaseHelper instance = DatabaseHelper._();
static Database? _database;

DatabaseHelper._();

这里的instance是一个静态且不可变的实例,代表DatabaseHelper的唯一实例。构造函数DatabaseHelper._()前面加了下划线,这是私有构造函数的标志,它的作用是防止外部随意创建这个类的实例。想要获取这个唯一实例,在代码里通过DatabaseHelper.instance就可以访问到。而_database是个静态变量,用来存放数据库实例,刚开始它的值是null,意味着数据库还没初始化。

获取数据库实例

要获取数据库实例,咱们写了一个异步的getter方法:

Future<Database> get database async {
  _database ??= await _initDatabase();
  return _database!;
}

这个方法是这么工作的:当代码里调用database时,如果_database的值是null,就说明数据库还没初始化,这时会调用_initDatabase()方法进行初始化操作,并且把初始化后的结果赋值给_database。这里用了??=操作符,它的作用是确保_database只会被初始化一次,这就是懒加载,只有真正需要用数据库的时候才去初始化它,避免了不必要的资源浪费。最后返回的_database!,表示返回一个肯定不为空的数据库实例。

显式初始化数据库

为了能在应用启动时就提前初始化数据库,避免使用时出现延迟,我们还写了一个方法:

Future<void> init() async {
  await database;
}

init()方法是个异步方法,它里面调用了await database,这会触发前面提到的database的getter方法,从而确保数据库被初始化。这样在应用启动阶段调用这个方法,就能提前把数据库准备好。

数据库初始化的具体逻辑

数据库的初始化逻辑在下面这个私有方法里:

Future<Database> _initDatabase() async {
  final dbPath = await getDatabasesPath();
  final path = join(dbPath, \'rental_management.db\');

  return await openDatabase(
    path,
    version: 4,
    onCreate: _createDatabase,
    onUpgrade: _upgradeDatabase,
  );
}

首先,通过getDatabasesPath()获取设备上默认的数据库存储路径,然后用join(dbPath, \'rental_management.db\')把路径和数据库文件名拼在一起,得到完整的数据库文件路径。

接着调用openDatabase()方法,这是Flutter中sqflite插件提供的,用来打开或者创建数据库。这里面几个参数很重要:path就是刚刚拼好的数据库文件完整路径;version代表数据库版本号,这里设置为4,如果版本号变了,就会触发onUpgrade回调;onCreate是数据库首次创建时会调用的回调函数,一般用来初始化表结构;onUpgrade则是在数据库版本升级时调用,用于处理数据迁移等操作。

数据库的创建与升级

虽然文章里没有给出_createDatabase_upgradeDatabase的完整代码,但咱们来看看它们大概的作用。

创建数据库表结构

_createDatabase方法在数据库首次创建时会被调用,主要用来执行SQL语句创建表结构。比如说:

Future<void> _createDatabase(Database db, int version) async {
  await db.execute(\'\'\'
    CREATE TABLE rentals (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      price REAL NOT NULL
    )
  \'\'\');
}

这段代码就是在创建一个名为rentals的表,里面有id(自增长的主键)、name(不能为空的文本字段)和price(不能为空的实数类型字段)这几个字段。

处理数据库升级

_upgradeDatabase方法在数据库版本升级时会被调用,用来处理数据迁移的事情,比如添加新表、修改现有表结构。举个例子:

Future<void> _upgradeDatabase(Database db, int oldVersion, int newVersion) async {
  if (oldVersion < 2) {
    await db.execute(\'ALTER TABLE rentals ADD COLUMN description TEXT\');
  }
  if (oldVersion < 3) {
    await db.execute(\'CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT)\');
  }
}

这段代码表示,如果旧版本小于2,就给rentals表添加一个description字段;如果旧版本小于3,就创建一个新表users

总结

这篇文章介绍的代码,核心就是用单例模式管理SQLite数据库的初始化和访问。这种方式有不少优点:

  • 单例模式保障:通过私有构造函数和静态实例,保证了整个应用里数据库管理类只有一个实例。
  • 懒加载特性:数据库只有在第一次被访问时才会初始化,减少了不必要的资源消耗。
  • 版本管理支持:能够对数据库版本进行控制,处理好创建和升级的逻辑。
  • 异步操作优势:所有数据库操作都是异步的,不会阻塞主线程,保证了应用的流畅运行。

这种设计模式在Flutter开发,尤其是需要持久化数据的场景里,应用非常广泛。希望大家通过这篇文章,对Flutter开发中数据库管理有更深入的理解,也欢迎大家一起交流学习Flutter的相关知识,共同进步!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6862.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

270
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

108
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

684
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

340
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

844
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号