应用后保留 SQFlite 数据的最佳方法是 uninstalled/reinstalled on Android?
Best way to keep SQFlite data after app is uninstalled/reinstalled on Android?
我的 SQFlite 有问题,应用程序 uninstalled/reinstalled 后数据库被删除。我的客户将在数据库中存储数千条日志,我不能冒数据丢失的风险。
我的一些问题和想法:
我可以在外部文件系统中创建 SQFLite 数据库文件并直接从那里的 db 文件查询吗?
或者我唯一的选择是不断将 db 文件的副本作为备份写入外部文件系统?如果文件大小达到 2-5mb,这会成为问题吗?写入速度会很慢还是会导致崩溃?
我是否应该完全跳过使用 SQFlite 并使用远程 SQL 服务器数据库来代替我的目的?
我觉得很烦人,因为似乎没有备份 SQFLite 的好选择。我敢肯定,许多应用程序都需要保留数据。
谢谢!
从一开始就使用 Firebase 之类的东西。不要存储在本地。
您可以通过将 SQFLite 数据库存储在外部存储器中来保留应用程序安装之间的数据,因为卸载应用程序时不会删除这些数据。我自己测试过,确实有效。
以下是如何在外部存储器中设置该数据库的示例:
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);
}
}
}
我的 SQFlite 有问题,应用程序 uninstalled/reinstalled 后数据库被删除。我的客户将在数据库中存储数千条日志,我不能冒数据丢失的风险。
我的一些问题和想法:
我可以在外部文件系统中创建 SQFLite 数据库文件并直接从那里的 db 文件查询吗?
或者我唯一的选择是不断将 db 文件的副本作为备份写入外部文件系统?如果文件大小达到 2-5mb,这会成为问题吗?写入速度会很慢还是会导致崩溃?
我是否应该完全跳过使用 SQFlite 并使用远程 SQL 服务器数据库来代替我的目的?
我觉得很烦人,因为似乎没有备份 SQFLite 的好选择。我敢肯定,许多应用程序都需要保留数据。
谢谢!
从一开始就使用 Firebase 之类的东西。不要存储在本地。
您可以通过将 SQFLite 数据库存储在外部存储器中来保留应用程序安装之间的数据,因为卸载应用程序时不会删除这些数据。我自己测试过,确实有效。
以下是如何在外部存储器中设置该数据库的示例:
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);
}
}
}