初试Google Agera database
February 10, 2017
(内白:第一次真正意义上写博客,这几年来开发路程遇到过许多问题,但都是简单标记一下,并没有记录下来,等过段时间遇到同样问题脑袋一热都忘了又得翻翻翻,特此开始写博客记录我的开发路程,老了,记忆力下降了,再过几年连代码都不会打了。。。 0 0)
进入主题,最近打算用 agera 运用在新项目上,本来打算 rxjava,貌似个个都在用。。但是对比了一下 agera 和 rxjava,感觉在 android 上使用 agera 更适合,个人觉得 rxjava 的确很强大,但是操作符有点乱,什么 action1、action2,虽然后面 rxjava2 更改并加强了概念,还是觉得使用起来有时候会忘记,况且 agera 跟 android 生命周期绑定,所以选择了 agera
那么开始吧,先从常用的 sqlite 入手
依赖
Google 官网出了一个 database 的库,就是基于 Agera 概念封装了一下 sqlite,使用方法如下
compile 'com.google.android.agera:agera:1.2.0'
compile 'com.google.android.agera:database:1.2.0'
Agera Github 地址: https://github.com/google/agera 还有中文翻译: https://github.com/captain-miao/AndroidAgeraTutorial/wiki
首先是创建一个 SQLiteOpenHelper
这里 database 库里有个SqlDatabaseSupplier
帮我们继承了SQLiteOpenHelper
并且实现了一个Supplier
接口(这个 Supplier 接口是使用 agera 必须实现的),所以直接继承SqlDatabaseSupplier
就行了
public class BikeDBHelper extends SqlDatabaseSupplier {
private static final String DB_NAME = "DB.db";
public static final String TABLE_NAME = "Bikes";
public BikeDBHelper(@NonNull Context context) {
super(context, DB_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table if not exists " + TABLE_NAME + " (id integer primary key,num text)";
db.execSQL(sql);
//插入两条数据模拟一下
db.execSQL("insert into " + TABLE_NAME + " (id,num) values (1,'123456')");
db.execSQL("insert into " + TABLE_NAME + " (id,num) values (2,'254365')");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//do nothing
}
}
下面是SqlDatabaseSupplier
的源码,很简单
/**
* Abstract extension of {@link SQLiteOpenHelper} implementing a sql database {@link Supplier} to be
* used with the {@link SqlDatabaseFunctions}.
*/
public abstract class SqlDatabaseSupplier extends SQLiteOpenHelper
implements Supplier<Result<SQLiteDatabase>> {
/**
* Extending the base constructor, for overriding in concrete implementations.
*/
public SqlDatabaseSupplier(@NonNull final Context context, @NonNull final String path,
@Nullable final CursorFactory factory, final int version) {
super(context, path, factory, version);
}
@NonNull
@Override
public final synchronized Result<SQLiteDatabase> get() {
try {
return absentIfNull(getWritableDatabase());
} catch (final SQLException e) {
return failure(e);
}
}
}
创建 Repository
在 agera 最重要的就是这个Repository
了,先从查询开始
Repository<Result<List<Bike>>> query = Repositories.repositoryWithInitialValue(Result.<List<Bike>>absent())
.observe(onSearchObservable)//这里观察一个按钮,点击按钮就获取一次
.onUpdatesPerLoop()//刷新频率
.getFrom(new Supplier<String>() {
@NonNull
@Override
public String get() {
return "";//可以是查询条件
}
})
.goTo(EXECUTOR)//异步
.transform(new Function<String, SqlRequest>() {
@NonNull
@Override
public SqlRequest apply(@NonNull String input) {
//这里的input就是getFrom返回的字符串,可以是查询条件,根据查询条件创建不同的SqlRequest
return SqlRequests.sqlRequest()
.sql("SELECT * FROM " + BikeDBHelper.TABLE_NAME)
.compile()
}
})
.thenTransform(SqlDatabaseFunctions.databaseQueryFunction(new BikeDBHelper(this), new Function<Cursor, Bike>() {
@NonNull
@Override
public Bike apply(@NonNull Cursor cursor) {
return new Bike(
cursor.getString(cursor.getColumnIndex("num"))
);
}
}))
.compile();
重点就是最后一步thenTransform
,将SqlRequest
转换成Result<List<Bike>>
。官网提供了SqlDatabaseFunctions
类,里面有数据库增删改查四个方法,这里用到的就是查询databaseQueryFunction
方法,通过传入一个Supplier<Result<SQLiteDatabase>>
,就是一开始创建的BikeDBHelper
,还传入一个Function
将里面处理好的游标Cursor
提供给我们去获取转换成该游标下的数据,至此转换成最后需要的Result<List<Bike>>
/**
* Creates a sql query {@link Function}.
*/
@NonNull
public static <T> Function<SqlRequest, Result<List<T>>> databaseQueryFunction(
@NonNull final Supplier<Result<SQLiteDatabase>> database,
@NonNull Function<Cursor, T> rowMap) {
return new DatabaseFunction<>(database, new DatabaseQueryMerger<>(rowMap));
}
push event
@Override
protected void onResume() {
super.onResume();
query.addUpdatable(this);
}
@Override
protected void onPause() {
super.onPause();
query.removeUpdatable(this);
}
pull data
@Override
public void update() {
query.get().ifSucceededSendTo(this);
}
@Override
public void accept(@NonNull List<Bike> value) {
mMainAdapter.setList(value);
}
总结
创建Repository
过程中涉及到一个SqlRequest
,这其实就是一个查询 request,针对增删改还有SqlInsertRequest``SqlDeleteRequest``SqlUpdateRequest
一共四种 request,都是通过SqlRequests
创建。其实整个 database 库很小,一共也就几个类,所以使用起来还是挺方便的,重点还是得理解 Repository。
— Evil Mouth