CPS251 Android Development by Scott Shaper

Building the Database

The Database Class: The Hub of Your Data

Now that we have our Entity and DAO, we can build the Database class. The Database class is the hub of your data. It ties all your Entities and DAOs together. It tells Room what tables exist and how to access them. You only need one Database class for your app.

The Database class ties all your Entities and DAOs together. It tells Room what tables exist and how to access them. You only need one Database class for your app.

Example: NoteDatabase (from RoomDatabaseDemo)


@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
    // Abstract method to provide the Data Access Object (DAO) for notes.
    // Room will generate the implementation for this method.
    abstract fun noteDao(): NoteDao

    // Companion object allows us to define static-like members and methods for the database.
    companion object {
        // The @Volatile annotation ensures that changes to the INSTANCE variable are immediately
        // visible to all threads. This is crucial for thread-safe singleton implementation.
        @Volatile
        private var INSTANCE: NoteDatabase? = null

        // Provides a singleton instance of the NoteDatabase.
        // If INSTANCE is null, it creates the database in a synchronized block to prevent multiple instances.
        fun getDatabase(context: Context): NoteDatabase {
            return INSTANCE ?: synchronized(this) {
                // Create database here if INSTANCE is null.
                val instance = Room.databaseBuilder(
                    context.applicationContext, // Application context to prevent memory leaks.
                    NoteDatabase::class.java,
                    "notes_db" // The name of the database file.
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

Understanding the `NoteDatabase` Class

This section explains the core components of your Room Database implementation. The `NoteDatabase` class serves as the central hub for your database operations, bringing together your data entities and data access objects (DAOs).

1. Database Annotation and Class Definition


@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
    // ...
}

Here's what each part means:

2. Data Access Object (DAO) Declaration


    abstract fun noteDao(): NoteDao

3. Singleton Pattern for Database Instance


    companion object {
        @Volatile
        private var INSTANCE: NoteDatabase? = null

        fun getDatabase(context: Context): NoteDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    NoteDatabase::class.java,
                    "notes_db"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }

This `companion object` block implements the Singleton pattern, which is a design pattern that ensures only one instance of a class exists throughout your application. For a database, this is crucial to prevent multiple connections and potential data inconsistencies.

Tips for Success

Common Mistakes to Avoid

Best Practices