You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的更新。

步骤如下:

  1. 在你的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();
  }
}
  1. 在业务代码中调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:52:29