Basic use of Android database room

Time:2021-5-3

Development and use of Android database room

1、 Introduction:
Room provides an abstraction layer on SQLite to make full use of the powerful functions of SQLite and access the database smoothly.
Room consists of three main components
Database: it contains the database holder and serves as the main access point for the underlying connection of the application with persistent relational data.
@Database comments
1. It is an abstract class that extends roomdatabase.
2. Add the entity table associated with the database in the annotation.
3. Contains an abstract method with 0 arguments and returns the class annotated with @ Dao.
At run time, you can call room. Databasebuilder() or room. Inmemorydatabasebuilder() to get an instance of the database.
@Entity: represents the table in the database
@Dao: contains methods for accessing the database
Basic use of Android database room
2: Rely on room database
1. Add project dependency in bulid.gradle under app module

//Add room dependency
implementation 'androidx.room:room-runtime:2.2.5'
annotationProcessor 'androidx.room:room-compiler:2.2.5'

Basic use of Android database room
3: Create an entity class entity

@Entity
public class User {
    @Primarykey (autogenerate = true) // whether the primary key automatically grows. The default value is false
 private int id;
 private String name;
 private int age;
 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 int getAge() {
        return age;
 }
    public void setAge(int age) {
        this.age = age;
 }
}

Basic use of Android database room
1. Primary key: each entity must define at least one field as the primary key.

1. You can annotate @ primarykey (autogenerate = true) in the entity. At the same time, you can also use the autogenerate attribute to assign ID automatically through room
 2. It can also be [email protected] [email protected] (primarykeys = {"Id", "name"}) if there is a combined primary key

2. Usually room will use the class name as the table name of the database. If you want to customize the table name in @ entity (tablename = my)_ Note:In SQLite, table names are case insensitive
3. Room uses the variable name as the field name of the database table. If you want the field name to be different from the variable name, add it in the variable output

public class User {
 @ColumnInfo(name = "first_name")
    private String name;
    }

4. Index and uniqueness
According to the way you operate the data, you may need to improve the speed of querying the database through the index. Add the indexes attribute through @ entity, and set the uniqueness of some fields. You can set unique to true under the @ index annotation

@Entity(indices = {@Index(value = "name",unique = true)})
public class User {
private String name;
}

5. Define the relationship between objects
Because SQLite is a relational database, you can specify the relationship before the object. Room explicitly forbids the direct use of relationship, but room still allows you to define foreign keys between entities.
For example, if there is another entity called book, you can define the relationship between them by using the @ ForeignKey annotation under the user entity.

@Entity(
        foreignKeys = @ForeignKey(entity = User.class, parentColumns = "id", 
        childColumns = "user_ ID ") // define foreign key
)
public class Book {
    @Primarykey // define primary key
 public int bookId;
 public String title;
 @ColumnInfo(name = "user_ ID ") // defines the field name in the database table
    public int userId;
 public int getUserId() {
        return userId;
 }
    public void setUserId(int userId) {
        this.userId = userId;
 }
    public int getBookId() {
        return bookId;
 }
    public void setBookId(int bookId) {
        this.bookId = bookId;
 }
    public String getTitle() {
        return title;
 }
    public void setTitle(String title) {
        this.title = title;
 }
}

6. Create nested objects
You can use the @ embedded annotation to represent the objects to be decomposed into sub fields in the table
For example, our user class can contain fields of type address, which represents a combination of fields named street, city, state and postcode. To store the combined columns separately in the table, include the address field annotated with @ embedded in the user class

public class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;
}

@Entity
public class User {
    @PrimaryKey
    public int id;

    public String firstName;

    @Embedded
    public Address address;
}

So the table representing the user object contains columns with the following names: ID, firstname, street, state, city, and post_ code。
@Embedded(prefix = “address_”) If the entity has multiple embedded fields of the same type, you can set the prefix property to make each column unique and change the address_ Embedded at the beginning of the column name
7. Ignore member variables
If you don’t want to keep some member variables, you can use the @ ignore annotation

@Ignore // indicates the fields to be ignored by room
private int age;

4: Create a Dao interface
Dao contains methods for accessing the database. Create an operation entity class and annotate it with @ Dao
@Insert statement comment
@Delete statement comment
@Update() UPDATE statement comment
@Query(“SELECT * FROM user WHERE first_ Name =: name “) query statement

@Dao
public interface UserDao {
    /*Insert data user*/
 @Insert
 void insert(User user);
 @Query ("select * from user") // query all users from the user table. User is the table created by the user entity class in room by default. You can also query all users through @ entity (tablename = my)_ User "), which specifies the table name, so the table name becomes my_ user
    List<User> getAllUsers();
 @Query("SELECT * FROM user WHERE first_ Name =: name ") // set the filter condition name to query the first_ Name is the table name first_ Name field, through @ columninfo (name = first)_ Name ") to set the table field name
    List<User> getUsersByName(String name);
}

5: Create a database holder class

@Database(entities = {User.class},version = 6,exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {
    private static final String DB_NAME="UserDatabase.db";
 private static volatile UserDatabase instance;// Create a singleton
 public static synchronized UserDatabase getInstance(Context context){
        if (instance==null){
            instance=create(context);
 }
        return instance;
 }
 /**
 *Create database*/
    private static UserDatabase create(Context context) {
        return Room.databaseBuilder(context,UserDatabase.class,DB_NAME)
        . allowmainthreadqueries() // allows the database to be operated on the main thread, which is generally not recommended; After setting this, the main thread will not report an error when calling add, delete, modify and query, otherwise it will report an error
        . fallbacktodestructivemigration() // this method can recreate the database in case of upgrade exception, but all data will be lost
        .addMigrations(new Migration(1,4) {
    @Override
 public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("alter table user add price TEXT");// Add a field price to upgrade the database version to 4
 }
})
        .build();
 }
 
 public  abstract UserDao getUserDao();// This is necessary to create an abstract class of Dao
}

be careful:
1. The SQL statement is checked for correctness at compile time
2. Do not operate the database in the main thread
3. Roomdatabase is best used in singleton mode
If the database is not set to operate in the main thread, an error will be reported, and the error prompt is
Basic use of Android database room
Therefore, you need to use the database, preferably in the new thread (). Start() sub thread, or handler or asynctask or rxjava asynchronous implementation.
Room database upgrade

//The first step is to change the version number to 2, the version to be upgraded
@Database(entities = {User.class},version = 2,exportSchema = false)
//Second, add addmigrations () to add database upgrade
 Room.databaseBuilder(context,UserDatabase.class,DB_NAME)
        .addMigrations(new Migration(1,2) {
            @Override
 public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("alter table user add go TEXT");// Add a field in the user table, go type is text
 Log.d("aa",database.getVersion()+"");
 }
        })
        .build();
//The third step is to add attributes to the entity class user
private String go;
public String getGo() {
    return go;
}
public void setGo(String go) {
    this.go = go;
}
//In this way, the database version is upgraded to 2 and can be used

6: Use of room database
It can also be implemented asynchronously with rxjava, handler, asynctask, etc

User user=new User();
user.setAge(2223);
user.setName("eees");
user.setGo("wogo");
new Thread(new Runnable() {
    @Override
 public void run() {
        UserDatabase.getInstance(NineActivity.this).getUserDao().insert(user);
 Log. D ("tag", "insert a data");
 }
}).start();

End: live up to youth and youth; Live up to the dream, live up to the future.