隨著Android X 庫加入,Jetpack庫中的框架也越來越多的人使用了,這幾天去研究了下Jetpack庫中的Room框架,今天跟大家分享下。
一、簡介
1.Room是Goole發(fā)布的一個Sqlite數(shù)據(jù)庫。它提供了SQLite的抽象層,以便在充分利用SQLite的同時允許流暢的數(shù)據(jù)庫訪問。
Room框架的三個重要組成部分:
AppDatabase(數(shù)據(jù)庫)、@Entity(實體類)、@Dao(操作層)
2.優(yōu)勢:
① SQL查詢在編譯時就會驗證 - 在編譯時檢查每個@Query和@Entity等,這就意味著沒有任何運行時錯誤的風險可能會導致應用程序崩潰(并且它不僅檢查語法問題,還會檢查是否有該表)
② 較少的模板代碼
③ 與 LiveData集成
二、集成
1.項目根目錄build.gradle添加maven{url'https://jitpack.io'}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
2.APP的build.gradle添加Room引用庫
implementation 'androidx.room:room-runtime:2.2.5'
implementation 'androidx.room:room-compiler:2.2.5'
重新編譯一下即可。
三、使用Room框架進行增刪改查操作
(一)、AppDatabase、Entity、Dao三者的創(chuàng)建
1.Entity(實體類)創(chuàng)建
@Entity(tableName = "user_info") tablename:定義數(shù)據(jù)庫表中的名字,默認是以類名為表明
public class UserInfo {
@NonNull
@PrimaryKey(autoGenerate = true) :主鍵注解,autoGenerate 是否自增長
@ColumnInfo(name = "uuid") :聲明數(shù)據(jù)庫表中的字段名
public int uid;
@ColumnInfo(name = "user_name")
public String userName;
@Ignore
public UserInfo() {
}
public UserInfo(Integer uid, String userName) {
this.uid = uid;
this.userName = userName;
}
}
實體類定義必須確認下面幾點,否則編譯不通過:
1.類名頂部添加@Entity注解
2.Entity必須有一個字段聲明為主鍵,即需要加@PrimaryKey注解,且加@NonNull注解
3.Entity中如果有無參構造的話,必須加 @Ignore注解
2.Dao層創(chuàng)建
@Dao
public interface UserInfoDao {
@Query("SELECT * FROM userinfo ORDER BY uuid ASC")
List<UserInfo> getAll();
//查單獨的
@Query("SELECT * FROM userinfo WHERE uuid = :number")
UserInfo getUser(String number);
//查數(shù)組
@Query("SELECT * FROM userinfo WHERE uuid IN (:numbers)")
List<UserInfo> getUsers(List<String> numbers);
@Insert
void insertAll(UserInfo... users);
@Delete
void delete(UserInfo user);
//寫語句需要 用 Query 處理
@Query("UPDATE userinfo SET user_name=:name WHERE uuid=:number")
void update(String number, String name);
//更新全部字段,需添加onConflict = OnConflictStrategy.REPLACE
@Update(onConflict = OnConflictStrategy.IGNORE)
int update(UserInfo info);
}
Dao注意事項
1.Dao層頂部添加@Dao注解;
2.Dao文件可以是接口,也是可以是抽象類
3.數(shù)據(jù)庫創(chuàng)建
定義一個抽象類并繼承RoomDatabase

特別說明
1.若想導出數(shù)據(jù)創(chuàng)建文件,可以在APP的build.gradle的defaultConfig中添加下面代碼,項目運行成功后,在項目根目錄下會增加schemas文件夾。
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath = true
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
(二)、數(shù)據(jù)的增刪改查操作,下面是以用戶Dao層為實例
//增加
@Insert
void insertAll(UserInfo... users);
//修改,需添加onConflict = OnConflictStrategy.REPLACE
@Update(onConflict = OnConflictStrategy.IGNORE)
int update(UserInfo info);
//查詢
@Query("SELECT * FROM userinfo ORDER BY uuid ASC") :ASC :降序
List<UserInfo> getAll();
//查單獨的
@Query("SELECT * FROM userinfo WHERE uuid = :number")
UserInfo getUser(String number);
//查數(shù)組
@Query("SELECT * FROM userinfo WHERE uuid IN (:numbers)")
List<UserInfo> getUsers(List<String> numbers);
@Insert
void insertAll(UserInfo... users);
//刪除
@Delete
void delete(UserInfo user);
注:這里只是一些數(shù)據(jù)庫的基本操作,如果需要更復雜的數(shù)據(jù)庫操作,需要自己去寫SQL語句
(三)、具體調用(以數(shù)據(jù)查詢操作為例,其他的類似就不寫了,有問題可以隨時私聊我或是在評論區(qū)留言)
//請求列表數(shù)據(jù)
void requestList() {
@SuppressLint("StaticFieldLeak")
AsyncTask task = new AsyncTask<Object, List<UserInfo>, List<UserInfo>>() {
@Override
protected List<UserInfo> doInBackground(Object[] objects) {
List<UserInfo> userInfos = JetpackApplication.getApp().getAppDatabase().userInfoDao().getAll();
return userInfos;
}
@Override
protected void onPostExecute(List<UserInfo> userInfos) {
super.onPostExecute(userInfos);
mAdapter.setNewInstance(userInfos);
}
};
task.execute();
}
看到這里,想必大家也會有疑問?為什么要用AsyncTask 異步去請求呢?這個是因為>Room框架的所有操作都不能在UI線程中操作,否則會拋異常
IllegalStateException:Cannot access database on the main thread since >it may potentially lock the UI for a long period of time .
到此,Room框架的基本操作已分享。自己動手試一試吧!
如果你覺得該項目對你有用,動動你的小手指,舉手之勞,贊有余香!