11

我正在查看此(https://github.com/tekartik/sqflite/blob/master/doc/opening_asset_db.md)来填充已格式化且应用程序需要的数据,仅用于读取功能。

因此,当我们已经拥有外部 CSV 文件中的所有信息时,我对创建 SQLite 数据库的理解是,在我的应用程序的 .dart 文件中创建类模型,例如

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 文件,其中包含所有用户信息(其值对应于用户类),我是否可以使用数据库资产来填写信息,然后在颤振应用程序中调用它? 我意识到可能有很多方法可以解决这个问题,但是 .db 文件究竟是什么存储的,它的格式如何?我可以在这个 .db 文件中实现一个 .csv 文件吗?

4

4 回答 4

35

首先,您需要从 csv 构建一个 sqlite 数据库。这可以通过以下方式完成:

  1. 创建必要的表(users.sql)

    CREATE TABLE users(
       firstname TEXT NOT NULL,
       lastname TEXT NOT NULL,
       dob TEXT NOT NULL
    );
    
  2. 创建sqlite数据库

    sqlite3 database.db < users.sql
    
  3. 插入 csv 数据

    sqlite3 database.db
    .mode csv
    .import data.csv users
    
  4. 将 database.db 放入您的资产并将其添加到 pubspec.yaml 中。

    flutter:
      # ...
      assets:
        - assets/database.db
    
  5. 在您的应用程序中,您必须将资产文件复制到“文档”中。这有点复杂。

    // 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);
    }
    
  6. 最后,您可以像这样访问数据库。

    Directory appDocDir = await getApplicationDocumentsDirectory();
    String databasePath = join(appDocDir.path, 'asset_database.db');
    this.db = await openDatabase(databasePath);
    initialized = true;
    
  7. 示例查询(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);
    }
    
于 2018-07-17T18:20:05.623 回答
1

在项目根目录的文件系统中添加资产。创建一个资产文件夹并将您的 db 文件放入其中:

assets/examples.db

在颤振部分的 pubspec.yaml 中指定资产

flutter:

  assets:

    - assets/example.db

然后你需要打开数据库,如果它存在,或者复制,如果它不存在。

此处的链接显示了打开/复制预先存在的 sqlite 数据库的代码:

https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md

于 2020-04-07T16:42:32.640 回答
1

此 .db 文件用于在其中保存 SQL 数据。因此您可以使用 SQL 命令保存和获取数据。插件本身将解析 .db 文件中的数据。

如果要将数据保存为 CSV 并在类中解析,最好将数据存储在原始文件中(在此处查找保存文件)或使用此插件。虽然,还有一些其他方法可以将数据保存为 JSON 文件或将其保存在键值对中。

于 2018-07-17T15:17:05.477 回答
0

我使用此功能从资产文件夹复制数据库

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');
    }
  }
于 2022-01-05T10:36:50.003 回答