Android 官方架構元件--ROOM 資料庫操作簡單介紹
本文只是簡單的介紹一下怎麼在我們的專案中使用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,它也是下層的主要連線 的訪問點。
註解的類應該是一個抽象的繼承
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();
例子特別簡單,主要是瞭解一下這個元件