[英]Best way to keep SQFlite data after app is uninstalled/reinstalled on Android?
I have a problem with SQFlite that the database is deleted after the app is uninstalled/reinstalled.我对 SQFlite 有疑问,即在卸载/重新安装应用程序后删除了数据库。 My client will have thousands of logs stored in the database and I can't risk the data being lost.
我的客户将在数据库中存储数以千计的日志,我不能冒丢失数据的风险。
Some questions and ideas I have:我有一些问题和想法:
Can I create a SQFLite database file in the external file system and query directly from a db file there?我可以在外部文件系统中创建一个 SQFLite 数据库文件并直接从那里的 db 文件中查询吗?
Or is my only option to constantly write a copy of the db file as a backup to the external file system?还是我唯一的选择是不断将 db 文件的副本作为备份写入外部文件系统? Will this be a problem if the file reaches a size of 2-5mb?
如果文件大小达到 2-5mb,这会是一个问题吗? Will that write be slow or could cause crashes?
写入会很慢还是会导致崩溃?
Should I just skip using SQFlite altogether and use a remote SQL Server database instead for my purpose?我是否应该完全跳过使用 SQFlite 并使用远程 SQL 服务器数据库来代替我的目的?
I find it very annoying that there doesn't seem to be a good option to backup SQFLite.我觉得很烦人,似乎没有备份 SQFLite 的好选择。 Many apps need to keep the data I'm sure.
我敢肯定,许多应用程序都需要保留数据。
Thanks!谢谢!
Just use something like Firebase from the get-go.从一开始就使用 Firebase 之类的东西。 Don't store it locally.
不要将其存储在本地。
You can keep the data between installations of the app by storing the SQFLite database in external storage, since this is not deleted when uninstalling the app.您可以通过将 SQFLite 数据库存储在外部存储中来保留应用程序安装之间的数据,因为卸载应用程序时不会删除这些数据。 I have tested it myself and it works.
我自己测试过它并且它有效。
Here is an example of how you can set up that database in external memory:以下是如何在外部 memory 中设置该数据库的示例:
import 'dart:io';
import 'package:SQFLite_test/helpers/ClientMocker.dart';
import 'package:SQFLite_test/models/ClientModel.dart';
import 'package:ext_storage/ext_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sqflite/sqflite.dart';
class LogServiceTwo {
LogServiceTwo._();
static final LogServiceTwo logRepo = LogServiceTwo._();
static Database _database;
Future<Database> get database async {
if (_database != null) {
return _database;
}
await askForWritePermission();
var db = await openDb();
if (db == null) {
_database = await initDB();
return _database;
}
var hasClientTableB = await hasClientTable(db);
if (hasClientTableB) {
_database = db;
return _database;
}
await createClientTable(db);
_database = db;
return _database;
}
Future createClientTable(Database db) async {
await db.execute("CREATE TABLE Client ("
"id INTEGER PRIMARY KEY,"
"first_name TEXT,"
"last_name TEXT,"
"blocked BIT"
")");
}
Future<bool> hasClientTable(Database db) async {
try {
var table = await db.query("Client");
return table != null;
} catch (e) {
return false;
}
}
Future<Database> openDb() async {
try {
var path = await getPersistentDbPath();
var db = await openDatabase(path, version: 1);
return db;
} catch (e) {
return null;
}
}
Future initDB() async {
var path = await getPersistentDbPath();
return await openDatabase(path, version: 1, onOpen: (db) {}, onCreate: (Database db, int version) async {
await db.execute("CREATE TABLE Client ("
"id INTEGER PRIMARY KEY,"
"first_name TEXT,"
"last_name TEXT,"
"blocked BIT"
")");
});
}
Future newClient(Client newClient) async {
final db = await database;
var res = await db.insert("Client", newClient.toMap());
return res;
}
Future newClients(List<Client> clients) async {
var clientMaps = clients.map((client) => client.toMap()).toList();
final db = await database;
var batch = db.batch();
clientMaps.forEach((clientMap) async {
batch.insert("Client", clientMap);
});
await batch.commit(noResult: true);
}
Future<Client> getClient(int id) async {
final db = await database;
var res = await db.query("Client", where: "id = ?", whereArgs: [id]);
return res.isNotEmpty ? Client.fromMap(res.first) : Null;
}
Future<List<Client>> getAllClients() async {
final db = await database;
var res = await db.query("Client");
List<Client> list = res.isNotEmpty ? res.map((c) => Client.fromMap(c)).toList() : [];
return list;
}
Future<List<Client>> getBlockedClients() async {
final db = await logRepo.database;
var res = await db.rawQuery("SELECT * FROM Client WHERE blocked=1");
List<Client> list = res.isNotEmpty ? res.toList().map((c) => Client.fromMap(c)) : null;
return list;
}
Future<List<String>> getTables() async {
var db = await logRepo.database;
var tableNames = (await db.query('sqlite_master', where: 'type = ?', whereArgs: ['table'])).map((row) => row['name'] as String).toList(growable: false);
return tableNames;
}
Future<String> getPersistentDbPath() async {
return await createPersistentDbDirecotry();
}
Future<String> createPersistentDbDirecotry() async {
var externalDirectoryPath = await ExtStorage.getExternalStorageDirectory();
var persistentDirectory = "$externalDirectoryPath/db_persistent";
var directory = await createDirectory(persistentDirectory);
listFiles(directory);
return "$persistentDirectory/persistent.db";
}
listFiles(Directory directory) {
print("${directory.path} files:");
directory.list().forEach((file) {
print(file.path);
print(file.statSync().size);
});
}
Future<Directory> createDirectory(String path) async {
return await (new Directory(path).create());
}
Future<bool> askForWritePermission() async {
var status = await Permission.storage.status;
if (!status.isGranted) {
status = await Permission.storage.request();
return status.isGranted;
}
return status.isGranted;
}
Future mockData() async {
var clients = ClientMocker.createClients();
await newClients(clients);
}
Future deleteAll() async {
var db = await database;
await db.rawDelete("DELETE FROM Client");
}
Future getClients() async {
try {
var db = await database;
return await db.rawQuery("SELECT * FROM Client");
} catch (e) {
print(e);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.