如何在SQFlite中插入POJO对象和列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在SQFlite中插入POJO对象和列表相关的知识,希望对你有一定的参考价值。
我正在尝试将API中的数据存储到sqflite
,但是我必须插入Objects和Lists,但是在此过程中,出现此错误:
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 ...]
这是模型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');
我的[[Bloc类别:
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的列表(对于blob,但Uint8List将来可能是唯一受支持的类型),因此强制转换错误可能来自此。在进行其他调查之前,您应尝试对标签(json或逗号分隔的字符串)进行编码。
此问题也适用于author
和category
字段。您必须展平模型。请参阅支持的类型帮助部分:https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md
基本上是int,double,String和Uint8List(blob)是唯一受支持的类型。不幸的是,您必须转换内部的List和Map,json是一种解决方案。
但是我同意所报告的错误无助于发现问题,可以肯定地加以改善...
以上是关于如何在SQFlite中插入POJO对象和列表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SQFLite 或 Moor 库将 JSON 数据存储到颤振中的数据库表中
Bloc 模式不会在屏幕上显示新添加的用户到 sqflite
(更新:如何在 sqflite 中存储 List<String> 数据类型) sqflite 错误:DatabaseException(java.lang.String 无法转换为 jav