本文只是简单的介绍一下怎么在我们的项目中使用ROOM和一个简单的小例子。
ROOM是Google官方推出的一个持久性数据库,Room持久性库提供了SQLite的抽象层,以便在充分利用SQLite的同时允许流畅的数据库访问。
ROOM的引用:
compile "android.arch.persistence.room:runtime:1.0.0" annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
ROOM数据库,一共有三个部分:DAO、Entity、Database;
DAO:这个组件代表了一个类或者接口作为DAO。DAOs 是Room中的主要组件,并且负责定义访问数据库的方法。被注解为@Database的类必须包含一个没有参数的抽象方法并且返回注解为@Dao的类。当在编译时生成代码,Room创建一个这个类的实现。(其实里面就是对数据库的增删改查操作)
Entity:这个组件代表了一个持有数据行的类。对于每个entity,一个数据库表被创建用于持有items。你必须引用entity类通过Database类中的entities数组。每个entity字段被持久化到数据库中除非你注解它通过@Ignore(这个就是某一个表的具体字段)
Database: 你可以使用这个组件创建一个数据库holder。注解定义了一系列entities并且类的内容提供了一系列DAOs,它也是下层的主要连接 的访问点。
注解的类应该是一个抽象的继承 RoomDatabase的类。在运行时,你能获得一个实例通过调用Room.databaseBuilder()或者 Room.inMemoryDatabaseBuilder()(这个就是数据库,包括创建数据库、数据库的更新等)
1、我们创建Entity
@Entity(tableName = "tb_student",//定义表名
indices = @Index(value = {"name", "sex"}, unique = true))
public class StudentEntity{
@PrimaryKey //定义主键
private long id;
@ColumnInfo(name = "name")//定义数据表中的字段名
private String name;
@ColumnInfo(name = "sex")
private int sex;
@Ignore//指示Room需要忽略的字段或方法
private String ignoreText;
}
首先@Entity是标识。其中tableName:是表名,PrimaryKey 主键是必须创建的,也是唯一的,value:就是各个字段的声明,"indices"、"unique"两个可以指定某个字段不能重复(举例:上述的name、sex两个字段存储的时候不允许有重复,不能存了一个张三、男,然后再存一个张三、男,这样的话会直接抛出异常),Ignore:是忽略的意思,不会保存到数据库中。
还有一个重要的外键(也就是和其他表关联)比如Student表中增加一个class_id字段与Class表的id主键关联:
foreignKeys ={@ForeignKey(entity=ClassEntity.class,parentColumns = "id",childColumns = "class_id")}
2、创建DAO:
@Dao
public interface StudentDao {
@Query("SELECT * FROM tb_student")
public List<StudentEntity> getAll();
@Query("SELECT * FROM tb_student WHERE id IN (:ids)")
List<StudentEntity> getAllByIds(long[] ids);
@Query("SELECT * FROM tb_student WHERE id = :id")
StudentEntity getById(int id);
@Insert
void insert(StudentEntity... entities);
@Delete
void delete(StudentEntity entity);
@Update
void update(StudentEntity entity);
}
首先@DAO是标识。里面主要也就是增删改查四个方法,其中查找可以根据不同条件进行查找。
3、创建Database:
@Database(entities = StudentEntity.class,version = 1,exportSchema = false)
public abstract class RoomDemoDatabase extends RoomDatabase {
private static final String DB_NAME = "UserDatabase.db";
private static volatile RoomDemoDatabase instance;
static synchronized RoomDemoDatabase getInstance(Context context) {
if (instance == null) {
instance = create(context);
}
return instance;
}
private static RoomDemoDatabase create(final Context context) {
return Room.databaseBuilder(
context,
RoomDemoDatabase.class,
DB_NAME).build();
}
public abstract StudentDao studentDao();
}
其中@Database是声明,里面的entities是对应的Entity,如果有多个的话,使用如下方式:entities={StudentEntity.clss,ClassEntity.class},version是数据库版本,
exportSchema:存储展示数据库的结构信息,如果不设置的话,需要再database类上配置exportSchema = false,要不然编译的时候会出现警告。
defaultConfig {
minSdkVersion 19
targetSdkVersion 26
javaCompileOptions {
annotationProcessorOptions {
arguments =["room.schemaLocation":"$projectDir/schemas".toString()]
}
}
}
创建数据库时有一些设置:
Room.databaseBuilder(this, RoomDemoDatabase.class,"database_name").allowMainThreadQueries(). fallbackToDestructiveMigration().build();
allowMainThreadQueries()允许再主线程查询:
fallbackToDestructiveMigration():如果两次运行的数据库版本号不一致的话,则将上个版本的数据库删除重新创建。
正常我们升级数据库操作应如下方式:
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");
}
};
4、我们的Entity、DAO、Database都创建完成了,可以使用代码测试一下了
StudentDao dao=RoomDemoDatabase.getInstance(this).studentDao();
StudentEntity entity=new StudentEntity();
entity.setName("nih33o5");
entity.setIgnoreText("ddddddd335");
entity.setSex(1);
entity.setId(1);
dao.insert(entity);
List<StudentEntity>list=dao.getAll();
例子特别简单,主要是了解一下这个组件