如何使用预填充的本地数据库设置飞镖对象框?
How setup dart objectbox with a local database pre-populated?
我想用 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();
});
}
}
是的,即使您想避免在应用程序内填充数据库(例如在第一个 运行 上),您也可以捆绑现有数据库。只需在本地创建数据库文件 (data.mdb
),甚至在您的计算机上(它们跨平台兼容),然后将其作为资源添加到应用程序中。
在第一个应用程序 运行 上,您可以将 data.mdb
文件移动到应用程序文档目录(进入子目录 objectbox
)——如果您这样做,ObjectBox 默认将文件存储在该目录中使用了生成的 openStore()
方法。所以数据库文件的路径应该是(使用包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());
}
}
我想用 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();
});
}
}
是的,即使您想避免在应用程序内填充数据库(例如在第一个 运行 上),您也可以捆绑现有数据库。只需在本地创建数据库文件 (data.mdb
),甚至在您的计算机上(它们跨平台兼容),然后将其作为资源添加到应用程序中。
在第一个应用程序 运行 上,您可以将 data.mdb
文件移动到应用程序文档目录(进入子目录 objectbox
)——如果您这样做,ObjectBox 默认将文件存储在该目录中使用了生成的 openStore()
方法。所以数据库文件的路径应该是(使用包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());
}
}