Room是android Architecture Components中簡化數據庫讀寫的組件
集成方法:
implementation "android.arch.persistence.room:runtime:1.0.0-rc1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-rc1"
testImplementation "android.arch.persistence.room:testing:1.0.0-rc1"
implementation "android.arch.persistence.room:rxjava2:1.0.0-rc1"
Room分為三部分
- DataBase: 代表一個數據庫,提供抽象方法訪問Dao對象。通過Room.databaseBuilder或者Room.inMemoryDatabaseBuilder創建。
- Entity:每個entity類代表一個
table
,每個實例代表一行 - Dao: 數據訪問接口,增刪查Entity的接口
Database
@Database(version = 1, entities = {Entity.class})
mark一個類是Database類,提供dao的獲取方法,entities指定有哪些表
Entity
@Entity
public class User {
@PrimaryKey
private int uid;
private String name;
@ColumnInfo(name = "last_name")
private String lastName;
// getters and setters are ignored for brevity but they are required for Room to work.
}
@Entity(tableName="", indices={@Index("name")}, foreignKeys={}, primaryKeys="", inheritSuperIndices="")
Entity的構造函數要么或者構造函數的參數對應到field
tranisent或者@Ignore
修飾的field不會持久化
至少要有一個@PrimaryKey
的field 或者Entity.primaryKeys()
定義主鍵
以下注解可以修飾field
@PrimaryKey(autoGenerate=true|false)
@ColumnInfo(index=true|false, collate= UNSPECIFIED|BINARY|NOCASE|RTRIM, name="", typeAffinity= UNDEFINED|TEXT|INTEGER|REAL|BLOB)
構造表示時列的一些屬性
@Embedded(prefix="")
如果field是另外一個class,那么這個class的屬性會放到主類中
public class Coordinates {
double latitude;
double longitude;
}
public class Address {
String street;
@Embedded
Coordinates coordinates;
}
@Relation(entity = class, entityColumn = "", parentColumn = "", projection = "")
定義一到多的關系,修飾的field需要是List或者set。用于自動獲取關聯的relation
@Entity
public class Pet {
@ PrimaryKey
int id;
int userId;
String name;
// other fields
}
public class UserNameAndAllPets {
public int id;
public String name;
@Relation(parentColumn = "id", entityColumn = "userId")
public List<Pet> pets;
}
DAO
DAO可以是接口或是抽象類,提供一系列insert,udpate或者delete的函數
@Insert(onConflict=ABORT|FAIL|IGNORE|REPLACE|ROLLBACK)
將傳入的對象在一個transaction中插入數據庫
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List<User> friends);
}
@Update(onConflict = ABORT|FAIL|IGNORE|REPLACE|ROLLBACK)
根據傳入對象的primaryKey尋找數據庫中的行,修改對象所在行
@Dao
public interface MyDao {
@Update
public void updateUsers(User... users);
}
@Delete
刪除傳入對象所在行
@Dao
public interface MyDao {
@Delete
public void deleteUsers(User... users);
}
@Query
運行一段query,可以是SELECT,UPDATE,DELETE
通過:name來在query中引用方法參數
用返回的column來構建返回對象
@Dao
public interface MyDao {
@Query("SELECT * FROM user")
public User[] loadAllUsers();
}
TypeConverter
當有自定義類文件要轉化成Room可以持久化的數據類型時,需要定義TypeConverter
public class Converters {
@TypeConverter
public static Date fromTimestamp(Long value) {
return value == null ? null : new Date(value);
}
@TypeConverter
public static Long dateToTimestamp(Date date) {
return date == null ? null : date.getTime();
}
}
然后在Database類上指定TypeConverter定義的類
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
Migration
用于指定從低version升級到高version時,進行的數據庫操作
Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
+ "`name` TEXT, PRIMARY KEY(`id`))");
}
};
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE Book "
+ " ADD COLUMN pub_year INTEGER");
}
};