Android SqlDelight和SqlBrite无缝结合使用的Demo例子
2017-03-17 11:41
447 查看
Android SqlDelight详解和Demo例子: 点我
Android SqlBrite使用介绍和官方demo详解: 点我
Android AutoValue使用和扩展库: 点我
在说到SqlBrite的时候有介绍到它的官方的例子,官方的栗子是没有用到SqlDelight的。这里我在这个例子的基础上添加SqlDelight,实现SqlBrite和SqlDelight的无缝连接。
这里我偷个懒,fork了SqlBrite的源码,然后添加了Sqldelight的栗子的module,然后把Sqldelight和SqlBrite的代码都加了中文注释; 然后再写了了一个Module,在SqlBrite的sample的基础上无缝结合SqlDelight。
sqlbrite_sqldelight_sample的Github地址: https://github.com/tpnet/sqlbrite
SqlBrite结合了SqlDelight之后:
可以看到: 结合后的bean我们写的代码量少了,组合ContentValues这些事情不用我们手动做了,解析cursor不用我们手动做了,各种操作对象可以放在这里。
结合后:
可以看到: 结合后的SQLiteOpenHelper sql语句不用组合放在这里,清晰多了; 创表语句放在sq文件中,在自动生成的model,也可以得到创表的语句; 插增删改查利用bind来实现,更方便了,不用自己组合ContentValue,逻辑清晰,代码简介。
结合后:
可以看到结合后的Curor解析不用我们手动解析,对应的查询语句和参数可以在SqlDelightStatement获取。
结合后:
可以看到结合后:利用了SqlDelight生成的对应的Model类进行更新插入,不需要自己编写ContentValue,更方便的插入。
当然还有其他的变化。大家可以看看源码。
Android SqlBrite使用介绍和官方demo详解: 点我
Android AutoValue使用和扩展库: 点我
在说到SqlBrite的时候有介绍到它的官方的例子,官方的栗子是没有用到SqlDelight的。这里我在这个例子的基础上添加SqlDelight,实现SqlBrite和SqlDelight的无缝连接。
这里我偷个懒,fork了SqlBrite的源码,然后添加了Sqldelight的栗子的module,然后把Sqldelight和SqlBrite的代码都加了中文注释; 然后再写了了一个Module,在SqlBrite的sample的基础上无缝结合SqlDelight。
sqlbrite_sqldelight_sample的Github地址: https://github.com/tpnet/sqlbrite
结合前和结合后的对比
这里以sqlbrite_sqldelight_sample 和 sqlbrite_sample作为例子:1. bean类对比
SqlBrite没有结合SqlDelight:@AutoValue public abstract class TodoList implements Parcelable { public static final String TABLE = "todo_list"; public static final String ID = "_id"; public static final String NAME = "name"; public static final String ARCHIVED = "archived"; public abstract long id(); public abstract String name(); public abstract boolean archived(); //利用RXjava进行数据的获取,返回bean列表 public static Func1<Cursor, List<TodoList>> MAP = new Func1<Cursor, List<TodoList>>() { @Override public List<TodoList> call(final Cursor cursor) { try { List<TodoList> values = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { long id = Db.getLong(cursor, ID); String name = Db.getString(cursor, NAME); boolean archived = Db.getBoolean(cursor, ARCHIVED); values.add(new AutoValue_TodoList(id, name, archived)); } return values; } finally { cursor.close(); } } }; //构建器,用来生成ContentValues public static final class Builder { private final ContentValues values = new ContentValues(); public Builder id(long id) { values.put(ID, id); return this; } public Builder name(String name) { values.put(NAME, name); return this; } public Builder archived(boolean archived) { values.put(ARCHIVED, archived); return this; } public ContentValues build() { return values; // TODO defensive copy? } } }
SqlBrite结合了SqlDelight之后:
@AutoValue public abstract class TodoList implements TodoListModel,Parcelable { public abstract class TodoList implements TodoListModel,Parcelable { public final static Factory<TodoList> FACTORY = new Factory<>(new TodoListModel.Creator<TodoList>() { @Override public TodoList create(long _id, @NonNull String name, @Nullable String archived) { return new AutoValue_TodoList(_id, name, archived); } }); @AutoValue public abstract static class ListsItem implements Parcelable, List_queryModel { } public static Func1<Cursor, ListsItem> LIST_ITEM_FUNC = new Func1<Cursor, ListsItem>() { @Override public ListsItem call(Cursor cursor) { return LIST_ITEM_MAPPER.map(cursor); } }; //查询title映射 public final static RowMapper<String> ROW_TITLE_MAPPER = FACTORY.title_queryMapper(); public final static RowMapper<ListsItem> LIST_ITEM_MAPPER = FACTORY.list_queryMapper(new List_queryCreator<ListsItem>() { @Override public ListsItem create(long _id, @NonNull String name, long item_count) { return new AutoValue_TodoList_ListsItem(_id, name, item_count); } }); } }
可以看到: 结合后的bean我们写的代码量少了,组合ContentValues这些事情不用我们手动做了,解析cursor不用我们手动做了,各种操作对象可以放在这里。
2. SQLiteOpenHelper类对比
结合前:final class DbOpenHelper extends SQLiteOpenHelper { private static final int VERSION = 1; //创建todo_list表的语句 private static final String CREATE_LIST = "" + "CREATE TABLE " + TodoList.TABLE + "(" + TodoList.ID + " INTEGER NOT NULL PRIMARY KEY," + TodoList.NAME + " TEXT NOT NULL," + TodoList.ARCHIVED + " INTEGER NOT NULL DEFAULT 0" + ")"; //创建todo_item表的语句 private static final String CREATE_ITEM = "" + "CREATE TABLE " + TodoItem.TABLE + "(" + TodoItem.ID + " INTEGER NOT NULL PRIMARY KEY," + TodoItem.LIST_ID + " INTEGER NOT NULL REFERENCES " + TodoList.TABLE + "(" + TodoList.ID + ")," + TodoItem.DESCRIPTION + " TEXT NOT NULL," + TodoItem.COMPLETE + " INTEGER NOT NULL DEFAULT 0" + ")"; //创建 单列索引,加速查询 private static final String CREATE_ITEM_LIST_ID_INDEX = "CREATE INDEX item_list_id ON " + TodoItem.TABLE + " (" + TodoItem.LIST_ID + ")"; //构造器,创建数据库 public DbOpenHelper(Context context) { super(context, "todo.db", null /* factory */, VERSION); } //创建数据库的时候回调 @Override public void onCreate(SQLiteDatabase db) { //创建对应的表和索引 db.execSQL(CREATE_LIST); db.execSQL(CREATE_ITEM); db.execSQL(CREATE_ITEM_LIST_ID_INDEX); //插入数据到todo_list表,返回id long groceryListId = db.insert(TodoList.TABLE, null, new TodoList.Builder() .name("Grocery List") .build()); //根据todo_list表的id,插入数据到todo_item表, db.insert(TodoItem.TABLE, null, new TodoItem.Builder() .listId(groceryListId) .description("Beer") .build()); db.insert(TodoItem.TABLE, null, new TodoItem.Builder() .listId(groceryListId) .description("Point Break on DVD") .build()); db.insert(TodoItem.TABLE, null, new TodoItem.Builder() .listId(groceryListId) .description("Bad Boys 2 on DVD") .build()); ....(和上面的套路一样这里省略了) } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
结合后:
final class DbOpenHelper extends SQLiteOpenHelper { private static final int VERSION = 1; //构造器,创建数据库 public DbOpenHelper(Context context) { super(context, "todo.db", null /* factory */, VERSION); } //创建数据库的时候回调 @Override public void onCreate(SQLiteDatabase db) { //创建对应的表和索引 db.execSQL(TodoList.CREATE_TABLE); db.execSQL(TodoItem.CREATE_TABLE); db.execSQL(CREATE_ITEM_LIST_ID_INDEX); //初始化插入实体 TodoList.Insert_list insertList = new TodoListModel.Insert_list(db); TodoItem.Insert_item insertItem = new TodoItemModel.Insert_item(db); //插入数据到todo_list表,返回id insertList.bind("Grocery List", "0"); long groceryListId = insertList.program.executeInsert(); //根据todo_list表的id,插入数据到todo_item insertItem.bind(groceryListId, "Beer", false); insertItem.program.executeInsert(); insertItem.bind(groceryListId, "Point Break on DVD", false); insertItem.program.executeInsert(); insertItem.bind(groceryListId, "Bad Boys 2 on DVD", false); insertItem.program.executeInsert(); ...(和上面的套路一样,这里省略) } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
可以看到: 结合后的SQLiteOpenHelper sql语句不用组合放在这里,清晰多了; 创表语句放在sq文件中,在自动生成的model,也可以得到创表的语句; 插增删改查利用bind来实现,更方便了,不用自己组合ContentValue,逻辑清晰,代码简介。
3. 查询对比
结合前:subscription = db.createQuery(ListsItem.TABLES, ListsItem.QUERY) .mapToList(ListsItem.MAPPER) //映射到ListItem的MAPPER .observeOn(AndroidSchedulers.mainThread()) //设置订阅者在主线程进行 .subscribe(adapter); static Func1<Cursor, ListsItem> MAPPER = new Func1<Cursor, ListsItem>() { @Override public ListsItem call(Cursor cursor) { long id = Db.getLong(cursor, TodoList.ID); String name = Db.getString(cursor, TodoList.NAME); int itemCount = Db.getInt(cursor, ITEM_COUNT); return new AutoValue_ListsItem(id, name, itemCount); } };
结合后:
//创建查询 SqlDelightStatement sqLiteStatement = TodoList.FACTORY.list_query(); subscription = db.createQuery(TodoList.TABLE_NAME, sqLiteStatement.statement, sqLiteStatement.args) .mapToList(TodoList.LIST_ITEM_FUNC) //映射到ListItem的MAPPER .observeOn(AndroidSchedulers.mainThread()) //设置订阅者在主线程进行 .subscribe(adapter); public static Func1<Cursor, ListsItem> MAPPER = new Func1<Cursor, ListsItem>() { @Override public ListsItem call(Cursor cursor) { return LIST_ITEM_MAPPER.map(cursor); } };
可以看到结合后的Curor解析不用我们手动解析,对应的查询语句和参数可以在SqlDelightStatement获取。
4. 更新添加对比
结合前:Observable.combineLatest(createClicked, RxTextView.textChanges(name), new Func2<String, CharSequence, String>() { @Override public String call(String ignored, CharSequence text) { return text.toString(); } }) // .observeOn(Schedulers.io()) .subscribe(new Action1<String>() { @Override public void call(String description) { db.insert(TodoItem.TABLE, new TodoItem.Builder().listId(getListId()).description(description).build()); } });
结合后:
Observable.combineLatest(createClicked, RxTextView.textChanges(name), new Func2<String, CharSequence, String>() { @Override public String call(String ignored, CharSequence text) { return text.toString(); } }) // .observeOn(Schedulers.io()) .subscribe(new Action1<String>() { @Override public void call(String description) { //初始化插入对象 TodoItemModel.Insert_item insertItem = new TodoItemModel.Insert_item(db.getWritableDatabase()); //填入数据 insertItem.bind(getListId(), description, false); //开始插入,这里会Rxjava会异步回调,进行更新列表 db.executeInsert(insertItem.table, insertItem.program); //注意这里不要使用下面的插入代码,会导致Rxjava不能异步回调发送数据 //insertItem.program.executeInsert(); } });
可以看到结合后:利用了SqlDelight生成的对应的Model类进行更新插入,不需要自己编写ContentValue,更方便的插入。
当然还有其他的变化。大家可以看看源码。
相关文章推荐
- Android actionBar与Fragment结合使用Demo2
- Android actionBar与Fragment结合使用Demo2
- android服务和广播的结合使用demo
- [Android开发] RxJava2之路六 - 结合组合操作符例子Demo
- Android使用handler和Runnable结合,自定义View更新UI的Demo
- android关于TabLayout+ViewPager结合使用的小Demo
- Android学习第十一篇——handler结合ImageView使用Demo
- Android Dialog的使用例子Demo
- Android actionBar与Fragment结合使用Demo
- android例子程序(ApiDemo)简单分类整理
- android中service的使用方法-小例子讲解
- Android ContentResolver 使用例子,读取联系人
- 【Android笔记 四 】使用android 调用震动的例子
- android中Dialog 的使用例子
- android学习小结5-各种控件使用方式DEMO
- Android的GridView和Gallery结合Demo
- 使用eclipse打开android_sdk自带的例子
- Android 3D与JNI结合的小例子
- ANDROID例子程序(ApiDemo)简单分类整理
- Android 例子: Dialog的使用--- AlertDialog功能演示一