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");
}
};