SqlBrite – 用 RxJava 來訪問數據庫
SqlBrite 是對 Android 系統的 SQLiteOpenHelper 和 ContentResolver 的輕量級 Rx 封裝,用來在 RxJava 中使用。
如何使用
創建一個 SqlBrite 對象,該對象是該庫的入口:
SqlBritesqlBrite = SqlBrite.create();
需要注意的是,為了方便調試查詢語句和結果,在創建 SqlBrite 的時候,可以指定一個 Logger 實現用來打印 log 信息。然后通過 BriteDatabase 或者 BriteContentResolver 的 setLoggingEnabled 函數來啟用或者關閉 log 。
然后提供一個 SQLiteOpenHelper 實例和一個 Scheduler 實例來創建一個 BriteDatabase 對象:
BriteDatabasedb = sqlBrite.wrapDatabaseHelper(openHelper, Schedulers.io());
如果是使用 ContentProvider 的話,需要使用 ContentResolver 來創建一個 BriteContentResolver 對象:
BriteContentResolvercr = sqlBrite.wrapContentProvider(contentResolver, Schedulers.io());
Scheduler 是指定執行查詢的操作的線程,由于查詢數據庫是不建議在 UI 線程中執行的,所以一般指定 Schedulers.io() 。
然后就需要使用 BriteDatabase 或者 BriteContentResolver 對象來查詢、更新、刪除數據了。
比如 BriteDatabase.createQuery 函數和 SQLiteDatabase.rawQuery 功能類似,參數有點不一樣。返回一個 Observable 對象,并執行需要的查詢語句。
Observable<Query> users = db.createQuery("users", "SELECT * FROM users");
users.subscribe(new Action1<Query>() {
@Override public void call(Queryquery) {
Cursorcursor = query.run();
// TODO parse data...
}
});
和 SQLiteDatabase.rawQuery 不同的是,這里需要指定所操作的數據庫表名字, sqlbrite 使用這個表的名字來通知其他監聽該表數據的 Observable 對象來更新數據。這就要求你只能通過 BriteDatabase 來訪問數據庫, 而不能使用 SQLiteOpenHelper 。
下面演示了數據變化通知功能:
final AtomicIntegerqueries = new AtomicInteger();
users.subscribe(new Action1<Query>() {
@Override public void call(Queryquery) {
queries.getAndIncrement();
}
});
System.out.println("Queries: " + queries.get()); // Prints 1
db.insert("users", createUser("jw", "Jake Wharton"));
db.insert("users", createUser("mattp", "Matt Precious"));
db.insert("users", createUser("strong", "Alec Strong"));
System.out.println("Queries: " + queries.get()); // Prints 4
當操作一個表的時候,所有訂閱到該表的訂閱者都可以收到數據變化的通知并返回新的數據。
如果不想接受數據更新了,則可以調用 Subscription 的 unsubscribe 函數來取消訂閱:
final AtomicIntegerqueries = new AtomicInteger();
Subscription s = users.subscribe(new Action1<Query>() {
@Override public void call(Queryquery) {
queries.getAndIncrement();
}
});
System.out.println("Queries: " + queries.get()); // Prints 1
db.insert("users", createUser("jw", "Jake Wharton"));
db.insert("users", createUser("mattp", "Matt Precious"));
s.unsubscribe();
db.insert("users", createUser("strong", "Alec Strong"));
System.out.println("Queries: " + queries.get()); // Prints 3
如果提交大量數據,則可以使用事務處理:
final AtomicIntegerqueries = new AtomicInteger();
users.subscribe(new Action1<Query>() {
@Override public void call(Queryquery) {
queries.getAndIncrement();
}
});
System.out.println("Queries: " + queries.get()); // Prints 1
Transactiontransaction = db.newTransaction();
try {
db.insert("users", createUser("jw", "Jake Wharton"));
db.insert("users", createUser("mattp", "Matt Precious"));
db.insert("users", createUser("strong", "Alec Strong"));
transaction.markSuccessful();
} finally {
transaction.end();
}
System.out.println("Queries: " + queries.get()); // Prints 2
還可以在 Transaction 對象上用 try-with-resources
由于查詢只是普通的 RxJava Observable 對象,所以可以在上面使用各種操作函數:
users.debounce(500, MILLISECONDS).subscribe(new Action1<Query>() {
@Override public void call(Queryquery) {
// TODO...
}
});
設計理念
SqlBrite 僅僅是一個用來協調更新數據和通知數據變化的輕量級封裝,當你對數據表進行操作的時候,其他訂閱者可以在數據發生變化的時候收到通知。然后可以用 RxJava 的方式來操作數據。
SqlBrite 不是一個 ORM 框架,也不是一個類型安全的查詢框架。也不會提供數據庫遷移的功能。所以 SqlBrite 的代碼很簡單,只有六個類幾百行代碼。
來自:http://blog.chengyunfeng.com/?p=990