对GreenDao的使用

来源:互联网 发布:霍尼韦尔净水器 知乎 编辑:程序博客网 时间:2024/05/17 22:15

GreenDao是将原始的SQL语句封装起来,极大地简化了对数据库相关操作,据了解它比其他的数据库相关的框架性能要好,扩张性、速度等都很强。

使用:1.在主项目app中进行依赖:compile 'de.greenrobot:greendao:2.1.0'

   2.创建JavaMidule,并且在JavaModule中依赖:compile 'de.greenrobot:greendao-generator:2.1.0'

   3.在Java类中进行表的创建:

public class MyClass {    public static void main(String[] arg){ Schema schema=new Schema(1,"www.asendi.com"); /**  * 创建表  */ Entity son=schema.addEntity("Son");  son.addStringProperty("name");  son.addIntProperty("age");  son.addIdProperty();  Property fatherId=son.addLongProperty("fatherId").getProperty(); Entity father=schema.addEntity("Father");father.addIdProperty(); father.addStringProperty("name"); father.addIntProperty("age"); son.addToOne(father,fatherId);        try {            new DaoGenerator().generateAll(schema,"app/src/main/java");        } catch (Exception e) {            e.printStackTrace();        }    }}
然后运行该Java类,运行成功后在主项目的app-src-main-java下会多了一个包,包名即最开始Schema对象传入的第二个参数。以上代码就创建了Son表和Father表,

Son表中的属性为:name、age、_id,

Father表中的属性为name、age、_id,

并且Son表中引用Father表中的_id作为外键

进行Dao层的实例和创建数据库:

private void openDb(){        db=new DaoMaster.DevOpenHelper(this,"person.db",null).getWritableDatabase();        mDaoMaster=new DaoMaster(db);        mSession=mDaoMaster.newSession();        mSonDao=mSession.getSonDao();        mFatherDao=mSession.getFatherDao();    }

4.插入数据:

 接着上面:

 private void addPerson() {        Son son = new Son();        son.setName("tomkin");        son.setAge(19);        Father father = new Father();        father.setName("tFather");        father.setAge(43);        long fatherId = mFatherDao.insert(father);        son.setFatherId(fatherId);        mSonDao.insert(son);    }

 

5.在android中进行查询:

查询所有:List<Son>list=mSonDao.queryBuilder().listLazy();//.list()
按属性查询:Son nate=mSonDao.queryBuilder().where(SonDao.Properties.Name.eq("senddi")).unique();
匹配符查询:List tomkin=mSonDao.queryBuilder().where(SonDao.Properties.Name.like("tomkin% ")).list();
范围(区间)查询:List sons=mSonDao.queryBuilder().where(SonDao.Properties.Age.between(20,30)).list();
范围(大于)查询:List data=mSonDao.queryBuilder().where(SonDao.Properties.Age.gt(18)).list();
范围(小于)查询:List data=mSonDao.queryBuilder().where(SonDao.Properties.Age.lt(19)).list();
范围(不等于)查询:List data=mSonDao.queryBuilder().where(SonDao.Properties.Age.notEq(19)).list();
范围(大于等于)查询:List data=mSonDao.queryBuilder().where(SonDao.Properties.Age.ge(19)).list();
升序查询:List<Son> data=mSonDao.queryBuilder().orderAsc(SonDao.Properties.Age).list();
降序查询:List<Son> data=mSonDao.queryBuilder().orderDesc(SonDao.Properties.Age).list();

与原始的SQL语句结合:(年龄在45岁一下的父亲的ID)
List data=mSonDao.queryBuilder().where(
new WhereCondition.StringCondition("FATHER_UD IN" +
                        "(SELECT _ID FROM FATHER WHERE AGE<45)")).list();

6.多线程的查询:

当前线程的Query对象要放在创建该对象的线程中去,否则会抛出异常
使用的方法为:query.forCurrentThread();
 (要注意

forCurrentThread();

源码:AbstractQueryData<T, Q extends AbstractQuery<T>>中的forCurrentThread()

Q forCurrentThread(Q query) {        if (Thread.currentThread() == query.ownerThread) {            System.arraycopy(initialValues, 0, query.parameters, 0, initialValues.length);            return query;        } else {            return forCurrentThread();        }    }

首先是拿到当前线程的ID,拿到后进行一系列的判断,最后的判断是如果是本线程的ID,那么将Query的查询参数拷贝到数组中去,否则执行下面的forCurrentThread()

Q forCurrentThread() {    int threadId = Process.myTid();    if (threadId == 0) {        // Workaround for Robolectric, always returns 0        long id = Thread.currentThread().getId();        if (id < 0 || id > Integer.MAX_VALUE) {            throw new RuntimeException("Cannot handle thread ID: " + id);        }        threadId = (int) id;    }    synchronized (queriesForThreads) {        WeakReference<Q> queryRef = queriesForThreads.get(threadId);        Q query = queryRef != null ? queryRef.get() : null;        if (query == null) {            gc();            query = createQuery();            queriesForThreads.put(threadId, new WeakReference<Q>(query));        } else {            System.arraycopy(initialValues, 0, query.parameters, 0, initialValues.length);        }        return query;    }}

上面这个forCurrentThread()首先拿到线程的id,然后拿到WeakReference<Q> queryRef,进而判断 queryRef是否为空,如果不为空,那么query则等于query.get();如果为null,则执行gc();然后创建query对象并把该对象放在集合中去

checkThread():检查线程

gc()方法源码:

 void gc() {        synchronized (queriesForThreads) {            for (int i = queriesForThreads.size() - 1; i >= 0; i--) {                if (queriesForThreads.valueAt(i).get() == null) {                    queriesForThreads.remove(queriesForThreads.keyAt(i));                }            }        }    }

该方法是遍历查询线程的集合,然后把查询的对象移除。

源码:

protected void checkThread() {        if (Thread.currentThread() != ownerThread) {            throw new DaoException(                    "Method may be called only in owner thread, use forCurrentThread to get an instance for this thread");        }    }
该方法检查了是否运行在自己的线程上,否则抛异常;

7.一对多的查询方式:(数据一次性查询出来,不会对UI线程造成阻塞)

如果想要一对多的关系,则在Java代码中需要进行修改:

Schema schema=new Schema(1,"www.asendi.com");        /**         * 创建表         */        Entity son=schema.addEntity("Son");        son.addStringProperty("name");        son.addIntProperty("age");        son.addIdProperty();//        Property fatherId=son.addLongProperty("fatherUd").getProperty();        Entity father=schema.addEntity("Father");        father.addIdProperty();        father.addStringProperty("name");        father.addIntProperty("age");        Property sonId=father.addLongProperty("sonId").getProperty();        father.addToOne(son,sonId);        son.addToMany(father,sonId).setName("fathers");        try {            new DaoGenerator().generateAll(schema,"app/src/main/java");        } catch (Exception e) {            e.printStackTrace();        }
(注意加粗的代码)。




1 0
原创粉丝点击