Room in Practice: Compile-Time SQL Checks and a Full CRUD Notes Database for Android
Runtime 'table not found' and column-name crashes move to compile time, and a stable repository boundary keeps persistence swaps invisible to the UI. Room is the default persistence recommendation for modern Android, and this migration path is the one most production notes-style apps take.
Room replaces hand-written SQLite helpers, cursor parsing, and string-concatenated SQL with an annotation-driven layer. @Entity marks a Kotlin data class as a table, @Dao declares the operations, and @Database owns the connection and exposes DAO instances. SQL syntax, table names, field names, and return types are validated during compilation, so a typo in a query fails the build instead of crashing at runtime.
The notes-database example puts those pieces to work. A Note entity uses an auto-generated primary key and a custom table name; its DAO provides insert, update, delete, ordered list, find-by-id, and clear-all operations. Suspend functions let Room run database work off the main thread. The AppDatabase is a thread-safe singleton built with Application Context, and TypeConverters bridge Date and List<String> values to SQLite-supported types.
The repository layer swaps in-memory data for Room while keeping method signatures stable, so ViewModel and UI code stay untouched. Conflict strategies, compile-time validation compared with raw SQLite failure modes, and setup traps such as missing kapt or Activity Context make up the rest of the material.
Compile-time SQL validation is the strongest practical reason to use Room: the comparison table shows raw SQLite only reports errors at runtime, while Room catches them during the build.
The zero-change repository swap demonstrates the real value of layered architecture; ViewModel and UI code did not need to know that data storage moved from memory to a database.
Room keeps developers writing SQL instead of hiding it behind a fully abstracted ORM; @Query methods take hand-written SQL, so database control stays visible while tooling catches mistakes.
DAOs designed around suspend functions push thread handling into Room's coroutine integration, removing a common source of main-thread bugs without extra code.
Deleting a note by its primary key is more reliable.