top of page

Building Android Apps with Kotlin and Room

Building Android Apps with Kotlin and Room

In today's world of mobile app development, efficient data management is crucial for creating high-quality applications. Kotlin, a modern programming language, offers great support for Android development. When combined with Room, an SQLite object-relational mapping (ORM) library, developers can streamline database operations and enhance productivity.

In this blog post, we will explore the fundamentals of working with Kotlin and Room and demonstrate how to leverage their features to build robust and efficient Android applications.


To follow along with the examples in this blog post, you should have a basic understanding of Kotlin and Android development. Familiarity with SQLite databases would also be helpful. Ensure you have Android Studio installed and set up on your machine.

What is Room?

Room is an Android library that provides an abstraction layer over SQLite, allowing developers to work with databases using Kotlin or Java objects. It simplifies the process of defining and interacting with databases by eliminating boilerplate code and providing compile-time checks for SQL statements.

Room consists of three main components: entities, data access objects (DAOs), and the database itself.

Setting Up Room in Android Project

To begin, create a new Android project in Android Studio or open an existing one. Then, follow these steps to add the necessary dependencies for Room:

1. Open the app-level build.gradle file.

2. Add the following dependencies in the dependencies block:

implementation ''
kapt ''

Replace x.y.z with the latest version of Room available. Make sure to check the official documentation or Maven repository for the most up-to-date version.

3. Sync your project to fetch the new dependencies.

Defining Entities

Entities represent the tables in the database. Each entity class represents a table, and its fields represent the columns. Let's create a simple entity called User:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String

Here, we annotate the class with @Entity and specify the table name as "users." The @PrimaryKey annotation marks the id field as the primary key.

Creating a Data Access Object (DAO)

A DAO provides methods to perform CRUD (Create, Read, Update, Delete) operations on the database. Let's create a DAO interface for the User entity:

interface UserDao {
    fun insert(user: User)
    @Query("SELECT * FROM users")
    fun getAllUsers(): List<User>

    @Query("SELECT * FROM users WHERE id = :userId")
    fun getUserById(userId: Int): User?

    fun updateUser(user: User)
    fun deleteUser(user: User)

In this example, we annotate the interface with @Dao to mark it as a DAO. We define several methods annotated with @Insert, @Query, @Update, and @Delete for different database operations.

Creating the Database

Now, let's create the database class that ties everything together:

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        private var INSTANCE: AppDatabase? = null
        fun getInstance(context: Context): AppDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }

        private fun buildDatabase(context: Context) =

Here, we annotate the class with @Database and specify the entities it contains (in this case, only User) and the database version. The AppDatabase class is an abstract class that extends RoomDatabase. We define an abstract method userDao() that returns the DAO interface for the User entity.

We also implement the Singleton pattern to ensure that only one instance of the database is created. The getInstance() method returns the singleton instance of the AppDatabase. If the instance is null, it creates a new instance using the buildDatabase() method.

Performing Database Operations: Now that we have set up the entities, DAO, and database, let's explore how to perform database operations:

val user = User(1, "John Doe", "")
val userDao = AppDatabase.getInstance(context).userDao()

// Inserting a user

// Fetching all users
val allUsers = userDao.getAllUsers()

// Fetching a user by ID
val retrievedUser = userDao.getUserById(1)

// Updating a user = "Jane Doe"

// Deleting a user

In the above example, we first create a User object and obtain an instance of the UserDao using the getInstance() method of the AppDatabase class. We can then perform various operations, such as inserting, fetching, updating, and deleting users.


Kotlin and Room provide a powerful combination for working with databases in Android applications. With Room's simplified API and compile-time checks, developers can write efficient and maintainable code.

In this blog post, we covered the basics of working with Kotlin and Room, including setting up dependencies, defining entities, creating DAOs, and performing common database operations. By leveraging these tools, you can streamline your Android app's data management and create robust applications with ease.

Remember to refer to the official documentation for Room and Kotlin for more in-depth information and advanced features.

Happy coding!


Blog for Mobile App Developers, Testers and App Owners


This blog is from Finotes Team. Finotes is a lightweight mobile APM and bug detection tool for iOS and Android apps.

In this blog we talk about iOS and Android app development technologies, languages and frameworks like Java, Kotlin, Swift, Objective-C, Dart and Flutter that are used to build mobile apps. Read articles from Finotes team about good programming and software engineering practices, testing and QA practices, performance issues and bugs, concepts and techniques. 

bottom of page