Android-Room數(shù)據(jù)庫(kù)-多表查詢(Relationships)
Android-Room自定義類型(TypeConverter)
Android—Room?數(shù)據(jù)庫(kù)遷移(Migration)
Android — Room?數(shù)據(jù)庫(kù)跳躍式升級(jí)(Migration)
Android—Room 通用封裝
前言
Google終于發(fā)布了一個(gè)和SQLite相關(guān)的庫(kù)了??????。之前一直都是在SQLite、XUtils、greenDao、Realm這些數(shù)據(jù)庫(kù)之間來(lái)回折騰?,F(xiàn)在終于有一個(gè)更“正統(tǒng)”數(shù)據(jù)庫(kù)了。
Room是什么?
Room是一個(gè)持久性數(shù)據(jù)庫(kù)。
Room持久性庫(kù)提供了SQLite的抽象層,以便在充分利用SQLite的同時(shí)允許流暢的數(shù)據(jù)庫(kù)訪問(wèn)。
為什么會(huì)選擇Room?
前面我也說(shuō)到了現(xiàn)在也有不少開源的數(shù)據(jù)庫(kù)給大家使用,那為什么我們還要去學(xué)習(xí)使用這個(gè)庫(kù)呢?當(dāng)然不是我前面說(shuō)的“正不正統(tǒng)”的原因了。
因?yàn)镽oom有下面幾個(gè)優(yōu)點(diǎn):
① SQL查詢?cè)诰幾g時(shí)就會(huì)驗(yàn)證 - 在編譯時(shí)檢查每個(gè)@Query和@Entity等,這就意味著沒(méi)有任何運(yùn)行時(shí)錯(cuò)誤的風(fēng)險(xiǎn)可能會(huì)導(dǎo)致應(yīng)用程序崩潰(并且它不僅檢查語(yǔ)法問(wèn)題,還會(huì)檢查是否有該表)
② 較少的模板代碼
③ 與 LiveData集成
該如何使用它?
1、在app/build.gradle中添加以下依賴
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
你可以點(diǎn)擊這里查看最新依賴版本號(hào)
2、創(chuàng)建JavaBean
@Entity
public class User {
@PrimaryKey(autoGenerate = true)//主鍵是否自動(dòng)增長(zhǎng),默認(rèn)為false
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//這里的getter/setter方法是必須的
//這里的getter/setter方法是必須的
//這里的getter/setter方法是必須的
//重要的事說(shuō)三遍
}
- 這里需要使用
@Entity來(lái)注解該類 - 至少要有一個(gè)主鍵
@PrimaryKey
3、創(chuàng)建Dao
接下來(lái),需要為我們的實(shí)體創(chuàng)建DAO。 DAO代表數(shù)據(jù)訪問(wèn)對(duì)象,所以它是告訴我們的數(shù)據(jù)庫(kù)如何操作數(shù)據(jù)的一種方式:
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAllUsers();
@Insert
void insert(User... users);
@Update
void update(User... users);
@Delete
void delete(User... users);
}
- 使用
@Dao注解該接口 -
@Insert,@Update,@Delete,@Query代表我們常用的插入、更新、刪除、查詢數(shù)據(jù)庫(kù)操作
@Insert, @Update, @Delete可以傳入多種不同的參數(shù)。例如:
@Insert
void insert(User... users);
@Insert
void insert(User user);
@Insert
void insert(List<User> userLists);
同理,@Query也可以返回多種不同的類型。
@Query("SELECT * FROM user")
List<User> getAllUsers();
@Query("SELECT * FROM user WHERE id=:id")
User getUser(int id);
@Query("SELECT * FROM user")
Cursor getUserCursor();
當(dāng)然,除了這些我們還可以傳入一些限制符進(jìn)去。例如,
@Query("SELECT * FROM user WHERE age=:age")
List<User> getUsersByAge(int age);
@Query("SELECT * FROM user WHERE age=:age LIMIT :max")
List<User> getUsersByAge(int max, int... age);
4、創(chuàng)建數(shù)據(jù)庫(kù)
@Database(entities = { User.class }, version = 1,exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {
private static final String DB_NAME = "UserDatabase.db";
private static volatile UserDatabase instance;
static synchronized UserDatabase getInstance(Context context) {
if (instance == null) {
instance = create(context);
}
return instance;
}
private static UserDatabase create(final Context context) {
return Room.databaseBuilder(
context,
UserDatabase.class,
DB_NAME).build();
}
public abstract UserDao getUserDao();
}
這里使用@Database注解該類并添加了表名、數(shù)據(jù)庫(kù)版本(每當(dāng)我們改變數(shù)據(jù)庫(kù)中的內(nèi)容時(shí)它都會(huì)增加),所以這里使用exportSchema = false
注意:除了添加表映射的類以及和數(shù)據(jù)庫(kù)版本外,還要添加
exportSchema = false否則會(huì)報(bào)警告。
Error:(10, 17) 警告: Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provideroom.schemaLocationannotation processor argument OR set exportSchema to false.
我們抽象了getUserDao()方法,這是必要的。
5、使用數(shù)據(jù)庫(kù)
我們終于能夠操作我們的數(shù)據(jù)庫(kù)了。但是所有的操作必須在后臺(tái)線程中完成。你可以通過(guò)使用AsyncTask,Thread,Handler,RxJava或其它方式來(lái)完成。
如果沒(méi)有在后臺(tái)線程執(zhí)行,并且也沒(méi)有說(shuō)明可以在主線程操作的話,就會(huì)報(bào)以下錯(cuò)誤。
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
例如,我們可以像下面這樣插入數(shù)據(jù)
User user=new User();
user.setName("name1");
user.setAge(18);
UserDatabase
.getInstance(context)
.getUserDao()
.insert(user);
或者這樣
List<User> allUsers = UserDatabase
.getInstance(RoomActivity.this)
.getUserDao()
.getAllUsers();
好了,基本的使用的方式就這些了。未完待續(xù)