Android_Sqlbrite入门使用

来源:互联网 发布:淘宝宝贝图片怎么拍照 编辑:程序博客网 时间:2024/06/08 05:50

除非迫不得已,要不然不要在你的APP里面使用数据库,记不得是哪个书的话了!
现在Android平台下的ORM框架very多,比如GreenDao,曾经写过一篇关于GreenDao的傻瓜式入门,喜欢的朋友可以去看下,GreenDao傻瓜式入门
他用起来需要自己建立一个Java工程,然后把数据模型建立,在执行java主函数的时候就把模型映射的表和结构全部创建完毕,
然后增删改查需要用greendao的api来操作,各有利弊.

随着今年RXjava Rxandroid的越来越火爆,一个响应式的数据库SqlBrite也被我们传说中的巨人,杰克大神放出,他基于RX观察者模式,来对我们原声的数据库进行操作,没有隐藏API,对于喜欢写sql语句的同学无非是比较不错的,

本文介绍下,在原生的sqllite中引入sqlbrite 操作数据库,先看下demo预览,

这里写图片描述

一个简单的界面,我们用数据库初始化了几个person,是不是看出来点什么端倪,
好吧,我们继续,
我们在app初始化的时候,用sqlite建立了数据库,以及我们的person表

这里的操作全部是原始的api操作大家都非常熟悉的

public class ATDbOpenHelper extends SQLiteOpenHelper {    public ATDbOpenHelper(Context context) {        super(context, ATDbConstant.AT_DB_NAME, null, ATDbConstant.AT_DB_VERSION);    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(ATDb.PersonTable.CREATE);        addSamePerson(db);    }    private void addSamePerson(SQLiteDatabase db) {        Person person = new Person();        person.setAge(35);        person.setName("陈冠希");        db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person));        person = new Person();        person.setAge(28);        person.setName("张柏芝");        db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person));        person = new Person();        person.setAge(23);        person.setName("蔡依林");        db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person));        person = new Person();        person.setAge(26);        person.setName("小S");        db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person));        person = new Person();        person.setAge(27);        person.setName("洪文安");        db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person));    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

接下来看下我们的DB对象

public class ATDb {    public ATDb() {    }    public static abstract class PersonTable {        // 表名        public static final String TABLE_NAME = "person";        // 表字段        public static final String ID = "_id";        public static final String COLUMN_NAME = "name";        public static final String COLUME_AGE = "age";        // 建表语句        public static final String CREATE =                "CREATE TABLE "                        + TABLE_NAME                        + " ("                        + ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"                        + COLUMN_NAME + " TEXT NOT NULL,"                        + COLUME_AGE + " INT,"                        + "UNIQUE (" + COLUMN_NAME + ")  ON CONFLICT REPLACE"                        + " ); ";        // 对象转字段,放入表中        public static ContentValues toContentValues(Person person) {            ContentValues values = new ContentValues();            values.put(COLUMN_NAME, person.getName());            values.put(COLUME_AGE, person.getAge());            return values;        }        // 响应式的查询,根据表中的row生成一个对象        static Func1<Cursor, Person> PERSON_MAPPER = new Func1<Cursor, Person>() {            @Override            public Person call(Cursor cursor) {                Person person = new Person();                String name = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME));                person.setName(name);                int age = cursor.getInt(cursor.getColumnIndexOrThrow(COLUME_AGE));                person.setAge(age);                return person;            }        };    }}

这里依然没有什么变化,就是根据官方的demo,我们多了一个响应式的查询,mapper,这个mapper参数一会需要放到sqlbrite给我们提供的数据库对象中,

下面是数据库的DbManager,里面包含了sqlbrite给我们提供的上帝数据库,britedatebase

public class ATDbManager {    private static final String TAG = "ATDbManager";    // rx响应式数据库,    private BriteDatabase briteDatabase;    public ATDbManager(Context context) {        ATDbOpenHelper dbOpenHelper;        // sqlbrite 初始化,构造出响应式数据库,添加log        SqlBrite sqlBrite;        sqlBrite = SqlBrite.create(new SqlBrite.Logger() {            @Override            public void log(String message) {                Logger.wtf(TAG, "log: >>>>" + message);            }        });        // 原生的sqllitehelper 用来建立数据库和数据表,以及构造,rx响应式数据库        dbOpenHelper = new ATDbOpenHelper(context);        // 执行slqbirte 构造数据库的语句        briteDatabase = sqlBrite.wrapDatabaseHelper(dbOpenHelper, Schedulers.io());        briteDatabase.setLoggingEnabled(true);    }    public Observable<List<Person>> queryPerson() {        return briteDatabase                .createQuery(ATDb.PersonTable.TABLE_NAME, "SELECT * FROM " + ATDb.PersonTable.TABLE_NAME)                .mapToList(ATDb.PersonTable.PERSON_MAPPER);    }    public Observable<List<Person>> queryPersonByName(String name) {        return briteDatabase.createQuery(ATDb.PersonTable.TABLE_NAME, "SELECT * FROM "                        + ATDb.PersonTable.TABLE_NAME                        + " WHERE "                        + ATDb.PersonTable.COLUMN_NAME                        + " = ?"                , name)                .mapToList(ATDb.PersonTable.PERSON_MAPPER)                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread());    }    public long addPerson(Person person) {        return briteDatabase.insert(ATDb.PersonTable.TABLE_NAME, ATDb.PersonTable.toContentValues(person));    }    public int deletePersonByName(final String name) {        return briteDatabase.delete(ATDb.PersonTable.TABLE_NAME, ATDb.PersonTable.COLUMN_NAME + "=?", name);    }}1

到这里,所有的数据库相关类全部介绍完毕,你会发现,sqlbrite不是一个数据库框架,他依然需要让你自己写sql语句来创建数据库查询,就是查询的等操作,采用了RX的方式来完成,这样的好处,就是我们在展示列表的时候,增删改查后,Sqlbrite都会自动的调用查询,来改变你传入列表的数据,不像我们以前的那种,比删除了一个人,你要更新列表,你需要重新queery person表然后 adapter notity,用sqlbrite可以不用这样做,
我们看下我们的activity中如何做,

//查询的时候,rx直接返回了当前数据的所有数据    private void queryPerson() {        Observable<List<Person>> listObservable = dbManager.queryPerson();        listObservable.subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Subscriber<List<Person>>() {                    @Override                    public void onCompleted() {                        this.unsubscribe();                    }                    @Override                    public void onError(Throwable e) {                    }                    @Override                    public void onNext(List<Person> persons) {                        Logger.e(TAG, "onNext: >>>>>" + persons.size() + persons.toString());                        dataForRecylerView.clear();                        dataForRecylerView.addAll(persons);                        personAdapter.notifyDataSetChanged();                    }                });    }

删除,操作,修改操作 在操作完毕后都会触发,查询,

以删除为例;

@OnClick(R.id.tv_add)    void addPerson() {        String personName = nameInput.getText().toString();        String personAge = ageInput.getText().toString();        if (TextUtils.isEmpty(personAge)) {            Snackbar.make(fab, "请输入年龄!", Snackbar.LENGTH_SHORT).show();        } else if (TextUtils.isEmpty(personName)) {            Snackbar.make(fab, "请输入姓名!", Snackbar.LENGTH_SHORT).show();        } else {            // 调用add person            Person addPerson = new Person();            addPerson.setAge(Integer.valueOf(personAge));            addPerson.setName(personName);            long state = dbManager.addPerson(addPerson);            if (state > 0) {                Snackbar.make(fab, "添加" + personName + "成功", Snackbar.LENGTH_SHORT).show();            }            // tips  没有调用查询语句,rxjava根据表数据的变化,会输出新的数据        }    }

执行完毕删除后,我们看下log日志,

这里写图片描述

这里写图片描述

所以我们刚才的删除代码,执行了db的delete语句并没有执行重新查询,列表会自动刷新.

想看源码分析和rx源码的同学,请佛咯github的杰克大神,SqlBirite源码链接
SqlBrite源码

最后奉上,demo的源码,欢迎拍砖!!

完整demo

原创粉丝点击