Flutter中使用sqflite创建数据表的数据类型适配问题
解决sqflite存储电影数据的字段问题
核心问题分析
你遇到的三个字段存储失败问题,根源在Model类命名错误、SQLite不支持原生数组类型以及部分字段的序列化/反序列化逻辑缺失:
genre_ids是数组类型,但SQLite没有原生数组字段,直接存储List会失败- Model类的构造函数名与类名不匹配,导致数据解析异常
vote_average的类型处理不够严谨,存在潜在类型转换问题
修复步骤及代码修改
1. 修正Model类的构造函数名称与字段处理逻辑
原Model类名为Movies,但构造函数用了PopularMovies,会导致实例化时无法正确映射数据,同时补充数组和浮点类型的序列化/反序列化逻辑:
class Movies { int? id; String? title; String? overview; List<int>? genreIds; double? voteAverage; // 替换dynamic为double,匹配API返回的浮点类型 String? posterPath; // 统一构造函数名称为Movies Movies({ this.id, this.title, this.overview, this.genreIds, this.voteAverage, this.posterPath, }); // 修正工厂构造函数名称,补充数组和浮点类型解析逻辑 Movies.fromJson(Map<String, dynamic> json) { id = json['id']; title = json['title']; overview = json['overview']; // 安全解析genre_ids数组 genreIds = json['genre_ids'] != null ? List<int>.from(json['genre_ids']) : []; // 确保vote_average转为double类型 voteAverage = (json['vote_average'] as num?)?.toDouble(); posterPath = json['poster_path']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = {}; data['id'] = id; data['title'] = title; data['overview'] = overview; data['vote_average'] = voteAverage; // 将数组转为JSON字符串,适配SQLite的TEXT字段 data['genre_ids'] = genreIds != null ? jsonEncode(genreIds) : null; data['poster_path'] = posterPath; return data; } }
2. 修改建表语句,适配数组的字符串存储
把genre_ids的字段类型改为TEXT,用来存储序列化后的JSON字符串:
// 创建数据库和Movies表 initDB() async { Directory documentsDirectory = await getApplicationDocumentsDirectory(); final path = join(documentsDirectory.path, 'movies.db'); return await openDatabase(path, version: 1, onOpen: (db) {}, onCreate: (Database db, int version) async { await db.execute('CREATE TABLE Movies(' 'id INTEGER PRIMARY KEY,' 'title TEXT,' 'overview TEXT,' 'vote_average REAL,' 'poster_path TEXT,' 'genre_ids TEXT' // 改为TEXT类型,存储JSON字符串 ')'); }); }
3. 读取数据时解析genre_ids字符串
从数据库读取数据时,需要把存储的JSON字符串转回List
// 示例:从数据库读取单条电影数据 Future<Movies?> getMovie(int id) async { final db = await initDB(); final maps = await db.query('Movies', where: 'id = ?', whereArgs: [id]); if (maps.isNotEmpty) { var movieMap = maps.first; // 解析genre_ids的JSON字符串为数组 if (movieMap['genre_ids'] != null) { movieMap['genre_ids'] = List<int>.from(jsonDecode(movieMap['genre_ids'])); } return Movies.fromJson(movieMap); } return null; }
验证要点
- 存储数据时必须调用
toJson()将数据转为Map,确保genre_ids被序列化为JSON字符串 - 读取数据时必须将
genre_ids的字符串反序列化为List vote_average统一使用double类型,避免dynamic带来的类型不确定问题
内容的提问来源于stack exchange,提问作者GrandMagus
相关产品推荐
相关产品推荐

