databaseflutterfloor

How to create singleton database object and utilise in different files?


I want to create the database for my app and I'm using floor database. I have created entity, dao and database class like below.

@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;
}

and I have created a database with name in my main.dart file like below.

 final database = await $FloorAppdatabase.databaseBuilder("MY_DATABASE").build();

I can store the data like this database.userDao().insertUser(user); But If i want to use database object in other file then I have to create it as a common one. Can someone help me how to create it as a common file and I can use it anywhere I want?


Solution

  • You can create a singleton class like the one below.

    class DatabaseHelper {
      static final DatabaseHelper instance = DatabaseHelper._internal();
    
      DatabaseHelper._internal();
    
      late final AppDatabase database;
    
      Future<void> initializeDatabase() async {
        database = await $FloorAppDatabase.databaseBuilder("MY_DATABASE").build();
      }
    }
    

    you initialize the database it in the main

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await DatabaseHelper.instance.initializeDatabase();
    
      runApp(const MyApp());
    }
    

    And later, you can call it from anywhere using:

    final database = DatabaseHelper.instance.database;
    final user = User(1, 'Test', 'test@example.com');
    database.userDao.insertUser(user);
    

    or you can use the get_it package, you initialize the database with get_it like:

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      GetIt.I.registerSingletonAsync<AppDatabase>(() async {
        return $FloorAppDatabase.databaseBuilder("MY_DATABASE").build();
      });
      await GetIt.I.allReady();
    
      runApp(const MyApp());
    }
    

    And later, you can call it from anywhere using:

    final database = GetIt.instance<AppDatabase>();
    final user = User(4, 'John Doe', 'john.doe@example.com');
    database.userDao.insertUser(user);