Android database Room development and use details

I. Introduction:

Room provides an abstraction layer on top of SQLite to allow smooth access to the database while taking full advantage of the power of SQLite.

Room consists of three main components:

Database: Contains the database holder and serves as the primary access point for underlying connections to apply retained relational data.

@ Database annotation

1. Is an abstract class that extends RoomDatabase.

2. Add the entity table associated with the database in the comment.

3. An abstract method that contains 0 arguments and returns a class annotated with @DAO.

At runtime, you can call Room. DatabaseBuilder () or Room. InMemoryDatabaseBuilder () access to the Database instance.

@Entity: Represents a table in the database

@DAO: Contains methods to access the database



2. Rely on ROOM database

1. Add project dependency in bulid.Gradle under APP module

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



Create an Entity class

@Entity public class User {@PrimaryKey(autoGenerate = true)// Private int id = false; 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; }}



1. Primary key: Each entity must define at least one field as the primary key.

1. You can annotate @PrimaryKey(autoGenerate = true) in an entity, and you can also use the autoGenerate property to automatically assign ID 2 by Room. This can also be done at @Entity@Entity(PrimaryKeys = {"id","name"}) if there is a combined primary key

2. If you want to customize the tableName in @entity (tableName = “my_user”), note: 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 TAB

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

Depending on how you manipulate the data, you may need to use an Index to query the database faster. Use @Entity to add indices. Set unique to some fields using the @Index annotation

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

Since SQLite is a relational database, you can specify the relationships that precede the objects. Room explicitly disallows the use of relationships directly, but Room still allows you to define foreign keys between entities. For example, if you have another entity called Book, you can define the relationship between them using the @ForeignKey annotation under the User entity.

@Entity( foreignKeys = @ForeignKey(entity = User.class, parentColumns = "id", Public class Book {@PrimaryKey public int BookID; public int BookID; public String title; @ColumnInfo(name = "user_id"); @ColumnInfo(name = "user_id"); 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; }}

You can use @Embedded annotations to represent objects to be decomposed into table neutron fields. 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 composite columns separately in the table, include the Address field using the @Embedded annotation 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 embed address_ into the top 7 of the column name by setting the prefix attribute to keep each column unique. Ignore member variables If you don’t want to keep some member variables, you can use the @Ignore annotation

@Ignore// Indicates which field Room needs to Ignore private int age;

Four: Create a DAO interface The DAO contains methods for accessing the database, @dao @insert @delete @update () @query (“SELECT * FROM user WHERE first_name=:name”) @query (“SELECT * FROM user WHERE first_name=:name”

@dao public interface UserDao {/* @insert void Insert (User User); @query ("SELECT * FROM user") @query ("SELECT * FROM user") @query ("SELECT * FROM user"); @entity (tableName = "my_user") @entity (tableName = "my_user") My_user List<User> getAllUsers(); my_user List<User> getAllUsers(); @query ("SELECT * FROM user WHERE first_name=:name"); @columnInfo (name = "SELECT * FROM user WHERE first_name=:name") List<User> getUsersByName(String name); }

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; Public static synchronized UserDatabase getInstance(Context Context){if (instance==null){ instance=create(context); } return instance; Private static UserDatabase create(Context Context) {return private static UserDatabase create(Context Context) {return private static UserDatabase create(Context Context) Room. DatabaseBuilder (context, UserDatabase. Class, DB_NAME). AllowMainThreadQueries () / / allow the main thread operation database, is generally not recommended; Set the left thread calls to add and delete not an error, or complains. FallbackToDestructiveMigration () / / this method can exception to upgrade to create the database, AddMigrations (new Migration(1,4) {@Override public void migrated (@Nonnull supportSQLiteDatabase) {addMigrations(new Migration(1,4)) {@Override public void migrated (@Nonnull supportSQLiteDatabase); 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 the DAO abstract class}

Note:

1. Check if the SQL statement is correct at compile time

2. Do not perform database operations on the main thread

3, RoomDatabase is best to use singleton mode

If the database is not set to operate on the main thread, an error will be reported



This is best done in a new Thread().start() subthread, or in a Handler or AsyncTask or RxJava asynchronous implementation.

Room Database Upgrade

@database (entities = {User. Class},version = 2,exportSchema = false) // Entities = entities (entities = {User. Class},version = 2,exportSchema = false) Add addMigrations () to add the 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"); Mysql > select * from user where user = 'TEXT log. d' ("aa",database.getVersion()+""); } }) .build(); // private String Go; // private String Go; public String getGo() { return go; } public void setGo(String go) { this.go = go; } // The database version has been upgraded to 2 and is ready to use

Six: Room database use By opening the child thread insert a data, can also be combined with RXJava and Handler and AsyncTask asynchronous implementation

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 piece of data "); } }).start();

End: not young, not young; Live up to your dreams and live up to your future.