天天看點

Android Room從入門到放棄

  Android 2017 IO大會推出了官方資料庫架構:Room。Room其實就隻是對原生的SQLite API進行了一層封裝。

簡單使用:

  1. 和正常的ORM架構一樣,讓Entity對應資料庫表,然後通過添加編譯期注解來進行表和字段的配置,例如:
@Entity
public class Student implements Serializable {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "student_name")
    public String name;

    @Embedded(prefix = "address_")
    public Address address;
}
           
  1. 用抽象DAO類來定義資料庫的CRUD操作,例如:
@Dao
public abstract class StudentDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public abstract void insert(Student... students);

    @Delete
    public abstract void delete(Student... students);

    @Update
    public abstract void update(Student... students);

    @Query("DELETE FROM Student")
    public abstract void deleteAll();
}
           
  1. AppDatabase對應資料庫,同時用來提供DAO類
@Database(entities = {Student.class}, version = , exportSchema = false)
public abstract class AppDatabase extends RoomDatabase{
    public abstract StudentDao studentDao();
}
           
  1. 調用範例
AppDatabase mDatabase = Room.databaseBuilder(this, AppDatabase.class, "app").addMigrations().build();
StudentDao dao = mDatabase.studentDao();
Student student = new Student();
student.id = ;
students.add(student);
           

原理: 在編譯時,使用annotationProcessor來解析被@Database和@Dao标注的類,在build/generated/source/apt裡生成具體的Impl類,相比于SQLite API,一定程度上減少了我們建立表和部分CRUD書寫的代碼量。

優點:

1. 分層清晰,上手簡單,代碼相比于第三方也更加可靠

2. 非基于運作時注解,僅對SQLite API進行簡單封裝,效率沒問題

3. 存儲對象裡嵌套對象時,可使用@Embedded注解進行自動拆分存儲。Room會把被嵌套對象裡的字段放置存儲對象對應的表裡,例如上例,Student表裡不僅會有id和name字段,還會有address對象裡的所有字段。這樣就可以不用通過外鍵關聯多表了。

缺點:

1. 查詢和需要判斷條件的删改都免不了要寫SQL語句,雖然Room把語句拼寫錯誤的提示提前到了編譯時,但仍然需要關心表名、字段名等

2. 資料庫更新無法自動且未提供友好API,同樣需要寫SQL語句,開發者手動寫”ALTER table”在多表外鍵關聯時容易出錯。