Flutter Floor数据库问题:执行DELETE操作后返回Stream的SELECT *查询未触发更新
解决Floor包删除数据后Stream不更新的问题
我之前也踩过Floor的这个小坑!问题核心在于:Floor的响应式Stream依赖数据库的变更通知,但自定义的@Query删除操作并不会自动触发这个通知——而Floor自带的注解式操作会帮你做这件事。下面给你几个可行的解决方案:
方案1:改用Floor的@Delete注解替代自定义SQL
这是最省心的方法,因为Floor的@Delete、@Insert、@Update注解内部会自动触发数据库监听通知,让关联的Stream自动刷新。
修改你的Dao方法:
// 替换原来的自定义DELETE查询 @Delete() Future<void> deleteCar(Car car);
使用时,你需要先获取到要删除的Car实例(可以通过ID先查询出来),再调用这个方法。删除完成后,getAllCars()的Stream会自动收到新的数据集。
方案2:手动触发数据库变更通知(适合必须用自定义SQL的场景)
如果你因为业务需求必须用@Query('DELETE FROM Car WHERE Id=:id')这种方式删除,那可以在删除操作后手动调用Floor数据库的notifyListeners()方法,强制触发所有监听Stream的更新。
步骤如下:
- 在你的Dao类中注入数据库实例:
import 'package:floor/floor.dart'; @dao abstract class CarDao { final AppDatabase _database; // 通过构造函数注入数据库 CarDao(this._database); // 你的自定义删除方法 @Query('DELETE FROM Car WHERE Id=:id') Future<void> deleteById(int id); // 封装一个删除+通知的方法 Future<void> deleteByIdAndNotify(int id) async { await deleteById(id); // 手动触发通知 _database.notifyListeners(); } }
- 在业务代码中调用
deleteByIdAndNotify(id)替代原来的deleteById(id),这样删除完成后,getAllCars()的Stream就会自动刷新了。
方案3:确认UI层的Stream监听是否正确
最后再检查一下你的UI层是不是正确绑定了Stream:
StreamBuilder<List<Car>?>( // 确保这里用的是getAllCars()返回的Stream,而不是Future stream: carDao.getAllCars(), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) => ListTile( title: Text(snapshot.data![index].name), ), ); } return const CircularProgressIndicator(); }, )
要注意,不能把getAllCars()转换成Future来用,必须直接绑定Stream才能实时响应数据库变化。
内容的提问来源于stack exchange,提问作者Mena
相关产品推荐
相关产品推荐

