0
0
Android-kotlinHow-ToBeginner ยท 4 min read

How to Use Room Database in Android: Simple Guide

To use Room Database in Android, define an Entity class for your data, create a Dao interface with database operations, and build a RoomDatabase abstract class. Then, get an instance of the database and use the DAO to read/write data asynchronously.
๐Ÿ“

Syntax

Entity: Defines a table with fields as columns using @Entity annotation.
Dao: Interface with @Dao annotation containing methods for database actions like insert, query, update.
Database: Abstract class extending RoomDatabase annotated with @Database listing entities and version.

java
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Database;
import androidx.room.RoomDatabase;

@Entity
public class User {
  @PrimaryKey
  public int uid;
  public String name;
}

@Dao
public interface UserDao {
  @Insert
  void insert(User user);

  @Query("SELECT * FROM User WHERE uid = :userId")
  User getUser(int userId);
}

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
  public abstract UserDao userDao();
}
๐Ÿ’ป

Example

This example shows how to create a Room database, insert a user, and fetch it on a background thread using Kotlin and coroutines.

kotlin
import android.content.Context
import androidx.room.*
import kotlinx.coroutines.runBlocking

@Entity
data class User(
  @PrimaryKey val uid: Int,
  val name: String
)

@Dao
interface UserDao {
  @Insert
  suspend fun insert(user: User)

  @Query("SELECT * FROM User WHERE uid = :userId")
  suspend fun getUser(userId: Int): User?
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
  abstract fun userDao(): UserDao
}

fun main() = runBlocking {
  val context: Context = TODO("Provide Android context here")
  val db = Room.databaseBuilder(context, AppDatabase::class.java, "app-db").build()
  val userDao = db.userDao()

  val user = User(1, "Alice")
  userDao.insert(user)

  val fetchedUser = userDao.getUser(1)
  println("Fetched user: ${fetchedUser?.name}")
}
Output
Fetched user: Alice
โš ๏ธ

Common Pitfalls

  • Forgetting to run database operations off the main thread causes app crashes.
  • Not annotating the primary key in the entity leads to errors.
  • Changing the database schema without updating the version and migration causes runtime exceptions.
  • Using blocking calls on the main thread instead of suspend functions or async tasks.
kotlin
/* Wrong: Running DB on main thread (causes crash) */
val user = userDao.getUser(1) // This blocks main thread

/* Right: Use suspend function or background thread */
// Inside coroutine
val user = userDao.getUser(1)
๐Ÿ“Š

Quick Reference

Room Components Cheat Sheet:

ComponentPurposeAnnotation/Usage
EntityDefines a table@Entity with fields and @PrimaryKey
DaoDefines database operations@Dao interface with @Insert, @Query, @Update, @Delete
DatabaseHolds database and serves DAOAbstract class extends RoomDatabase, annotated @Database
BuilderCreates database instanceRoom.databaseBuilder(context, DBClass::class.java, "name")
ThreadingRun DB ops off main threadUse suspend functions, coroutines, or AsyncTask
โœ…

Key Takeaways

Define entities, DAOs, and database class to use Room.
Always run database operations off the main thread to avoid crashes.
Update database version and provide migrations when schema changes.
Use suspend functions or coroutines for asynchronous database access.
Room simplifies SQLite usage with compile-time checks and easy queries.