本文涉及Library的版本以下:java
Room爲了SQLite提供了一個抽象層,對Android SQLite進行了封裝 , 更加方便地進行數據庫訪問。android
Room主要有3個組件:sql
Room架構圖以下:數據庫
從上圖能夠知道,應用層須要定義有哪些表; 定義數據訪問對象; 定義數據庫,好比說數據庫名稱,有哪些些表等。下面結合一些簡單的代碼例子:bash
// 定義User表, 用Entity註解來表示這個類是一個數據庫表
@Entity
public class User {
// 使用ColumnInfo註解定義一個字段名, 不用註解默認去變量名
@ColumnInfo(name = "first_name")
public String firstName;
@PrimaryKey // 主鍵
public int id;
}
複製代碼
// 定義數據訪問對象的接口
@Dao
public interface UserDao { // 定義成接口
// Query註解定義查詢, 參數是sql語句
@Query("SELECT * FROM user")
List<User> getAll();
// 根據id查詢user, :id這裏意思是引用findById方法裏參數id。是room定義固定寫法:冒號+參數名稱
@Query("SELECT * FROM user WHERE id = :id")
User findById(String id);
//Update註解定義更新User
@Update
void udapte(User user);
//Insert註解定義插入User
@Insert
void insert(User user);
//Delete註解定義刪除User
@Delete
void delete(User user);
}
複製代碼
//定義AppDatabase類,須要是abstract的,繼承RoomDatabase
//使用Database註解,定義entities類, entities參數是一個class[],version是數據庫的版本號
@Database(entities = {User.class, Favorite.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
public abstract FavoriteDao favoriteDao();
private static final String DB_NAME = "room_demo";
private static volatile AppDatabase sInstance;
//一般定義一個單例持有AppDatabase引用
//DB_NAME是數據庫文件名稱
public static AppDatabase getInstance(Application app){
if(sInstance == null){
synchronized (AppDatabase.class){
if(sInstance == null){
sInstance = Room.databaseBuilder(app,
AppDatabase.class, DB_NAME).build();
}
}
}
return sInstance;
}
}
//操做數據庫增刪查
mAppDatabase = AppDatabase.getInstance(this.getApplication());
mAppDatabase.userDao().delete(user);
mAppDatabase.userDao().insert(user);
mAppDatabase.userDao().getAll();
複製代碼
經過RoomDatabase.Builder.addMigrations()添加Migration去實現。代碼示例以下:架構
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// database.execSQL("");執行sql語句
}
};
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// database.execSQL("");執行sql語句
}
};
Room.databaseBuilder(app,AppDatabase.class, DB_NAME)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build();
複製代碼
在定義Dao接口時,能夠直接LiveData和Flowable來做爲返回數據類型。app
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
LiveData<List<User>> getUsersLiveData();
@Query("SELECT * FROM user")
Flowable<List<User>> getUsersFlowable();
}
//LiveData使用例子
public class RoomActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRoomModel = ViewModelProviders.of(this).get(RoomModel.class);
mRoomModel.getUsersLiveData().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
adapter.setData(users);//更新UI
}
});
}
}
public class RoomModel extends AndroidViewModel {
private final AppDatabase mAppDatabase;
public RoomModel(@NonNull Application application) {
super(application);
mAppDatabase = AppDatabase.getInstance(this.getApplication());
}
public LiveData<List<User>> getUsersLiveData() {
return mAppDatabase.userDao().getUsersLiveData();
}
}
//RxJava使用例子
mAppDatabase.userDao().getUsersFlowable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<User>>() {
@Override
public void accept(List<User> users) throws Exception {
adapter.setData(users);//更新UI
}
});
複製代碼
對RxJava不熟悉本身去了解, 對 LiveData不瞭解能夠我以前的文章LiveDataide
利用註解Database而且繼承RoomDatabase,究竟是怎麼生存數據庫post
數據訪問只須要定義一個DAO接口, Dao接口真正實現是怎樣的,增刪改查是如何實現的ui
是如何擴展RxJava和LiveData, 而且如何能監聽Flowable和LiveData數據的變動
參考:*