数据库那些事--greenDAO增删查改

转载请注明出处:王亟亟的大牛之路

话不多说先安利:https://github.com/ddwhan0123/Useful-Open-Source-Android 一直在加新东西,你值得拥有

这几天忙的1B,这里跑那里跑,写的Demo就是没时间发帖,昨天10来点到家然后 弄鱼 弄麦麦啥的再敲敲代码就1点了,早上起来困的1B。。。。

OK,先来说下为什么写这篇文章。

上周面试,一个面试官问了一堆,答得还不错,然后聊到数据库,我说我之前用sql直接写,然后他一脸闷B说了句好吧。。。然后我应该去学个第三方的ORM,所以就写了这个Demo,这篇博文

greenDAO是什么我就不多罗嗦了,google/莆田(百度) 都有一堆,这里给出几个比较好的给大家

http://www.jianshu.com/p/c4e9288d2ce6

http://greenrobot.org/greendao/

来看下我们的项目结构

数据库那些事--greenDAO增删查改_第1张图片

用到的库如下:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:recyclerview-v7:23.4.0'
    apt 'com.jakewharton:butterknife-compiler:8.1.0'
    compile 'org.greenrobot:greendao:2.2.1'
    compile 'com.jakewharton:butterknife:8.1.0'
    compile 'com.apkfuns.logutils:library:1.4.2'
    compile 'io.reactivex:rxjava:1.1.5'
    compile 'io.reactivex:rxandroid:1.2.0'
}

因为这部分和其他开源库 还是有点使用的小区别,我这边还是照搬下如何构建项目(隔壁搬来的)

1.首先开个项目

2.然后在.src/main下java目录同级的地方新建个目录叫java-gen

3.开完之后在build.gradle的sourceSets节点复制以下内容

 main {
            java.srcDirs = ['src/main/java', 'src/main/java-gen']
        }

数据库那些事--greenDAO增删查改_第2张图片

当然记得把前面那一堆依赖里 greenDAO相关的先build下不然 不能成

4.接下来再建我们的依赖java Module(用于创建对象和DAO代码)

5.然后在那个项目里加上generator所需的依赖,像这样

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'org.greenrobot:greendao-generator:2.2.0'
}

6.然后在这个JAVA 项目里创建一个类,叫什么随你,喜欢就好。

这里贴下具体的代码

public class DemoClass {
    public static void main(String[] asa) {
        Schema schema = new Schema(1, "com.example");
        addPerson(schema);
        try {
            new DaoGenerator().generateAll(schema, "/Users/jiajiewang/Desktop/SQLDemo/app/src/main/java-gen");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void addPerson(Schema schema) {
        Entity entity = schema.addEntity("Person");
        entity.addIdProperty();
        entity.addStringProperty("Name").notNull();
        entity.addStringProperty("Age").notNull();
        entity.addStringProperty("Address");
    }
}

这里有一个Main方法,一个addPerson

这里我们先声明了一个模式对象,传入2个参数 1个是数据库版本号,1个是生成代码的路径,这个路径就是前面我们java-gen的路径(可能在运行前并没有这个路径,但是运行后就自动生成了)

然后我们再给这个模式对象构建实体,这个实体其实就是我们数据库字段所对应的对象实体。(greenDAO的一系列操作就是在操作对象)

设置完了构建完了,OK我们就“创造”代码,传入模式对象和输出路径就OK了!!

右键 run main就成了我们最上面那个包截图的样子了

里面都是些啥我这里不做过多解释,上面传送门有介绍,我们来看看具体如何使用

官方比较推荐把一系列的初始化行为放在Applicatin里,省的每个业务类都要做初始化的一些操作。

public class MyApplication extends Application {
    public DaoSession daoSession;
    public SQLiteDatabase db;
    public DaoMaster.DevOpenHelper helper;
    public DaoMaster daoMaster;

    @Override
    public void onCreate() {
        super.onCreate();
        helper = new DaoMaster.DevOpenHelper(this, "person", null);
        db = helper.getWritableDatabase();
        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }
}

这里主要是给予业务类获取DAO实例什么的用。

贴下运行效果(Log也可以看下不然不太好理解)

数据库那些事--greenDAO增删查改_第3张图片

数据库那些事--greenDAO增删查改_第4张图片

改(先添加了数据,然后再改)

数据库那些事--greenDAO增删查改_第5张图片

年纪改到了 100

数据库那些事--greenDAO增删查改_第6张图片

删 id为2的那一条数据

数据库那些事--greenDAO增删查改_第7张图片

删完了 就剩一条了

数据库那些事--greenDAO增删查改_第8张图片

接下来就是具体的增删查改了,因为数据库都是大消耗操作,所以这里用了 RX(强行按进去的RX 其实这里用不用无所谓了)

package com.wjj.demo;


public class MainActivity extends AppCompatActivity {

    @BindView(R.id.delete_id_tv)
    EditText deleteIdTv;
    private List list;
    private Cursor cursor;
    private PersonAdapter adapter;

    @BindView(R.id.add)
    Button add;
    @BindView(R.id.delete)
    Button delete;
    @BindView(R.id.edit)
    Button edit;
    @BindView(R.id.query)
    Button query;
    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    @BindView(R.id.input_name)
    EditText inputName;
    @BindView(R.id.input_address)
    EditText inputAddress;
    @BindView(R.id.input_age)
    EditText inputAge;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        //初始化游标
        cursor = getDb().query(getPersonDao().getTablename(), getPersonDao().getAllColumns(), null, null, null, null, null);
        list = new ArrayList<>();
        adapter = new PersonAdapter(MainActivity.this, list);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    //返回Dao对象
    private PersonDao getPersonDao() {
        return ((MyApplication) this.getApplicationContext()).getDaoSession().getPersonDao();
    }

    //返回数据库对象
    private SQLiteDatabase getDb() {
        // 通过 BaseApplication 类提供的 getDb() 获取具体 db
        return ((MyApplication) this.getApplicationContext()).getDb();
    }

    @OnClick({R.id.add, R.id.delete, R.id.edit, R.id.query})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.add:
                addPerson();
                break;
            case R.id.delete:
                String v = deleteIdTv.getText().toString().trim();
                if (v.length() > 0) {
                    deletePerson(Long.parseLong(v));
                } else {
                    LogUtils.e( "---> 删除所需的TextView值为空");
                }
                break;
            case R.id.edit:
                String age = inputAge.getText().toString().trim();
                editPerson(age);
                inputAge.setText("");
                break;
            case R.id.query:
                list.clear();
                queryPerson();
                break;
        }
    }

    //增
    private void addPerson() {
        Observable.create(new Observable.OnSubscribe() {

            @Override
            public void call(Subscribersuper Person> subscriber) {
                Person person = null;
                String age = inputAge.getText().toString().trim();
                String name = inputName.getText().toString().trim();
                String address = inputAddress.getText().toString().trim();
                //判断不为空
                if (address.length() > 0 && name.length() > 0 && age.length() > 0) {
                    person = new Person(null, name, age, address);
                    getPersonDao().insert(person);
                    cursor.requery();

                } else {
                    LogUtils.d("---> 有一个/多个输入框里没东西");
                }
                if (person != null) {
                    subscriber.onNext(person);
                } else {
                    Observable.error(new NullPointerException("person为空"));
                }

                LogUtils.d("---> add 新线程" + Thread.currentThread().getId());
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                LogUtils.e(e);
            }

            @Override
            public void onNext(Person person) {
                inputAddress.setText("");
                inputAge.setText("");
                inputName.setText("");
            }
        });
    }

    //查
    private void queryPerson() {
        Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscribersuper String> subscriber) {
                String age = inputAge.getText().toString().trim();
                String name = inputName.getText().toString().trim();
                String address = inputAddress.getText().toString().trim();
                //判断是否有东西
                if (name.length() > 0) {
                    queryLogic(name, 1);
                    subscriber.onNext(name);
                } else if (age.length() > 0) {
                    queryLogic(age, 3);
                    subscriber.onNext(age);
                } else if (address.length() > 0) {
                    subscriber.onNext(address);
                    queryLogic(address, 2);  // Query 类代表了一个可以被重复执行的查询
                } else {
                    LogUtils.d("有一个/多个输入框里没东西");
                }
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onError(Throwable e) {
                LogUtils.e(e);
            }

            @Override
            public void onNext(String s) {
                inputAge.setText("");
                inputAddress.setText("");
                inputName.setText("");
            }
        });
    }

    private void queryLogic(String value, int type) {
        Query query = null;
        switch (type) {
            case 1:
                // Query 类代表了一个可以被重复执行的查询
                query = getQuery(value, PersonDao.Properties.Name);
                break;
            case 2:
                query = getQuery(value, PersonDao.Properties.Address);
                break;
            case 3:
                query = getQuery(value, PersonDao.Properties.Age);
                break;
        }
        if (query != null) {
            // 查询结果以 List 返回
            List queryList = (List) query.list();
            list.addAll(queryList);
            LogUtils.d("--->有" + queryList.size() + "个值");
        }

    }

    private Query getQuery(String value, Property p) {
        Query query = null;
        query = getPersonDao().queryBuilder()
                //逻辑
                .where(p.eq(value))
                //排序
                .orderAsc(PersonDao.Properties.Id)
                .build();
        return query;

    }

    //删
    private void deletePerson(long value) {
        Observable.just(value).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Long call(Long aLong) {
                getPersonDao().deleteByKey(aLong);
                return aLong;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() {
            @Override
            public void call(Long aLong) {
                deleteIdTv.setText("");
            }
        });


    }

    //改
    private void editPerson(String age) {
        Observable.just(age).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Person call(String s) {
                Person person = new Person();
                person.setAddress("suzhou");
                person.setAge(s);
                person.setName("kobe");
                person.setId(3l);
                getPersonDao().update(person);
                return person;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() {
            @Override
            public void call(Person person) {
                LogUtils.d(person);
            }
        });
    }

}

上面这些业务代码比较简单,这里不做太多介绍,这里讲一下这些sql操作的方法哪来的

我们这些 数据库操作的方法来自多个类,但是实现类是我们一直在get的PersonDao

PersonDao extends AbstractDao<Person, Long>

所以其实这些sql方法都来源于 public abstract class AbstractDao

一看到抽象类就懂了,给我们拿来使的。 里面有一大堆 public protected的方法,这个大家自己去看就行。

总结:

我对greenDAO内部实现不是太清楚,但是大量的测评和使用好评率让我们可以放心食用,接下来一段时间还会继续啃ORM,会不会对这部分最 2 3 4期的分析看情况吧。

如果英文好的可以看http://greenrobot.org/greendao/documentation/how-to-get-started/ 学创建流程。

源码地址:https://github.com/ddwhan0123/GreenDaoDemo
下载地址:https://github.com/ddwhan0123/GreenDaoDemo/archive/master.zip

暂时还是待业,有坑的带我啊!!!

数据库那些事--greenDAO增删查改_第9张图片

你可能感兴趣的:(各种小案例,翻翻Git找资源)