Flutter 中的 Sqlite,数据库资产是如何工作的
Sqlite in flutter, how database assets work
我正在查看此 (https://github.com/tekartik/sqflite/blob/master/doc/opening_asset_db.md) 以填充已格式化且应用程序需要的数据,仅用于读取功能。
所以我对在外部 CSV 文件中已经拥有所有信息时创建 SQLite 数据库的理解是,在我的应用程序的 .dart 文件中创建 class 模型,例如
class User {
int id;
String _firstName;
String _lastName;
String _dob;
User(this._firstName, this._lastName, this._dob);
User.map(dynamic obj) {
this._firstName = obj["firstname"];
this._lastName = obj["lastname"];
this._dob = obj["dob"];
}
String get firstName => _firstName;
String get lastName => _lastName;
String get dob => _dob;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["firstname"] = _firstName;
map["lastname"] = _lastName;
map["dob"] = _dob;
return map;
}
void setUserId(int id) {
this.id = id;
}
}
那么如果我有一个 CSV 文件,其中包含所有用户信息(具有与用户对应的值 class),我可以使用数据库资产来填写信息和然后在 flutter 应用程序中调用它?我意识到可能有很多方法可以解决这个问题,但是 .db 文件存储的到底是什么,它是如何格式化的?我可以在这个 .db 文件中实现一个 .csv 文件吗?
此 .db 文件用于在 it.so 中保存 SQL 数据,您可以使用 SQL 命令保存和获取数据。插件本身会解析.db文件中的数据。
如果您想将数据保存为 CSV 格式并在 class 中解析,最好将数据存储在原始文件中(查看 here for saving file) or use this plugin。
虽然,还有一些其他方法可以将数据保存为 JSON 文件或将其保存在 key-value pair.
中
首先,您需要从您的 csv 构建一个 sqlite 数据库。这可以通过以下方式完成:
创建必要的 table (users.sql)
CREATE TABLE users(
firstname TEXT NOT NULL,
lastname TEXT NOT NULL,
dob TEXT NOT NULL
);
创建sqlite数据库
sqlite3 database.db < users.sql
插入csv数据
sqlite3 database.db
.mode csv
.import data.csv users
将 database.db 放入您的资产并将其添加到 pubspec.yaml。
flutter:
# ...
assets:
- assets/database.db
在您的应用中,您必须将资产文件复制到 "documents"。这个有点复杂。
// Construct a file path to copy database to
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "asset_database.db");
// Only copy if the database doesn't exist
if (FileSystemEntity.typeSync(path) == FileSystemEntityType.notFound){
// Load database from asset and copy
ByteData data = await rootBundle.load(join('assets', 'database.db'));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Save copied asset to documents
await new File(path).writeAsBytes(bytes);
}
终于可以这样访问数据库了
Directory appDocDir = await getApplicationDocumentsDirectory();
String databasePath = join(appDocDir.path, 'asset_database.db');
this.db = await openDatabase(databasePath);
initialized = true;
示例查询(this._initialize() 是第 6 步)
Future<List<Page>> search(String word, int parentId) async {
if (!initialized) await this._initialize();
String query = '''
SELECT * FROM users
LIMIT 25''';
return await this.db.rawQuery(query);
}
将资产添加到项目根目录下的文件系统中。创建一个资产文件夹并将您的数据库文件放入其中:
assets/examples.db
在 flutter 部分pubspec.yaml 中指定资产
flutter:
assets:
- assets/example.db
然后如果数据库存在就需要打开,如果不存在则复制。
此处的 link 显示 open/copy 预先存在的 sqlite 数据库的代码:
https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md
i use this function for copy database from assets folder
Future<void> _copyDatabase() async {
final String databasePath = await getDatabasesPath();
final String path = join(databasePath, 'dic.db');
final File file = File(path);
if (!file.existsSync()) {
ByteData data = await rootBundle.load(join('assets', 'dic.db'));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await file.writeAsBytes(bytes, flush: true);
logger.i('database successfully copied to $path');
} else {
logger.i('database already exist');
}
}
我正在查看此 (https://github.com/tekartik/sqflite/blob/master/doc/opening_asset_db.md) 以填充已格式化且应用程序需要的数据,仅用于读取功能。
所以我对在外部 CSV 文件中已经拥有所有信息时创建 SQLite 数据库的理解是,在我的应用程序的 .dart 文件中创建 class 模型,例如
class User {
int id;
String _firstName;
String _lastName;
String _dob;
User(this._firstName, this._lastName, this._dob);
User.map(dynamic obj) {
this._firstName = obj["firstname"];
this._lastName = obj["lastname"];
this._dob = obj["dob"];
}
String get firstName => _firstName;
String get lastName => _lastName;
String get dob => _dob;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["firstname"] = _firstName;
map["lastname"] = _lastName;
map["dob"] = _dob;
return map;
}
void setUserId(int id) {
this.id = id;
}
}
那么如果我有一个 CSV 文件,其中包含所有用户信息(具有与用户对应的值 class),我可以使用数据库资产来填写信息和然后在 flutter 应用程序中调用它?我意识到可能有很多方法可以解决这个问题,但是 .db 文件存储的到底是什么,它是如何格式化的?我可以在这个 .db 文件中实现一个 .csv 文件吗?
此 .db 文件用于在 it.so 中保存 SQL 数据,您可以使用 SQL 命令保存和获取数据。插件本身会解析.db文件中的数据。
如果您想将数据保存为 CSV 格式并在 class 中解析,最好将数据存储在原始文件中(查看 here for saving file) or use this plugin。 虽然,还有一些其他方法可以将数据保存为 JSON 文件或将其保存在 key-value pair.
中首先,您需要从您的 csv 构建一个 sqlite 数据库。这可以通过以下方式完成:
创建必要的 table (users.sql)
CREATE TABLE users( firstname TEXT NOT NULL, lastname TEXT NOT NULL, dob TEXT NOT NULL );
创建sqlite数据库
sqlite3 database.db < users.sql
插入csv数据
sqlite3 database.db .mode csv .import data.csv users
将 database.db 放入您的资产并将其添加到 pubspec.yaml。
flutter: # ... assets: - assets/database.db
在您的应用中,您必须将资产文件复制到 "documents"。这个有点复杂。
// Construct a file path to copy database to Directory documentsDirectory = await getApplicationDocumentsDirectory(); String path = join(documentsDirectory.path, "asset_database.db"); // Only copy if the database doesn't exist if (FileSystemEntity.typeSync(path) == FileSystemEntityType.notFound){ // Load database from asset and copy ByteData data = await rootBundle.load(join('assets', 'database.db')); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); // Save copied asset to documents await new File(path).writeAsBytes(bytes); }
终于可以这样访问数据库了
Directory appDocDir = await getApplicationDocumentsDirectory(); String databasePath = join(appDocDir.path, 'asset_database.db'); this.db = await openDatabase(databasePath); initialized = true;
示例查询(this._initialize() 是第 6 步)
Future<List<Page>> search(String word, int parentId) async { if (!initialized) await this._initialize(); String query = ''' SELECT * FROM users LIMIT 25'''; return await this.db.rawQuery(query); }
将资产添加到项目根目录下的文件系统中。创建一个资产文件夹并将您的数据库文件放入其中:
assets/examples.db
在 flutter 部分pubspec.yaml 中指定资产
flutter:
assets:
- assets/example.db
然后如果数据库存在就需要打开,如果不存在则复制。
此处的 link 显示 open/copy 预先存在的 sqlite 数据库的代码:
https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md
i use this function for copy database from assets folder
Future<void> _copyDatabase() async {
final String databasePath = await getDatabasesPath();
final String path = join(databasePath, 'dic.db');
final File file = File(path);
if (!file.existsSync()) {
ByteData data = await rootBundle.load(join('assets', 'dic.db'));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await file.writeAsBytes(bytes, flush: true);
logger.i('database successfully copied to $path');
} else {
logger.i('database already exist');
}
}