【问题标题】:Best way to keep SQFlite data after app is uninstalled/reinstalled on Android?在 Android 上卸载/重新安装应用程序后保留 SQFlite 数据的最佳方式?
【发布时间】:2020-12-18 12:44:49
【问题描述】:

我对 SQFlite 有疑问,即在卸载/重新安装应用程序后删除了数据库。我的客户将在数据库中存储数千条日志,我不能冒丢失数据的风险。

我的一些问题和想法:

我可以在外部文件系统中创建一个 SQFLite 数据库文件并直接从那里的 db 文件中查询吗?

或者我唯一的选择是不断将 db 文件的副本作为备份写入外部文件系统?如果文件大小达到 2-5mb,这会是一个问题吗?写入会很慢还是会导致崩溃?

我是否应该完全跳过使用 SQFlite 并使用远程 SQL Server 数据库来代替我的目的?

我觉得很烦人,似乎没有备份 SQFLite 的好选择。我敢肯定,许多应用程序都需要保留数据。

谢谢!

【问题讨论】:

    标签: android flutter backup sqflite


    【解决方案1】:

    您可以通过将 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);
        }
      }
    }
    
    

    【讨论】:

      【解决方案2】:

      从一开始就使用 Firebase 之类的东西。不要将其存储在本地。

      【讨论】:

        猜你喜欢
        • 2014-03-27
        • 2016-06-16
        • 2016-01-15
        • 2017-09-21
        • 2014-12-29
        • 2013-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多