如何实现嵌套 json 到数据库 SQLite?

Posted

技术标签:

【中文标题】如何实现嵌套 json 到数据库 SQLite?【英文标题】:How to implement nested json to database SQLite? 【发布时间】:2021-06-20 16:09:01 【问题描述】:

我目前正在开发一个包含嵌套类的应用程序,在我没有开始为我的应用程序设置 SQLite 数据库之前,我将嵌套类存储在地图中,但现在我必须使用 Json 格式来存储这些数据。我在下面分享了嵌套类..

    我怎样才能使那些嵌套类 jsonString ?
class CategoryModel
  CategoryModel(
    this.categoryId, this.categoryImagePath, this.categoryName,this.categoryColor,this.subCategoryModels);
  final int categoryColor;
  List<SubCategoryModel> subCategoryModels=[];
  int categoryId;
  String categoryImagePath;
  String categoryName;


class SubCategoryModel 
  SubCategoryModel(
    this.subCategoryId,
    this.subCategoryImagePath,
    this.subCategoryName,
    this.categoryColor,
    this.recipeId,
    List<Ingredient>ingredients,
    this.recipePhotoDir,
    this.recipeTextFromSpeechProcessing,
    this.recordedVoiceDir,
    bool isCompeted);

  final Color categoryColor;
  final double recipeId;
  bool isCompleted;
  int subCategoryId;
  String subCategoryImagePath;
  String subCategoryName;
  List<Ingredient> ingredients = [];
  String recipeTextFromSpeechProcessing;
  String recipePhotoDir;
  String recordedVoiceDir;

class Ingredient
  Ingredient(this.ingredientName,this.dropDownValue, this.ingredientAmount);
  final ingredientName;
  String dropDownValue;
  String ingredientAmount;

  Map<String, dynamic> toMap() 
    return 
      'ingredientName': ingredientName,
      'dropDownValue': dropDownValue,
      'ingredientAmount': ingredientAmount,
    ;
  

2)当用户添加主类别时,只会创建 CategoryModel 对象,那么如何在每个用户步骤中从数据库中获取数据?

最后,我在下面分享一下 DbProvider 类。

class DBProvider 
  DBProvider._();
  static final DBProvider db = DBProvider._();
  static Database _database;

  Future<Database> get database async 
    if (_database != null)
      return _database;

    // if _database is null we instantiate it
    _database = await initDB();
    return _database;
  
  initDB() async 
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "TestDB.db");
    return await openDatabase(path, version: 1, onOpen: (db) 
    , onCreate: (Database db, int version) async 
      await db.execute("CREATE TABLE categoryModels ("
          "Id INTEGER PRIMARY KEY,"
          "Json String TEXT,"
          "categoryImagePath TEXT,"
          "categoryName TEXT"")");
    );
  
  Future<void> insertCategoryModels(CategoryModel categoryModel)async
    final Database db = await database;

    await db.insert('categoryModels', categoryModel.toJson(),conflictAlgorithm: ConflictAlgorithm.replace);
  
  Future<List<CategoryModel>> getCategoryModels() async 
    // Get a reference to the database.
    final Database db = await database;

    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('categoryModels');

    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return List.generate(maps.length, (i) 
      return CategoryModel(
        categoryId: maps[i]['categoryId'],
        categoryColor: maps[i]['categoryColor'],
        categoryImagePath: maps[i]['categoryImagePath'],
        categoryName:  maps[i]['categoryName'],
        subCategoryModels:maps[i]['subCategoryModels']
      );
    );
  
  Future<int> getCategoryModelsLenght()async
    final Database db = await database;
    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('categoryModels');
    return maps.length;
  



【问题讨论】:

【参考方案1】:

SQLite 是关系型数据库管理系统。您期望从 JSON 获得的数据主要是 NoSQL(Key-Value) 类型。如果您期待嵌套 JSON 之类的数据,那么使用 SQFLite 可能只有两种方法。

将嵌套类数据保存为 JSON 字符串并在每次引用对象时解析。 或者您需要创建一个在从表中查询数据时引用这些值的表。像 Category 表具有 id 为 2 的 subCategory。因此,在获取或设置时执行所需的任务来处理所有引用的表。

实际上,如果您要问,我会建议第二种选择。因为数据完整性不会以这种方式丢失。但是你也应该考虑使用 NoSQL 数据库,比如

Hive Sembast

【讨论】:

【参考方案2】:

试试这个flutter插件json_store

【讨论】:

以上是关于如何实现嵌套 json 到数据库 SQLite?的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter的sqlite数据库中保存嵌套的复杂JSON数据

如何迭代sqlite中嵌套json对象中的数组?

遍历嵌套的json对象并将数据保存在android sqlite

使用 Gson 解析后将嵌套的 JSON 数组插入 SQLite

完成sqlite执行参数的字典

如何处理常见的JSON嵌套结构