我正在尝试将API中的数据存储到sqflite中,但是我必须插入对象列表,但是在此过程中,出现此错误:

ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: DatabaseException(java.lang.String cannot be cast to java.lang.Integer) sql 'INSERT INTO articleTable (id, created_on, title, summary, details, tags, featured_image, author, category) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' args [21, 2020-04-14 04:04:57, Singer Jose ...}]

这是Model Article类:
@JsonSerializable(explicitToJson: true)
class Article {
  Article(this.id, this.created_on, this.title, this.details,
      this.featured_image, this.author, this.category, this.summary, this.tags);

  int id;
  String created_on;
  String title;
  String summary;
  String details;
  List<String> tags;
  String featured_image;
  Author author;
  Category category;

  factory Article.fromJson(Map<String, dynamic> json) =>
      _$ArticleFromJson(json);

  Map<String, dynamic> toJson() => _$ArticleToJson(this);
}
Article模型类的自动生成的文件:
/ GENERATED CODE - DO NOT MODIFY BY HAND

part of 'article.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Article _$ArticleFromJson(Map<String, dynamic> json) {
  return Article(
    json['id'] as int,
    json['created_on'] as String,
    json['title'] as String,
    json['details'] as String,
    json['featured_image'] as String,
    json['author'] == null
        ? null
        : Author.fromJson(json['author'] as Map<String, dynamic>),
    json['category'] == null
        ? null
        : Category.fromJson(json['category'] as Map<String, dynamic>),
    json['summary'] as String,
    (json['tags'] as List)?.map((e) => e as String)?.toList(),
  );
}

Map<String, dynamic> _$ArticleToJson(Article instance) => <String, dynamic>{
      'id': instance.id,
      'created_on': instance.created_on,
      'title': instance.title,
      'summary': instance.summary,
      'details': instance.details,
      'tags': instance.tags,
      'featured_image': instance.featured_image,
      'author': instance.author?.toJson(),
      'category': instance.category?.toJson(),
    };

这是我在做Sqflite插入的地方:
class ArticleApiProvider {
  Future<List<Article>> fetchArticles() async {
    final response =
        await http.get('https://api.xyxyxyxy');

    if (response.statusCode == 200) {
      List jsonResponse = jsonDecode(response.body);
      return jsonResponse.map((article) {
        articleBloc.addArticles(Article.fromJson(article));
      }).toList();
    } else {
      throw Exception('Failed to retrieve articles');
    }
  }
}

我的集团类别:
class ArticleBloc {
  final _repository = Repository();
  final _articleFetcher = PublishSubject<List<Article>>();

  Stream<List<Article>> get allArticles => _articleFetcher.stream;

  fetchArticles() async {
    List<Article> articles = await _repository.fetchArticles();
    _articleFetcher.sink.add(articles);
  }

   getArticlesCached() async {
    // sink is a way of adding data reactively to the stream
    // by registering a new event

    _articleFetcher.sink.add(await _repository.getAllArticles());
  }

   void addArticles(Article article) async {
    await _repository.insertArticle(article);
  }

  dispose() {
    _articleFetcher.close();
  }
}

final articleBloc = ArticleBloc();

这是 DatabaseProvider的
final articlesTable = "articleTable";

class DatabaseProvider {
  static final DatabaseProvider dbProvider = DatabaseProvider();
   Database _database;

  String id = "id";
  String createdOn = "created_on";
  String title = "title";
  String summary = "summary";
  String details = "details";
  String featuredImage = "featured_image";
  String author = "author";
  String category = "category";
  String tags = "tags";

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

  createDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();

    // NewVision.db is our database instance name
    String path = join(documentsDirectory.path, "NewVision.db");

    var database = await openDatabase(path,
        version: 1, onCreate: initDB, onUpgrade: onUpgrade);

    return database;
  }

  void initDB(Database db, int version) async {
    await db.execute(
        'CREATE TABLE $articlesTable($id INTEGER PRIMARY KEY AUTOINCREMENT, $createdOn TEXT,  $title TEXT ,'
        ' $summary TEXT , $details TEXT , '
        '$tags TEXT,  $featuredImage TEXT , $author TEXT , $category TEXT )');
  }

  void onUpgrade(Database db, int oldVersion, int newVersion) {
    if (newVersion > oldVersion) {}
  }
}

String join(String path, String s) {
  return path + s;
}

其余文件的确遵循Bloc架构,为了使问题更精确,我认为从我提供的内容中可以得到一些帮助。

感谢您的帮助。

最佳答案

感谢您提供详细的报告。我的假设是错误来自您的tags属性。 SQLite不支持字符串列表。由于兼容性原因,sqflite支持int的List(对于blob,但将来Uint8List可能是唯一受支持的类型),因此强制转换错误可能来自此。

在进行其他调查之前,您应该尝试对标签(json或逗号分隔的字符串)进行编码。

此问题也适用于authorcategory字段。
您必须展平模型。请参阅支持的类型帮助部分:https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md

基本上仅支持int,double,String和Uint8List(blob)类型。不幸的是,您必须转换内部的List和Map,json是一种解决方案。

但我同意所报告的错误无助于发现问题,可以肯定地加以改善。

关于sqlite - 如何在SQFlite中插入POJO对象和列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61415933/

10-10 20:16