Flutter Sqflite:如何按条件筛选数据并展示至ListView
解决Sqflite按bodyPart筛选数据并展示到ListView的问题
问题核心
你当前无法通过bodyPart字段筛选数据,主要原因包括:模型类缺失bodyPart字段、筛选方法存在未定义变量和SQL拼接风险、未正确传入筛选参数。以下是分步修复方案:
1. 完善模型类,补充bodyPart字段
原模型类未包含bodyPart字段,导致从数据库读取数据时无法映射该字段,修正后:
class UserInputModel { int? id; String? content; String? bodyPart; UserInputModel({ this.id, required this.content, this.bodyPart, }); Map<String, dynamic> toMap() { var map = <String,dynamic> {}; map['id'] = id; map['content'] = content; map['bodyPart'] = bodyPart; return map; } factory UserInputModel.fromMap(Map<String, dynamic> map) => UserInputModel( id: map['id'], content: map['content'], bodyPart: map['bodyPart'], ); }
2. 修复数据库筛选方法,使用参数化查询
原fetchDesiredData方法存在未定义变量和SQL注入风险,改用sqflite的query方法实现安全筛选:
// 替换数据库助手类中的fetchDesiredData方法 static Future<List<UserInputModel>> fetchDesiredData(String targetBodyPart) async { final db = await MeasurementsDBHelper.db(); final result = await db.query( tableName, where: "$columnBodyPart = ?", whereArgs: [targetBodyPart], // 参数化查询自动处理字符串格式,避免类型不匹配 orderBy: "$columnId DESC", ); return result.map((map) => UserInputModel.fromMap(map)).toList(); }
3. 页面调用筛选方法并展示ListView
以"手臂"页面为例,实现对应bodyPart的数据加载和展示:
class ArmMeasurementsPage extends StatefulWidget { const ArmMeasurementsPage({super.key}); @override State<ArmMeasurementsPage> createState() => _ArmMeasurementsPageState(); } class _ArmMeasurementsPageState extends State<ArmMeasurementsPage> { List<UserInputModel> _filteredData = []; @override void initState() { super.initState(); _loadFilteredMeasurements(); } Future<void> _loadFilteredMeasurements() async { // 传入当前页面对应的bodyPart值,比如"手臂" final data = await MeasurementsDBHelper.fetchDesiredData("手臂"); setState(() { _filteredData = data; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("手臂测量记录")), body: ListView.builder( itemCount: _filteredData.length, itemBuilder: (context, index) { final item = _filteredData[index]; return ListTile( title: Text(item.content ?? ""), subtitle: Text(item.bodyPart ?? ""), trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () async { if (item.id != null) { await MeasurementsDBHelper.deleteMeasurement(item.id!); _loadFilteredMeasurements(); // 删除后刷新列表 } }, ), ); }, ), ); } }
4. 排查注意事项
- 确保插入数据时的bodyPart值与筛选时传入的完全一致(注意大小写、空格等细节)
- 可使用数据库查看工具(如SQLiteStudio)确认数据库中bodyPart字段的实际存储值
- 始终使用参数化查询(whereArgs),避免直接拼接SQL语句,防止注入风险和类型不匹配问题
内容的提问来源于stack exchange,提问作者user22187566
相关产品推荐
相关产品推荐

