Best Premium Templates For App and Software Downloading Site. Made By HIVE-Store

Android Jetpack Compose

Stay ahead with the latest tools, trends, and best practices in Android Jetpack Compose App development

Room Database in Jetpack Compose

Room Database in Jetpack Compose - Coding Bihar
Room Database in Jetpack Compose

🏠 Room Database in Jetpack Compose — Full Practical Guide (2025)

If you’re learning Android development with Jetpack Compose, one of the most important things you’ll need is a local data storage system that works even without the internet.

That’s where Room Database comes in — a powerful, efficient, and Kotlin-friendly way to manage local structured data built on top of SQLite.


🧩 What is Room Database?

Room is an object-mapping layer over SQLite. It converts Kotlin data classes into database tables and vice versa — making data persistence simple and type-safe.

In simple terms: Room = SQLite made easy + Kotlin-friendly + lifecycle-aware.

✅ Common Use-Cases:

  • Notes or To-Do apps
  • Offline caching (store API data locally)
  • User preferences or game scores
  • Saving login info or user history

🧠 Why Use Room Instead of SQLite?

Before Room, developers used raw SQL queries and SQLiteOpenHelper classes, which were:

  • Hard to maintain
  • Error-prone
  • Not type-safe

Room solves these issues by offering:

  • Compile-time verification of SQL queries
  • Automatic mapping between Kotlin objects and tables
  • Integration with Coroutines, Flow, LiveData, ViewModel
  • Much less boilerplate code

🧱 Core Components of Room Database (Theory)

Room follows MVVM + Repository architecture. It has three key components:

ComponentDescription
EntityDefines the structure of the database table.
DAOData Access Object — defines SQL operations like insert, delete, query.
DatabaseMain class that connects Entities and DAOs.

1️⃣ Entity — Defining the Table

@Entity(tableName = "notes")
data class NoteEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val title: String,
    val content: String
)
Explanation:
@Entity → Marks the data class as a table.
@PrimaryKey(autoGenerate = true) → Auto-increment ID.
Each property → A column in the table.

2️⃣ DAO — Data Access Object

@Dao
interface NoteDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(note: NoteEntity)

    @Query("SELECT * FROM notes ORDER BY id DESC")
    fun getAllNotes(): Flow<List<NoteEntity>>

    @Delete
    suspend fun delete(note: NoteEntity)
}
Explanation:
@Insert → Add data.
@Query → Fetch data with SQL.
@Delete → Remove specific note.
Flow<List<NoteEntity>> → Real-time data updates for Compose.

3️⃣ Database — Connecting Everything

@Database(entities = [NoteEntity::class], version = 1)
abstract class NoteDatabase : RoomDatabase() {
    abstract fun noteDao(): NoteDao

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

        fun getInstance(context: Context): NoteDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    NoteDatabase::class.java,
                    "note_db"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}
Explanation:
@Database defines entities & version.
Singleton pattern ensures one database instance.
Room.databaseBuilder() creates the DB.

🧰 Repository Layer (Clean Architecture)

class NoteRepository(private val dao: NoteDao) {
    val allNotes = dao.getAllNotes()
    suspend fun insert(note: NoteEntity) = dao.insert(note)
    suspend fun delete(note: NoteEntity) = dao.delete(note)
}

This layer manages all data operations and ensures your app remains scalable.


🧠 ViewModel Integration

class NoteViewModel(application: Application) : AndroidViewModel(application) {

    private val dao = NoteDatabase.getInstance(application).noteDao()
    private val repository = NoteRepository(dao)

    val notes = repository.allNotes.asLiveData()

    fun addNote(title: String, content: String) {
        viewModelScope.launch {
            repository.insert(NoteEntity(title = title, content = content))
        }
    }

    fun delete(note: NoteEntity) {
        viewModelScope.launch {
            repository.delete(note)
        }
    }
}
Key Points:
viewModelScope.launch → Background thread for safe DB ops.
asLiveData() → Converts Flow to LiveData.
ViewModel survives configuration changes.

🎨 Jetpack Compose UI (Practical Implementation)

@Composable
fun NotesScreen(viewModel: NoteViewModel = viewModel()) {
    val notes by viewModel.notes.observeAsState(emptyList())
    var title by remember { mutableStateOf("") }
    var content by remember { mutableStateOf("") }

    Column(Modifier.padding(16.dp)) {
        Text("Room Database Demo", style = MaterialTheme.typography.headlineMedium)
        Spacer(Modifier.height(8.dp))

        OutlinedTextField(value = title, onValueChange = { title = it }, label = { Text("Title") })
        OutlinedTextField(value = content, onValueChange = { content = it }, label = { Text("Content") })

        Button(onClick = {
            if (title.isNotBlank() && content.isNotBlank()) {
                viewModel.addNote(title, content)
                title = ""
                content = ""
            }
        }, modifier = Modifier.padding(top = 8.dp)) {
            Text("Add Note")
        }

        Spacer(Modifier.height(16.dp))

        LazyColumn {
            items(notes) { note ->
                Card(Modifier.fillMaxWidth().padding(vertical = 4.dp)) {
                    Column(Modifier.padding(8.dp)) {
                        Text(note.title, style = MaterialTheme.typography.titleMedium)
                        Text(note.content, style = MaterialTheme.typography.bodyMedium)
                        TextButton(onClick = { viewModel.delete(note) }) {
                            Text("Delete")
                        }
                    }
                }
            }
        }
    }
}

✅ How it works:

  • User adds a note → stored in Room DB
  • Flow emits updated data automatically
  • Compose UI refreshes instantly

🔄 Full Data Flow Diagram

User Input → Compose UI → ViewModel → Repository → Room DAO → SQLite Table
                                            ↑
                                            | (Flow)
                                            └─── Real-time updates back to UI

⚡ Advanced Topics (Deep Knowledge)

  • TypeConverters — store complex data like lists or dates.
  • Migrations — handle DB structure changes safely.
  • Room + Retrofit — cache API responses locally.
  • Testing — use in-memory DB for unit testing.
  • Coroutines & Flow — real-time updates without manual refresh.

🧠 Summary Table

LayerRoleExample
EntityDefines table structureNoteEntity
DAODatabase operationsNoteDao
DatabaseRoom instanceNoteDatabase
RepositoryManages data accessNoteRepository
ViewModelHolds UI dataNoteViewModel
Compose UIDisplays dataNotesScreen

🏁 Final Thoughts

Room Database is essential for modern Android apps — not just for saving data, but for creating stable, offline-capable, and reactive apps.

Combined with Jetpack Compose, Coroutines, and Flow, it gives you a clean, scalable, and future-proof architecture.

Once you master this, you can build full-fledged apps like:

  • 📝 Notes or To-Do apps
  • 💰 Expense trackers
  • 📶 Offline caching systems

Build. Learn. Repeat. You’re now ready to create your first offline-ready app using Room + Jetpack Compose 🎯

 Sandeep Kumar

Posted by Sandeep Kumar

Please share your feedback us at:sandeep@codingbihar.com. Thank you for being a part of our community!

Special Message

You Can Show Anything To Your Users