In this blog, we will learn how to implement complete CRUD (Create, Read, Update, Delete) operations using Room Database in Android with Kotlin. This guide covers a practical implementation using RecyclerView to display data and perform real-time updates.
We will build a simple user management feature where users can add, view, update, and delete records. The project uses modern Android development practices including Coroutines, LiveData for observing database changes, and a clean adapter-based RecyclerView setup.
By the end of this tutorial, you will understand how to:
Insert data into Room Database
Observe and display data using LiveData
Update existing records dynamically
Delete items directly from RecyclerView
Structure your code for better scalability
class RoomDatabaseActivity : AppCompatActivity() {
private lateinit var binding: ActivityRoomDatabaseBinding
private lateinit var db: AppDatabase
private lateinit var userAdapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = DataBindingUtil.setContentView(this, R.layout.activity_room_database)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
initView()
}
private fun initView() {
db = DatabaseBuilder.getInstance(this@RoomDatabaseActivity)
userAdapter = UserAdapter(onDelete = { userData ->
lifecycleScope.launch {
db.userDao().deleteUser(userData)
}
}, onUpdate = { userData ->
lifecycleScope.launch {
db.userDao().updateUser(
userData.copy(name = userData.name + " Updated")
)
}
})
binding.rvUser.adapter = userAdapter
binding.rvUser.layoutManager = LinearLayoutManager(this)
binding.btnSubmit.setOnClickListener {
if (binding.edtAge.text.toString().isNotEmpty() && binding.edtName.text.toString()
.isNotEmpty()
) {
lifecycleScope.launch {
db.userDao().insertUser(
User(
name = binding.edtName.text.toString().trim(),
age = binding.edtAge.text.toString().toInt()
)
)
}
} else {
Toast.makeText(this, "Enter Name & Age", Toast.LENGTH_SHORT).show()
}
}
lifecycleScope.launch {
db.userDao().getAllUsers().observe(this@RoomDatabaseActivity) { userList ->
userAdapter.setData(userList)
}
}
}
}
implement Room Database in Android with Kotlin, including Entity, DAO, CRUD operations, and a singleton database setup using best practices.
Database class
@Database(entities = [User::class], version = 1)
abstract class AppDatabase: RoomDatabase() {
abstract fun userDao(): UserDao
}
User Table(Model)
@Entity(tableName = "user_table")
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val name: String,
val age: Int
)
UserDao Class
@Dao
interface UserDao {
// CREATE
@Insert
suspend fun insertUser(user: User)
// READ
@Query("SELECT * FROM user_table")
fun getAllUsers(): LiveData<List<User>>
// UPDATE
@Update
suspend fun updateUser(user: User)
// DELETE
@Delete
suspend fun deleteUser(user: User)
}
Create Database Instance
object DatabaseBuilder {
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"user_db"
).build()
INSTANCE = instance
instance
}
}
}
Adapter For Display Data
class UserAdapter(
private val onDelete: (User) -> Unit,
private val onUpdate: (User) -> Unit
) : RecyclerView.Adapter<UserAdapter.ViewHolder>() {
private var list = ArrayList<User>()
fun setData(data: List<User>) {
list.clear()
list.addAll(data)
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val binding =
ItemUserDesignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int
) {
val itemData = list[position]
holder.setData(itemData, onDelete, onUpdate)
}
override fun getItemCount(): Int {
return list.size
}
class ViewHolder(private val binding: ItemUserDesignBinding) :
RecyclerView.ViewHolder(binding.root) {
fun setData(itemData: User, onDelete: (User) -> Unit, onUpdate: (User) -> Unit) {
binding.tvName.text = itemData.name
binding.tvAge.text = itemData.age.toString()
binding.btnDelete.setOnClickListener {
onDelete(itemData)
}
binding.btnUpdate.setOnClickListener {
onUpdate(itemData)
}
}
}
}
This guide demonstrates how to implement Room Database in Android using Kotlin. It covers creating an Entity to define the table structure, a DAO for handling CRUD operations, and a Database class to manage data access.
A singleton pattern is used to ensure a single instance of the database throughout the app. LiveData is utilized to observe data changes and automatically update the UI, making the app more reactive and efficient.
Overall, this setup provides a simple and scalable approach to local data storage in Android applications.
Top comments (0)