什么时候是静态数据库? _D b;不为空?

when is static Database? _db; not null?

我是第一次使用 sqflite 创建数据库。我只是对 dbHelper 的创建感到困惑。所有实现几乎都以相同的方式进行。令人困惑的问题是 _db 在每次打开应用程序的开始时它总是空的,这意味着这总是创建一个新的 table。 _db 何时不为空?

代码是:

class DatabaseHelper {
  DatabaseHelper._();
  static final DatabaseHelper _instance = DatabaseHelper._();
  factory DatabaseHelper() => _instance;
  static Database? _db;

  Future<Database?> createDB() async {
    if (_db != null) return _db;
    String path = await getDatabasesPath();
    _db = await openDatabase(
      join(path, "todo.db"),version: 1,
      onCreate: (Database database, int version)async {
        await database.execute('');
      },
    );
    return _db;
  }
}

TLDR; 只有在指定路径中找不到数据库文件时,才会调用传递给 openDatabase 中 onCreate 参数的回调。


如果我答对了你的问题,你担心多次创建相同的表,对吗? 除非用户清除应用程序数据,否则不会发生这种情况。来自 docs:

onCreate is called if the database did not exist prior to calling openDatabase. You can use the opportunity to create the required tables in the database according to your schema

我将尝试绘制事件发生的场景,希望这将为您清除所有内容:

第一次 运行 您的应用:

  1. 你通过工厂
  2. 启动获取单例实例DatabaseHelper
  3. 您调用 createDB() 获取 sqflite.Database
  4. 的实例
  5. _db 将为 null,因此当 openDatabase 被调用时,将创建一个新的数据库实例并将其分配给 _db
  6. 由于 getDatabasesPath() 提供的路径中没有数据库文件,将调用 onCreate 并创建表
  7. 之后任何时候调用 creatDB() 都不会触发相同的工作流程,因为 _db 不再为空(因为它是静态变量)

你第二次 运行 app:

  1. 你通过工厂

    启动获取单例实例DatabaseHelper
  2. 你调用createDB()得到sqflite.Database

    的一个实例
  3. _db 将为空 ,因此当 openDatabase 被调用

  4. 并且由于数据库文件 存在 在您由 getDatabasesPath() 提供的路径中,因此 onCreate()不再 被调用

  5. 之后任何时候调用 creatDB() 都不会触发相同的工作流程,因为 _db 不再为空(因为它是静态变量)