Room Database in jetpack compose
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 theuser
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.