【问题标题】:How setup dart objectbox with a local database pre-populated?如何使用预先填充的本地数据库设置 dart objectbox?
【发布时间】:2021-09-27 20:32:08
【问题描述】:

我想用 Flutter 建立一个 ObjectBox 数据库。 我想用值预先填充数据库文件。安装应用程序时,数据库文件将被复制并由应用程序使用。我希望能够继续提供模式迁移。有可能吗?

如何建立这种类型的架构? 你有什么例子吗?

解决方案: 通过@vaind 响应,我实现了一个数据库管理器,例如:

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';

import '../objectbox.g.dart';

/// Database manager manage database initialisation and configuration.
class DatabaseManager {
  static DatabaseManager? _instance;

  DatabaseManager._internal();

  /// Singleton Factory constructor
  factory DatabaseManager() {
    if (_instance == null) {
      _instance = DatabaseManager._internal();
    }

    return _instance!;
  }

  /// Initialize configuration of database:
  ///  - Init database file by copying.
  ///  - Open instance of database and close it.
  Future<void> init() async {
    await copyDatabaseFileFromAssets();
    await testInstanceAndCloseIt();
  }

  /// Copy packaged database from assets folder to the app directory.
  Future<void> copyDatabaseFileFromAssets() async {
    // Get pre-populated db file.
    ByteData data = await rootBundle.load("assets/databases/data.mdb");
    List<int> bytes =
    data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

    // Search and create db file destination folder if not exist
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = documentsDirectory.path + "/objectbox/data.mdb";

    if (!await File(path).exists()) {
      var objectBoxDirectory = Directory(documentsDirectory.path + "/objectbox/");
      if ((!await objectBoxDirectory.exists())) {
        objectBoxDirectory.create();
      }

      // Copying source data into destination file.
      await new File(path).writeAsBytes(bytes);
    }
  }

  /// Open instance of database and close it.
  Future<void> testInstanceAndCloseIt() async {
    await openStore().then((Store store) {
      store.close();
    });
  }
}

【问题讨论】:

    标签: flutter dart objectbox flutter-objectbox objectbuilder


    【解决方案1】:

    是的,即使您想避免在应用程序内填充数据库(例如在第一次运行时),您也可以捆绑现有数据库。只需在本地创建数据库文件 (data.mdb),甚至在您的机器上(它们跨平台兼容),然后将其作为资源添加到应用程序中。

    在第一个应用程序运行时,您只需将data.mdb 文件移动到应用程序文档目录(到子目录objectbox) - 如果您使用了生成的openStore() 方法,默认情况下ObjectBox 会存储在该目录中。所以数据库文件的路径应该是(使用包path_provider): (await getApplicationDocumentsDirectory()).path + '/objectbox/data.mdb'。当然,请确保写入文件后打开商店。


    问题更新后更新。我认为您的copyDatabaseFileFromAssets 应该看起来更像以下内容。仅当数据库文件不存在时才创建它。

    Future<void> copyDatabaseFileFromAssets() async {
      // Search and create db file destination folder if not exist
      final documentsDirectory = await getApplicationDocumentsDirectory();
      final objectBoxDirectory = Directory(documentsDirectory.path + '/objectbox/');
      
      if (!objectBoxDirectory.existsSync()) {
        await objectBoxDirectory.create(recursive: true);
      }
    
      final dbFile = File(objectBoxDirectory.path + '/data.mdb');
      if (!dbFile.existsSync()) {
        // Get pre-populated db file.
        ByteData data = await rootBundle.load("assets/databases/data.mdb");
    
        // Copying source data into destination file.
        await dbFile.writeAsBytes(data.buffer.asUint8List());
      }
    }
    

    【讨论】:

    • 一个建议,请创建一些加入复杂查询的示例。我还想创建一些对新手有用的示例。
    • 非常欢迎带有示例的 PR。我假设你已经看过relation link queries
    • Tkank,我用我的实现更新了我的帖子。如何使用这种方法迁移数据库?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2016-07-02
    相关资源
    最近更新 更多