Use of Room in Android Jetpack

  • 2021-12-21 05:12:52
  • OfStack

Room

Room is mainly divided into three parts: database, dao and entity class entity

Entity

The @ Entity (tableName = "student") annotation is required for entity entity class definition, where the parameter is the table name

The @ PrimaryKey (autoGenerate = true) annotation is needed for the primary key definition, and the parameter determines whether to grow by itself

Each attribute (that is, the field of the table) needs to be annotated with @ ColumnInfo (name = "name", typeAffinity = ColumnInfo. TEXT), name is the field name in the table, typeAffinity is the field type, and the types are:


//  Type association is not defined. Resolves based on type. 
int UNDEFINED = 1;
​
//  Text type  
int TEXT = 2;
​
//  Column correlation constant of integer or Boolean value. 
int INTEGER = 3;
​
//  Column correlation constant for floating-point numbers or doubles. 
int REAL = 4;
​
// 2 Column affinity constant of binary data. 
int BLOB = 5;

Entity classes need to specify 1 constructor. If we have multiple constructors, we need to tell room to ignore other constructors, otherwise an error will be reported, and room can only use one constructor. You can add @ Ignore annotation to the constructor (also if you want to ignore 1 attribute)


@Entity(tableName = "student")
public class Student {
​
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id",typeAffinity = ColumnInfo.INTEGER)
    public int id;
​
    @ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT)
    public String name;
​
    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;
​
    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER)
    public int sex;
    @Ignore//  Tell room Ignore this constructor 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
​
    @Ignore//  Tell room Ignore this constructor 
    public Student(int id) {
        this.id = id;
    }
    //  Specify room The construction method used 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Dao

dao is an interface, and needs to add a @ Dao annotation. It mainly declares some abstract methods for data operation, and all methods need to add specific annotations in room

@ Insert Add

@ Update Modification

@ Delete delete

@ Query to query this annotation, you need to add parameters. The parameter is sql statement


@Dao
public interface StudentDao {
    @Insert
    void  insertStudent(Student...students);
​
    @Query("SELECT * FROM student")
    List<Student> getAllStudent();
​
    @Query("SELECT * FROM student WHERE id=:id")
    List<Student> getAllStudentById(int id);
​
    @Query("DELETE FROM student")
    void clearAll();
​
    @Update
    void upData(Student...students);
    
    @Delete
    void delete(Student...students);
}

DataBase

The database class needs to inherit the abstract class RoomDatabase, and dataBase must also be an abstract class. Need to add @ DataBase annotation


@Database(entities = 
{Student.class}, version = 1, exportSchema = false)  // entities- Entity class   version- Database version  exportSchema- Whether to generate schema Documents, schema The file contains the table structure and information 

If you want to generate the schema file, you also need to specify the generation location of the schema file in build. gradle


android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
​
    defaultConfig {
        applicationId "com.example.room"
        minSdkVersion 20
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
​
        // Specify room.schemaLocation Generated file path 
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
}

The database class needs to be singleton but does not need to write a private constructor. After inheriting RoomDatabase, room will recognize it, only one getInstance method is needed, and the interior is an instantiation of database.


public static synchronized StudentDataBase getInstance(Context context) {
    if (mInstance == null) {
        mInstance = Room.databaseBuilder(context.getApplicationContext(),
                StudentDataBase.class,
                DATABASE_NAME)
                // .allowMainThreadQueries()//  Allows database manipulation on the main thread 
                .addMigrations(MIGRATION_1_2)//  When upgrading the database, 
                .fallbackToDestructiveMigration()//  When the database version is abnormal   The original data will be emptied    Then go to the current version 
              //  .createFromAsset(" Initial database in resource file ")//  Pre-populate the database    Initial data 
                .build();
    }
    return mInstance;
}

You also need to declare an abstract method to get dao, just declare it.


public abstract StudentDao getStudentDao();

When the version of the database is upgraded, you need to use Migration, create Migration (), which version to which version of the parameter upgrade. Override the mingrate method to write table changes (structural changes, etc.) through the database. execSQL () method within the mingrate method. Migration can have multiple, corresponding to multiple upgrades of the table.


static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");//  Add a table field 
    }
};

Panorama of database


@Database(entities = {Student.class}, version = 1, exportSchema = true)
public abstract class StudentDataBase extends RoomDatabase {
    private static StudentDataBase mInstance;
    private static final String DATABASE_NAME = "student.db";
​
    public static synchronized StudentDataBase getInstance(Context context) {
        if (mInstance == null) {
            mInstance = Room.databaseBuilder(context.getApplicationContext(),
                    StudentDataBase.class,
                    DATABASE_NAME)
                    // .allowMainThreadQueries()//  Allows database manipulation on the main thread 
                    .addMigrations(MIGRATION_1_2)//  When upgrading the database, 
                    .fallbackToDestructiveMigration()//  When the database version is abnormal   The original data will be emptied    Then go to the current version 
                  //  .createFromAsset(" Initial database in resource file ")//  Pre-populate the database    Initial data 
                    .build();
        }
        return mInstance;
    }
​
    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");//  Add a table field 
        }
    };
​
    public abstract StudentDao getStudentDao();
}

Use

Get dao


StudentDataBase dataBase = StudentDataBase.getInstance(this);
StudentDao studentDao = dataBase.getStudentDao();

Through the dao operation table, note that the operation on the database needs to be put into the sub-thread operation


@Entity(tableName = "student")
public class Student {
​
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id",typeAffinity = ColumnInfo.INTEGER)
    public int id;
​
    @ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT)
    public String name;
​
    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;
​
    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER)
    public int sex;
    @Ignore//  Tell room Ignore this constructor 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
​
    @Ignore//  Tell room Ignore this constructor 
    public Student(int id) {
        this.id = id;
    }
    //  Specify room The construction method used 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
0

Related articles: