如何创建Floor数据库单例对象并在多文件中复用?
实现Floor数据库的单例复用
问题描述
我正在为我的应用创建数据库,使用的是Floor数据库。已创建了如下的Entity、Dao和Database类:
@entity class User{ @primaryKey final int id; final String name; final String email; User(this.id, this.name, this.email); } @dao abstract class UserDao { @Query('SELECT * FROM User') Future<List<User>> findAllUsers(); @Query('DELETE FROM User WHERE id = :id') Future<void> deleteUserById(int id); @insert Future<void> insertUser(User user); } @Database(version: 1, entities: [User]) abstract class Appdatabase extends FloorDatabase{ UserDao get userDao; }
我在main.dart文件中通过以下代码创建了数据库实例:
final database = await $FloorAppdatabase.databaseBuilder("MY_DATABASE").build();
可以通过database.userDao().insertUser(user);存储数据,但想要在其他文件中使用该数据库对象,需要将其设置为可复用的单例,该如何实现?
解决方案
方法一:静态类实现线程安全单例
创建专门的数据库管理类,通过双重检查锁确保全局唯一实例:
import 'package:floor/floor.dart'; import 'dart:async'; // 导入你的数据库类和自动生成的代码 import 'app_database.dart'; import 'database.g.dart'; class DatabaseManager { static Appdatabase? _instance; static final _lock = Lock(); // 私有构造函数,禁止外部实例化 DatabaseManager._(); static Future<Appdatabase> getInstance() async { if (_instance == null) { await _lock.synchronized(() async { if (_instance == null) { _instance = await $FloorAppdatabase.databaseBuilder("MY_DATABASE").build(); } }); } return _instance!; } }
使用方式:在任意文件中调用获取实例后使用DAO方法
final db = await DatabaseManager.getInstance(); await db.userDao.insertUser(User(1, "张三", "zhangsan@example.com"));
方法二:全局变量快速实现(适合小型项目)
通过全局变量直接复用初始化后的实例:
- 在单独文件(如
globals.dart)定义全局变量:
import 'app_database.dart'; late Appdatabase globalDatabase;
- 在main.dart中完成初始化:
void main() async { WidgetsFlutterBinding.ensureInitialized(); globalDatabase = await $FloorAppdatabase.databaseBuilder("MY_DATABASE").build(); runApp(MyApp()); }
- 在其他文件直接调用:
await globalDatabase.userDao.insertUser(User(2, "李四", "lisi@example.com"));
注意:这种方式不利于代码解耦和测试,仅适合小型项目快速落地。
方法三:依赖注入管理(推荐中大型项目)
使用依赖注入框架(如get_it)管理单例,提升代码灵活性:
- 添加依赖到pubspec.yaml:
dependencies: get_it: ^7.6.0
- 创建依赖注入初始化文件(如
locator.dart):
import 'package:get_it/get_it.dart'; import 'app_database.dart'; import 'database.g.dart'; final getIt = GetIt.instance; Future<void> setupLocator() async { getIt.registerSingletonAsync<Appdatabase>(() async { return await $FloorAppdatabase.databaseBuilder("MY_DATABASE").build(); }); }
- 在main.dart中初始化:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await setupLocator(); runApp(MyApp()); }
- 在其他文件获取实例:
final db = await getIt.getAsync<Appdatabase>(); await db.userDao.findAllUsers();
内容的提问来源于stack exchange,提问作者sridhar venkatesan
相关产品推荐
相关产品推荐

