Open In App

Introduction to Room Persistent Library in Android

Last Updated : 23 Jan, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Room is a persistence library for Android that is part of Google’s Android Jetpack project. According to the documentation, Room acts as an abstraction layer over SQLite, allowing for fluent database access while leveraging SQLite’s full power. Apps that deal with a large amount of structured data can benefit greatly from storing it locally. The most common application is to cache relevant data. As a result, even if the device is unable to connect to the network, the user can still access the content while offline. After the device is brought back online, any user-initiated content changes are synced to the server.

Making More Space in Your Project

In your module’s (app’s) build.gradle file, include the following:

dependencies {
  implementation "androidx.room:room-runtime:2.2.5"
  kapt "androidx.room:room-compiler:2.2.5"
}

Benefits of Using Room

There are several advantages to using Room over other alternatives such as SQLiteOpenHelper:

  1. Queries are validated at compile time.
  2. Cuts down on boilerplate code.
  3. Simple to grasp and apply.
  4. Integration with RxJava, LiveData, and Kotlin Coroutines is simple.

Room Components

Room is made up of three major components:

  1. Database: This contains the database holder and serves as the primary access point for your app’s persisted, relational data.
  2. Entity: A table in the database that is represented by an entity.
  3. DAO: This class contains the methods for accessing the database.

The Room database is used by your application to retrieve the data access objects, or DAOs, associated with your database. Each DAO is then used by the app to retrieve entities from the database and save any changes to those entities back to the database. Finally, the app makes use of an entity to retrieve and set values corresponding to table columns in the database.

Database

As previously stated, it contains the database holder and serves as the primary access point for the underlying connection to the persisted, relational data in your app. The class annotated with @Database must meet the following requirements:

  1. Extend RoomDatabase with an abstract class.
  2. Within the annotation, include a list of the entities associated with the database.
  3. Contain an abstract method with no arguments that returns the class annotated with @Dao.
@Database(entities = arrayOf(User::class), version = 1)
abstract class courseDB: RoomDatabase() {
  abstract fun courseName(): courseDB
}

GeekTip: When instantiating a RoomDatabase object, you should use the singleton design pattern if your app runs in a single process. Each RoomDatabase instance is reasonably priced, and you rarely require access to multiple instances within a single process.

Entity

A table in a database is represented by an Entity. This class is marked with the @Entity annotation. This class’s data members represent the columns in a table. An entity’s fields must all be public or have getter and setter methods. If all fields are accessible, the entity class should have an empty function Object() { [native code] } or a parameterized function Object() { [native code] } that takes all fields. Partial constructors can also be used in Room. At least one primary key is required for each entity class. To define a single field’s primary key, use the @PrimaryKey annotation, or the primaryKeys attribute of the @Entity annotation for multiple fields. You can also use the @PrimaryKey annotation’s autoGenerate property to assign primary keys automatically.

@Entity
data class User(
  @PrimaryKey val uid: Int,
  @ColumnInfo(name = "courseName") val firstName: String?,
  @ColumnInfo(name = "courseHolder") val lastName: String?
)

To add indices to an entity, use the @Entity annotation’s indices property. You can also create unique indices by setting the @Index annotation’s unique property to true.

@Entity(indices = arrayOf(Index(value = ["courseHolder", "address"])))@Entity(indices = arrayOf(Index(value = ["courseName", "courseHolder"],
        unique = true)))

Data Access Object (DAO)

DAOs provide an API for interacting with the database. This is an interface that has the @Dao annotation. This interface’s methods are all used to retrieve data from the database or to make changes to the database. Annotations such as @Query, @Insert, and @Delete are used to identify these methods.

@Dao
interface courseDAO{
  @Query("SELECT * FROM course")
  fun getAll(): List<GFG>
  
  @Query("SELECT * FROM course WHERE uid IN (:userIds)")
  fun loadAllByIds(userIds: IntArray): List<GFG>
  
  @Insert
  fun insertAll(vararg courses: User)
  
  @Delete
  fun delete(course: Courses)
}

Converting Types

You may need to persist a custom data type in a single database column on occasion. Type converters can be useful in these situations.

class GFG {
  @TypeConverter
  fun fromTimestamp(value: Long?): Date? {
  return value?.let { Date(it) }
  }

  @TypeConverter
  fun dateToTimestamp(date: Date?): Long? {
  return date?.time?.toLong()
  }
}

Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads