对GreenDao的使用

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中进行查询:

查询所有:Listlist=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 data=mSonDao.queryBuilder().orderAsc(SonDao.Properties.Age).list();
降序查询:List 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>中的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 queryRef = queriesForThreads.get(threadId); Q query = queryRef != null ? queryRef.get() : null; if (query == null) { gc(); query = createQuery(); queriesForThreads.put(threadId, new WeakReference(query)); } else { System.arraycopy(initialValues, 0, query.parameters, 0, initialValues.length); } return query; } }

上面这个forCurrentThread()首先拿到线程的id,然后拿到WeakReference 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(); }
(注意加粗的代码)。




你可能感兴趣的:(Android)