Android room database : CRUD example tutorial

Android room database : CRUD example tutorial

Introduction: 

Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.

Apps that handle non-trivial amounts of structured data can benefit greatly from persisting that data locally. The most common use case is to cache relevant pieces of data. That way, when the device cannot access the network, the user can still browse that content while they are offline. Any user-initiated content changes are then synced to the server after the device is back online.

Because Room takes care of these concerns for you, we highly recommend using Room instead of SQLite.

GITHUB

DEMO

Components: 

There are 3 major components in Room:

  • Database: Contains the database holder and serves as the main access point for the underlying connection to your app’s persisted, relational data.The class that’s annotated with @Database should satisfy the following conditions:
    • Be an abstract class that extends RoomDatabase.
    • Include the list of entities associated with the database within the annotation.
    • Contain an abstract method that has 0 arguments and returns the class that is annotated with @Dao.

    At runtime, you can acquire an instance of Database by calling Room.databaseBuilder() orRoom.inMemoryDatabaseBuilder().

  • Entity: Represents a table within the database.
  • DAO: Contains the methods used for accessing the database.

 

Architecture :

 

 

CRUD Operation

 

 

1)Project setup and dependency:

add  google() to repository in gradle (project) file

 buildscript {
    
    repositories {
       <strong> google()</strong>
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

and

implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

to gradle(app) file

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.adndigitalbd.androidroomdatabase"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

   <strong> implementation "android.arch.persistence.room:runtime:1.0.0"
    annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:cardview-v7:28.0.0'

}

 

 

2) Create Entity: 

Create a entity/model named User  and create three fields id,name,email where id is auto incremental primary key.


import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.ColorInt;

@Entity(tableName = "users")
public class User {

    @PrimaryKey(autoGenerate = true)
    private int id = 0;

    @ColumnInfo(name = "user_name")
    private String name;

    @ColumnInfo(name = "user_email")
    private String email;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

3) Create DAO (data access object) class :

Create a DAO interface class named DAO class . Here added insert , get data , update and delete operation methods and queries.

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;

import com.adndigitalbd.androidroomdatabase.entity.User;

import java.util.List;

@Dao
public interface DaoClass {

    /***
     *  insert data
     * @param user
     */
    @Insert
    public void addUser(User user);

    /**
     * retrieve all data from users table
     * @return
     */
    @Query("select * from users")
    public List<User> getUsers();

    /***
     * Delete user from users table
     * @param user
     */
    @Delete
    public void deleteUser(User user);


    /***
     * Update user from users table
     * @param user
     */
    @Update
    public void updateUser(User user);
}

4) Database access class :
Create database abstract class that will extends RoomDatabase , So that we can call this class and method from any where

import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;

import com.adndigitalbd.androidroomdatabase.entity.User;
import com.adndigitalbd.androidroomdatabase.dao.DaoClass;

@Database(entities = User.class, version = 1)
public abstract class DatabaseClass extends RoomDatabase {
    public abstract DaoClass daoClass();
}

5 ) Create an Adapter :

Congratulations!! We have done our main task to implement RoomDatabase in our project . We will just call the CRUD methods from an Activity.
We will show our data as a list . We can use recyclerview so that . Now we will create an adapter so that we can display our data with recyclerview .

import android.app.AlertDialog;
import android.arch.persistence.room.Room;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.adndigitalbd.androidroomdatabase.R;
import com.adndigitalbd.androidroomdatabase.activities.AddUserActivity;
import com.adndigitalbd.androidroomdatabase.activities.MainActivity;
import com.adndigitalbd.androidroomdatabase.database.DatabaseClass;
import com.adndigitalbd.androidroomdatabase.entity.User;
import com.adndigitalbd.androidroomdatabase.globalVariables.GlobalVariables;

import java.util.List;

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserHolder> {

    public List<User> userList;
    DatabaseClass db;
    private Context mContext;

    public UserAdapter(List<User> userList) {
        this.userList = userList;
    }

    @NonNull
    @Override
    public UserAdapter.UserHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

        mContext = parent.getContext();
        db = Room.databaseBuilder(parent.getContext(),
                DatabaseClass.class, "myDatabase").allowMainThreadQueries().build();

        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.user_adapter, parent, false);
        UserHolder userAdapter = new UserHolder(v);
        return userAdapter;
    }

    @Override
    public void onBindViewHolder(@NonNull final UserAdapter.UserHolder userHolder, final int position) {
        userHolder.name.setText(userList.get(position).getName().toString());
        userHolder.email.setText(userList.get(position).getEmail().toString());


        userHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                AlertDialog alertDialog = new AlertDialog.Builder(mContext).create();

                alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Edit",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                GlobalVariables.id = userList.get(position).getId();
                                GlobalVariables.name = userList.get(position).getName();
                                GlobalVariables.email = userList.get(position).getEmail();
                                GlobalVariables.updateFlag = "update";

                                Intent intent = new Intent(mContext,AddUserActivity.class);
                                mContext.startActivity(intent);
                            }
                        });


                alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Delete",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                deleteUser(userList.get(position).getId());
                                dialog.dismiss();
                                userList.remove(position);
                                notifyItemRemoved(position);
                                notifyItemRangeChanged(position, userList.size());


                            }
                        });
                alertDialog.show();


            }
        });
    }

    @Override
    public int getItemCount() {
        return userList.size();
    }


    private void deleteUser(int id) {
        User user = new User();
        user.setId(id);
        db.daoClass().deleteUser(user);
        Toast.makeText(mContext, "Deleted!", Toast.LENGTH_SHORT).show();
    }


    public class UserHolder extends RecyclerView.ViewHolder {

        private TextView name, email;

        public UserHolder(@NonNull View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.name);
            email = itemView.findViewById(R.id.email);

        }
    }
}

XML file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto">


    <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardElevation="1dp" app:cardBackgroundColor="@color/white" android:layout_marginBottom="1dp" >
        <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginLeft="20dp" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" >

            <TextView android:id="@+id/name" android:textColor="@color/black" android:textSize="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" " />

            <TextView android:id="@+id/email" android:textSize="12dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" />
        </LinearLayout>
    </android.support.v7.widget.CardView>


</RelativeLayout>

6) Add/update Data :

Create an activity named AddUserActivity . We will use this activity for both add new user and update user.

import android.arch.persistence.room.Room;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.constraint.solver.GoalRow;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.adndigitalbd.androidroomdatabase.R;
import com.adndigitalbd.androidroomdatabase.database.DatabaseClass;
import com.adndigitalbd.androidroomdatabase.entity.User;
import com.adndigitalbd.androidroomdatabase.globalVariables.GlobalVariables;

public class AddUserActivity extends AppCompatActivity {


    private EditText mName,mEmail;
    private Button mAddUser;
    private String nameString,emailString;

    private Context mContext;
    DatabaseClass db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_user);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mContext = AddUserActivity.this;

        mName = findViewById(R.id.name);
        mEmail = findViewById(R.id.email);
        mAddUser = findViewById(R.id.addUser);


        if (GlobalVariables.updateFlag.equals("update")){
            mName.setText(GlobalVariables.name);
            mEmail.setText(GlobalVariables.email);
        }

        db = Room.databaseBuilder(getApplicationContext(),
                DatabaseClass.class, "myDatabase").allowMainThreadQueries().build();

        mAddUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                nameString = mName.getText().toString();
                emailString = mEmail.getText().toString();

                if (nameString.length()&gt;0 &amp;&amp; emailString.length()&gt;0){



                    if (GlobalVariables.updateFlag.equals("update")){
                        User user = new User();
                        user.setId(GlobalVariables.id);
                        user.setName(nameString);
                        user.setEmail(emailString);
                        db.daoClass().updateUser(user);
                        Toast.makeText(mContext, "Successful", Toast.LENGTH_SHORT).show();
                        GlobalVariables.updateFlag = "";

                        startActivity(new Intent(AddUserActivity.this,MainActivity.class));
                    }else {

                        User user = new User();
                        user.setName(nameString);
                        user.setEmail(emailString);
                        db.daoClass().addUser(user);
                        Toast.makeText(mContext, "Successful", Toast.LENGTH_SHORT).show();

                        startActivity(new Intent(AddUserActivity.this, MainActivity.class));

                    }

                }

            }
        });






    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        GlobalVariables.updateFlag = "";
    }
}

XML


<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activities.AddUserActivity">

    <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_add_user" />



</android.support.design.widget.CoordinatorLayout>

and

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".activities.AddUserActivity" tools:showIn="@layout/activity_add_user">


    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_margin="50dp">


        <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" android:hint="Name" tools:layout_editor_absoluteX="84dp" tools:layout_editor_absoluteY="137dp" tools:ignore="MissingConstraints" />

        <EditText android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="Email" android:inputType="textEmailAddress" tools:layout_editor_absoluteX="84dp" tools:layout_editor_absoluteY="197dp" tools:ignore="MissingConstraints" />

        <Button android:id="@+id/addUser" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Submit" android:layout_marginTop="10dp" android:textColor="@color/white" android:background="@color/colorPrimary" tools:layout_editor_absoluteX="148dp" tools:layout_editor_absoluteY="273dp" tools:ignore="MissingConstraints" />

    </LinearLayout>

</RelativeLayout>

7) Display list :
Now create an Activity . It’s actually main activity . That will display user data as list . also there a button to add new user data .

import android.arch.persistence.room.Room;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.InputType;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.adndigitalbd.androidroomdatabase.R;
import com.adndigitalbd.androidroomdatabase.adapters.UserAdapter;
import com.adndigitalbd.androidroomdatabase.database.DatabaseClass;
import com.adndigitalbd.androidroomdatabase.entity.User;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.DialogInterface;

public class MainActivity extends AppCompatActivity {


    DatabaseClass db;

    private RecyclerView mRecyclerView;
    public UserAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    List<User> userList;

    private String name = "";
    private String emailString = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setTitle("Room Database");

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(MainActivity.this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        db = Room.databaseBuilder(getApplicationContext(),
                DatabaseClass.class, "myDatabase").allowMainThreadQueries().build();
        getAllData();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

               startActivity(new Intent(MainActivity.this,AddUserActivity.class));
            }
        });





    }


    private void getAllData() {
        List<User> userList = new ArrayList<>();
        userList = db.daoClass().getUsers();

        if (userList.size() > 0) {
            mAdapter = new UserAdapter(userList);
            mRecyclerView.setAdapter(mAdapter);

        } else {
            Toast.makeText(this, "No data ", Toast.LENGTH_SHORT).show();
        }


    }

    private void deleteUser() {
        User user = new User();
        user.setId(3);
        db.daoClass().deleteUser(user);

        Toast.makeText(this, "Delete user", Toast.LENGTH_SHORT).show();
    }

    private void updateUser() {
        User user = new User();
        user.setId(4);
        user.setEmail("arifhasnat.com@gmail.com");
        user.setName("arif hasnat");
        db.daoClass().updateUser(user);

        Toast.makeText(this, "User Updated", Toast.LENGTH_SHORT).show();
    }


}

XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activities.MainActivity">

    <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" app:srcCompat="@drawable/pencil" />

</android.support.design.widget.CoordinatorLayout>

and

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".activities.MainActivity" tools:showIn="@layout/activity_main" android:background="@color/gray">

    <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent">


    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

And All Done . You can also download full project code from Github.

 

Download Project Code From Github

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *