Jetpack.jpg
1.前言
- 2018年谷歌I/O 發布了一系列輔助android開發者的實用工具,合稱 Jetpack ,以幫助開發者構建出色的 Android 應用。
- Jetpack 包含4個部分的組件:Architecture、Foundation、Behavior 以及 UI 。
- 今天為大家介紹的是 Architecture 中
Room
。 - 文章中實例 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_簡書!
不定期分享關于安卓開發的干貨。
寫技術文章初心
- 技術知識積累
- 技術知識鞏固
- 技術知識分享
- 技術知識交流