Room Database in jetpack compose

harsh shah
4 min readAug 2, 2022

The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. In particular, Room provides the following benefits:

  • Compile-time verification of SQL queries.
  • Convenience annotations that minimize repetitive and error-prone boilerplate code.
  • Streamlined database migration paths.

Why we use room database

  • Database object into java object without boilerplate code
  • The room provides compiler time query verification, which will reduce error and smooth connection between database and java object
  • It also provides an annotation to perform any query option rather than writing raw queries

Components for room database

There are three major components in Room:

  • The database class holds the database and serves as the main access point for the underlying connection to your app’s persisted data.
  • Data entities that represent tables in your app’s database.
  • Data access objects (DAOs) that provide methods that your app can use to query, update, insert, and delete data in the database.

The database class provides your app with instances of the DAOs associated with that database. In turn, the app can use the DAOs to retrieve data from the database as instances of the associated data entity objects. The app can also use the defined data entities to update rows from the corresponding tables, or to create new rows for insertion

DataEntity

  • Represent a table within a database. create a table for each class that has @entity annotation
@Entity(tableName = "user")
class UserModel {

@PrimaryKey(autoGenerate = true)
@NonNull
@ColumnInfo(name = "userId")
var id: Int = 0

@ColumnInfo(name = "name")
var name: String = ""
}

Data access object (DAO)

  • UserDao provides the methods that the rest of the app uses to interact with data in the user table.
@Dao
interface UserDao{

@Query("SELECT * From user")
fun fetchAllUsers() : LiveData<List<UserModel>>

@Insert()
fun insertUser(user: UserModel)

@Query("DELETE FROM user where userId = :id")
fun deleteCustomerById(id: Int)

@Query("DELETE FROM user")
fun deleteAllCustomer()
}

Database

  • AppDatabase defines the database configuration and serves as the app's main access point to the persisted data
@Database(entities = [UserModel::class], version = 1, exportSchema = true)
abstract class AppDataBase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object{
private var INSTANCE:AppDataBase? = null

fun getDatabase(context:Context):AppDataBase{
synchronized(this){
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
AppDataBase::class.java,
"userDatabase"
).fallbackToDestructiveMigration()
.build()

INSTANCE = instance
}
return instance
}
}
}
}

Managing Data

class UserViewModel(application: Application) : ViewModel() {

private val userRepository:UserRepository

init {
val userDB = AppDataBase.getDatabase(application)
val userDao = userDB.userDao()
userRepository = UserRepository(userDao)
}

fun fetchAllUsers() : LiveData<List<UserModel>>{
return userRepository.fetchAllUsers
}

fun insertUser(user: UserModel){
viewModelScope.launch(Dispatchers.IO) {
userRepository.insertUser(user = user)
}
}

fun deleteUserById(id: Int) {
viewModelScope.launch {
userRepository.deleteCustomerById(id = id)
}
}
}
class UserRepository(private val userDao:UserDao) {

val fetchAllUsers: LiveData<List<UserModel>> = userDao.fetchAllUsers()

fun insertUser(user: UserModel) {
userDao.insertUser(user)
}

fun deleteCustomerById(id: Int) {
userDao.deleteCustomerById(id)
}

fun deleteAllCustomer() {
userDao.deleteAllCustomer()
}
}

Insert Quey

userViewModel.insertUser(
UserModel(
name = name,
gender = "Male",
emailId = "abc@gmail.com"
),
)

Get All Query

Get All fetch users from the list and shows UI

val userList = userViewModel.fetchAllUsers().observeAsState(arrayListOf())Box(modifier = Modifier
.fillMaxSize()
.padding(bottom = 50.dp)) {
Row(modifier = Modifier
.fillMaxSize(fraction = 1f)
.background(color = Color.White)
.align(Alignment.TopEnd)) {
LazyColumn(content = {
items(
items = userList.value,
itemContent = {
Card(
content = {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
content = {
Box(
content = {
Text(
text = it.name,
color = Color.Black,
)
}
)
}
)
}
)
}
)
})
}
Row(modifier = Modifier
.size(width = 100.dp, height = 80.dp)
.align(Alignment.BottomEnd)) {
ExtendedFloatingActionButton(text = {
Text(text = "User", color = Color.White)
}, onClick = {
val name = UUID.randomUUID().toString()
userViewModel.insertUser(
UserModel(
name = name,
gender = "Male",
emailId = "abc@gmail.com"
),
)
})
}
}

Here is an output :-

If you facing “Inheritance from an interface with ‘@JvmDefault’ members is only allowed with -Xjvm-default option” while run the app

add this line inside android in module gradle.file

kotlinOptions{
freeCompilerArgs += [
"-Xjvm-default=all",
]
}

Here is a detailed example and comment below if you have any queries related to this.

--

--

harsh shah

Mobile Developer (Android , flutter) - 5 Years , Worked on multiple domain like pharma , financial , Ecommerce , BLE .