I. Room introduction

1, an overview of the

Room is a member of the Jetpack component library, an official Database ORM framework provided by Google, which provides an abstraction layer on SQLite for smoother database access while taking advantage of SQLite’s full capabilities.

Google official introduction:

The Room persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.

The Room persistence library provides an abstraction layer on top of SQLite, allowing for more robust database access while taking full advantage of SQLite’s capabilities.

Simply put: Room is a powerful database framework based on SQLite.

2. Three main components of Room

Database: Database holder. This component is used to create a Database holder. Annotations define a list of entities, and the content of a class defines an object (DAO) that gets data from a database. It is also the main entry point for the underlying connection. The annotated class is an abstract class that inherits RoomDatabase. At runtime, by calling the Room. DatabaseBuilder () or Room. InMemoryDatabaseBuilder instance () to get it.

Entity: Entity class. An example of this component represents a row of data in a database. For each Entity class, a corresponding table is created. In order for these entities to be created, you need to remove the above Database annotation from the entities list. All fields in the default Entity will be used to create the table unless it is annotated with @ignore.

Dao: A set of methods for accessing a database. This component is used to express a class or interface that has Data Access Object(Dao) functionality. The Dao class is an important component of Room and defines methods for querying (adding or deleting, etc.) a database. A class annotated with @Database must define an abstract method with no arguments that returns the @DAO annotated class. Room, an abstract method that returns the @DAO annotated class, generates an implementation of the class at compile time.

At first glance, don’t understand these three concepts feel very confused, confused it doesn’t matter, don’t need to memorize, I just record here, look at the actual combat part of the line, turn back, the concept of nature will understand.

Second, the actual combat

1. Add Room library dependencies

First add the following to the Build. gradle file in Google’s Maven repository (the outermost layer of the project) :

allprojects {
    repositories {
        jcenter()
        google()
    }
}
Copy the code

Then add dependencies to the app/build.gradle file

Def room_version = "2.0-rc01" // implementation "androidx. Room :room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version"Copy the code

If the project is developed in Kotlin, use the kapt keyword when adding room-compiler, and Java uses the annotationProcessor key. Otherwise, an access error may occur.

2. Define an Entity

When a class is annotated with @Entity and referenced by the entities property in the @Database annotation, Room creates a table in the Database for the @Entity annotated class.

The default entity class has the class name table name and the parameter name field name. Of course, we can also modify. A parameter called tableName is passed in the @Entity annotation to specify the name of the table.

2.1 PrimaryKey

Each Entity must have at least one PrimaryKey. Even if there is only one property, use @primaryKey to annotate this property. If you want Room to set an autoGenerate ID for an Entity, set the autoGenerate property of @primaryKey.

2.2 ColumnInfo

If you want to customize a column in a table, add @columninfo to the attribute, for example, @columninfo (name = “ID”), where “ID” is the name of a user-defined column.

@entity (tableName = "PHONE") public class PhoneBean implements Parcelable {@primarykey (autoGenerate = true) // set PrimaryKey @columnInfo (name = "ID") private int ID; @ColumnInfo(name = "PHONE") private String phone; @ColumnInfo(name = "NAME") private String name; @ColumnInfo(name = "DATE") private Date date; public PhoneBean(String phone, String name, Date date) { this.phone = phone; this.name = name; this.date = date; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getDate(){ return date; } public void setDate(Date date) { this.date = date; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(this.phone); dest.writeString(this.name); dest.writeLong(this.date ! = null ? this.date.getTime() : -1); } protected PhoneBean(Parcel in) { this.id = in.readInt(); this.phone = in.readString(); this.name = in.readString(); long tmpDate = in.readLong(); this.date = tmpDate == -1 ? null : new Date(tmpDate); } public static final Parcelable.Creator<PhoneBean> CREATOR = new Parcelable.Creator<PhoneBean>() { @Override public PhoneBean createFromParcel(Parcel source) { return new PhoneBean(source); } @Override public PhoneBean[] newArray(int size) { return new PhoneBean[size]; }}; }Copy the code
2.3 Defining a Transformation

TypeConverter uses the @typeconverter annotation to define the conversion method, as follows, to convert data of type Date to type Long for storage.

public class ConversionFactory { @TypeConverter public static Long fromDateToLong(Date date) { return date == null ? null : date.getTime(); } @TypeConverter public static Date fromLongToDate(Long value) { return value == null ? null : new Date(value); }}Copy the code

As shown, the example converts the Date attribute value to Long and stores it in the database:

Read the Date attribute value of the database, then convert the Date attribute value into a string to display:

Define the Dao

A Dao is an interface that defines a set of methods for adding, deleting, modifying, or querying a database. Room also provides annotations for ours, such as @insert, @delete, @update, and @Query. Update and Detele operations are performed based on defined primary keys.

@dao public interface PhoneDao {/** * Query("SELECT * FROM PHONE") List<PhoneBean> getPhoneAll(); /** * select * from @query; /** select * from @query; For example, we query a user's information based on PHONE:  * @return */ @Query("SELECT * FROM PHONE WHERE phone = :phone") List<PhoneBean> loadPhoneByIds(String phone); /** ** Add data to the database ** We can see the onConflict argument in the direct, which represents the logic to process the inserted data when it already exists. * There are three types of operation logic: REPLACE, ABORT, and IGNORE. * If not specified, ABORT is default to ABORT data insertion. Here we specify it as REPLACE to REPLACE the original data. * * @param phone */ @Insert(onConflict = OnConflictStrategy.REPLACE) void insertAll(List<PhoneBean> phone); /** * If you need to modify a piece of data, use the @update annotation, just like @delete, to find the entity to be deleted based on the primary key. * * @param phone */ @Update() void update(PhoneBean phone); /** * Delete data ** If you need to Delete data from a table, use the @delete annotation: * Use the primary key to find the entity to Delete. * * @param phoneBean */ @Delete() void delete(PhoneBean phoneBean); }Copy the code

Define Database — create Database

@Database(entities = {PhoneBean.class}, version = 1, exportSchema = false)
@TypeConverters({ConversionFactory.class})
public abstract class PhoneDatabase extends RoomDatabase {

    public static PhoneDatabase getDefault(Context context) {
        return buildDatabase(context);
    }

    private static PhoneDatabase buildDatabase(Context context) {
        return Room.databaseBuilder(context.getApplicationContext(), PhoneDatabase.class, "PHONE.db")
                .allowMainThreadQueries()
                .build();
    }

    public abstract PhoneDao getPhoneDao();
}
Copy the code

5, use

  • increase
private void insertPhone(String mName, String mPhone) {
    List<PhoneBean> mPhones = new ArrayList<>();
    mPhones.add(new PhoneBean(mPhone, mName));
    PhoneDatabase.getDefault(getApplicationContext()).getPhoneDao().insertAll(mPhones);
}
Copy the code
  • The query
private void queryPhone() { List<PhoneBean> mPhoneLists = PhoneDatabase.getDefault(getApplicationContext()).getPhoneDao().getPhoneAll(); / /... }Copy the code
  • Modify the
private void updatePhone(String name, String phone) { PhoneDatabase.getDefault(getActivity().getApplicationContext()).getPhoneDao(). update(new PhoneBean(phone, name)); / /... }Copy the code
  • delete
private void deletePhone() { PhoneDatabase.getDefault(getActivity().getApplicationContext()).getPhoneDao(). delete(mPhoneBean); / /... }Copy the code

Third, summary

The above is the basic use of The Jetpack architecture component Room. It is enough to master the basic operations above, such as combining LiveData and so on, and then you will understand the Jetpack component naturally.