Android Jetpack - Room 介紹

Jetpack.jpg

1.前言

  • 2018年谷歌I/O 發布了一系列輔助android開發者的實用工具,合稱 Jetpack ,以幫助開發者構建出色的 Android 應用。
  • Jetpack 包含4個部分的組件:Architecture、Foundation、Behavior 以及 UI
  • 今天為大家介紹的是 ArchitectureRoom
  • 文章中實例 linhaojian的Github

2.簡介

  • 介紹 :
    Room 是Google為了簡化舊式的SQLite操作專門提供的一個覆蓋SQLite抽象層框架庫
  • 作用:
    1.實現SQLite的增、刪、查、改功能。
  • 特點:
    1.使用簡單(類似于Retrofit庫),通過注解的方式實現相關功能。
    2.擁有SQLite的所有操作功能(表所有操作、版本升級....)。

3.說明

  • 主要角色說明
    • Bean : 實體類,表示數據庫表的數據。
    • Dao : 數據操作類,包含用于訪問數據庫的方法。
    • Database : 數據庫持有者 & 數據庫版本管理者。
    • Room : 數據庫的創建者 & 負責數據庫版本更新的具體實現者。
  • 注釋說明
    1.Bean(實體)
    • @Entity : 數據表的實體類。
    • @PrimaryKey : 每一個實體類都需要一個唯一的標識。
    • @ColumnInfo : 數據表中字段名稱。
    • @Ignore : 標注不需要添加到數據表中的屬性。
    • @Embedded : 實體類中引用其他實體類。
    • @ForeignKey : 外鍵約束。
@Entity
public class User {
    @PrimaryKey(autoGenerate = true)//autoGenerate 為true時,自增;
    private int uid;
    @ColumnInfo(name = "name")
    private String name;
    @Ignore
    private String remark;
    @Embedded
    public Address address;
}
public class Address {
    public String street;
    public String state;
    public String city;
    @ColumnInfo(name = "post_code")
    public int postCode;
}
@Entity(foreignKeys = @ForeignKey(entity = User.class,
                                  parentColumns = "uid",
                                  childColumns = "user_id"))
public class Book {
    @PrimaryKey
    public int bookId;
    public String title;
    @ColumnInfo(name = "user_id")
    public int userId;
}

2.Dao(數據庫操作類)

  • @Dao : 標注數據庫操作的類。
  • @Query : 包含所有Sqlite語句操作。
  • @Insert : 標注數據庫的插入操作。
  • @Delete : 標注數據庫的刪除操作。
  • @Update : 標注數據庫的更新操作。
@Dao
public interface UserDao {
    @Query("Select * from user")
    List<User> getAll();
    @Query("Select * from user Where uid In (:userIds)")
    List<User> loadAllByIds(int[] userIds);
    @Insert
    void insertAll(User... users);
    @Delete
    void delete(User... users);
    @Update
    void update(User... users);
    @Query("update user set name =:name1 where uid=:uid")
    void updateCustom(String name1, int uid);
}

3.Database(數據庫持久化)

  • @Database : 標注數據庫持久化的類。
@Database(entities = {User.class},version = 1)
public abstract class AppDataBase extends RoomDatabase {
    public abstract UserDao getUserDao();
}

4.基本使用

4.1 Lib引用

    // room
    implementation 'android.arch.persistence.room:runtime:1.1.1'
    annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'

4.2 User 實體

@Entity
public class User {
    @PrimaryKey(autoGenerate = true)//autoGenerate 為true時,自增;
    private int uid;
    @ColumnInfo(name = "name")
    private String name;
}

4.3 Dao 操作類

@Dao
public interface UserDao {
    @Query("Select * from user")
    List<User> getAll();
    @Insert
    void insertAll(User... users);
    @Delete
    void delete(User... users);
    @Update
    void update(User... users);
}

4.4 DataBase 數據庫持久化

@Database(entities = {User.class},version = 1)
public abstract class AppDataBase extends RoomDatabase {
    public abstract UserDao getUserDao();
}

4.5 Room初始化

每一次初始化數據庫對象都需要消費較大的資源,因此可以通過單例的方式,實現一個進程中公用一個數據庫對象。

public class DBInstance {
    private static final String DB_NAME = "room_test";
    public static AppDataBase appDataBase;
    public static AppDataBase getInstance(Context context){
        if(appDataBase==null){
            synchronized (DBInstance.class){
                if(appDataBase==null){
                     return Room.databaseBuilder(context,AppDataBase.class, DB_NAME)
                             .build();
                }
            }
        }
        return appDataBase;
    }
}

4.6 應用

通過DbInstance獲取AppDataBase單例 & 操作User數據表

    //獲取數據
    List<User> list = DBInstance.getInstance(getApplicationContext()).getUserDao().getAll();
    //插入數據
    User user = new User();
    user.setName("linhaojian");
    DBInstance.getInstance(getApplicationContext()).getUserDao().insertAll(user);
    //更新數據
    user.setUid(1);
    user.setName("linhaojian");
    DBInstance.getInstance(getApplicationContext()).userDao().update(user);
    //刪除數據
    DBInstance.getInstance(getApplicationContext()).getUserDao().delete(user);

5.進階

5.1 版本更新

  • 在User對象中,添加多一個屬性:sex,看看修改的步驟有哪些:
    1.User實體中添加sex屬性
@Entity
public class User {
    @PrimaryKey(autoGenerate = true)//autoGenerate 為true時,自增;
    private int uid;
    @ColumnInfo(name = "name")
    private String name;
    @ColumnInfo(sex= "sex")
    private String sex;
}

2.修改DateBase的版本信息 1 -> 2

@Database(entities = {User.class},version = 2)
public abstract class AppDataBase extends RoomDatabase {
    public abstract UserDao getUserDao();
}

3.添加一個Migration & 實現版本更新的具體內容

    public static Migration MIGRATION_1_2 = new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("alter table user add column sex text");
        }
    };

4.在數據庫初始化中添加Migration

Room.databaseBuilder(context,AppDataBase.class, DB_NAME)
                             .addMigrations(
                                     VersionDataBase.MIGRATION_1_2)
                             .build()

完成上述4個步驟就可以更新數據庫,非常方便,不再像舊式Sqlite需要修改實體類、數據庫更新類,還要修改具體的數據表操作的相關方法(增刪查改)。

5.2 沖突條款(ON CONFLICT)

conflict-clause.gif

沖突條款 : 就是針對出現約束異常(ROLLBACK, ABORT, FAIL, IGNORE, and REPLACE)的非標準處理。

  • ABORT : 默認值,不處理約束異常。
  • ROLLBACK : 與ABORT相似,不常用。
  • FAIL : 在批量更新或者修改時,中途出現了約束異常,就會終止后續執行,但會保留已執行的sql語句。
  • IGNORE : 忽略約束異常,不做任何處理保留原數據。
  • REPLACE : 當出現約束異常時,移除原數據 & 將新數據覆蓋。
  • 使用方式
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    @Update(onConflict = OnConflictStrategy.REPLACE)

6.總結

  • 到此,Room就介紹完成了。后續我會進行分享Jetpack更多其他內容。
  • 如果喜歡我的分享,可以點擊 關注 或者 ,你們支持是我分享的最大動力 。
  • linhaojian的Github

歡迎關注linhaojian_CSDN博客或者linhaojian_簡書

不定期分享關于安卓開發的干貨。


寫技術文章初心

  • 技術知識積累
  • 技術知識鞏固
  • 技術知識分享
  • 技術知識交流
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容