build.gradle
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("kotlin-kapt")
}
android {
namespace = "com.androindian.roomdatabase"
compileSdk = 34
defaultConfig {
applicationId = "com.androindian.roomdatabase"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
dataBinding{
enable=true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation("androidx.room:room-runtime:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
// ViewModel and LiveData
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
// Coroutines
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:inputType="textPersonName" />
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/etMobile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Mobile"
android:inputType="phone" />
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:id="@+id/btnSave"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save User" />
<Button
android:id="@+id/btnLoad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Load Users" />
<Button
android:id="@+id/btnDelete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete All Users" />
</LinearLayout>
MainActivity.kt
This activity interacts with the database through the UserViewModel
package com.androindian.roomdb
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.room.Room
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private lateinit var userViewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val database = Room.databaseBuilder(
applicationContext,
UserDatabase::class.java,
"user_database"
).build()
val repository = UserRepository(database.userDao())
val viewModelFactory = UserViewModelFactory(repository)
userViewModel = ViewModelProvider(this, viewModelFactory).get(UserViewModel::class.java)
val etUsername = findViewById<EditText>(R.id.etUsername)
val etEmail = findViewById<EditText>(R.id.etEmail)
val etMobile = findViewById<EditText>(R.id.etMobile)
val etPassword = findViewById<EditText>(R.id.etPassword)
val btnSave = findViewById<Button>(R.id.btnSave)
val btnLoad = findViewById<Button>(R.id.btnLoad)
val btnDelete = findViewById<Button>(R.id.btnDelete)
btnSave.setOnClickListener {
val user = User(
username = etUsername.text.toString(),
email = etEmail.text.toString(),
mobile = etMobile.text.toString(),
password = etPassword.text.toString()
)
lifecycleScope.launch {
userViewModel.insert(user)
Toast.makeText(this@MainActivity, "User Saved", Toast.LENGTH_SHORT).show()
}
}
btnLoad.setOnClickListener {
lifecycleScope.launch {
val users = userViewModel.getAllUsers()
users.forEach { user ->
Toast.makeText(this@MainActivity, "User: ${user.username}, Email: ${user.email}", Toast.LENGTH_SHORT).show()
}
}
}
btnDelete.setOnClickListener {
lifecycleScope.launch {
userViewModel.deleteAll()
Toast.makeText(this@MainActivity, "All Users Deleted", Toast.LENGTH_SHORT).show()
}
}
}
}
User.kt
This class represents the user entity in the database.
package com.androindian.roomdb
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "user_table")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val username: String,
val email: String,
val mobile: String,
val password: String
)
UserDao.kt
This interface defines the methods for accessing the database.
package com.androindian.roomdb
import androidx.room.*
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(user: User)
@Update
suspend fun update(user: User)
@Delete
suspend fun delete(user: User)
@Query("SELECT * FROM user_table ORDER BY username ASC")
suspend fun getAllUsers(): List<User>
@Query("DELETE FROM user_table")
suspend fun deleteAll()
}
UserDatabase.kt
This class provides the database instance.
package com.androindian.roomdb
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
UserRepository.kt
This class handles data operations, interacting with the DAO.
package com.androindian.roomdb
class UserRepository(private val userDao: UserDao) {
suspend fun insert(user: User) {
userDao.insert(user)
}
suspend fun update(user: User) {
userDao.update(user)
}
suspend fun delete(user: User) {
userDao.delete(user)
}
suspend fun getAllUsers(): List<User> {
return userDao.getAllUsers()
}
suspend fun deleteAll() {
userDao.deleteAll()
}
}
UserViewModel.kt
This class interacts with the repository and provides data to the UI.
package com.androindian.roomdb
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class UserViewModel(private val repository: UserRepository) : ViewModel() {
fun insert(user: User) = viewModelScope.launch {
repository.insert(user)
}
fun update(user: User) = viewModelScope.launch {
repository.update(user)
}
fun delete(user: User) = viewModelScope.launch {
repository.delete(user)
}
suspend fun getAllUsers(): List<User> {
return repository.getAllUsers()
}
fun deleteAll() = viewModelScope.launch {
repository.deleteAll()
}
}
class UserViewModelFactory(private val repository: UserRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(UserViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return UserViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}