geeendao学习小结

来源:互联网 发布:企业 如何优化 编辑:程序博客网 时间:2024/06/05 20:42

最近研究greendao框架,了解了一些东西,总结一下

greenDAO(greenDAO官网:http://greendao-orm.com/)是一个可以帮助Android开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储、更新、删除和查询。

greenDAO的主要设计目标:

   *最大性能(最快的Android ORM)

   *易于使用API

   *高度优化

   *最小内存消耗

 

android几个ORM框架里,greendao还是比较突出的

GreenDao跟ORMLite的对比:http://blog.csdn.net/xushuaic/article/details/24434881

greendao与contentProvider ormlite的性能对比:http://blog.csdn.net/u012565107/article/details/21546829

greenDao与provider的区别:http://blog.csdn.net/u012565107/article/details/20042339

 

下面说下greendao的实战

通常都是从greendao在github上的DEMO开始的 https://github.com/greenrobot/greenDAO

从github上clone到本地

官方Demo里共有六个工程目录,分别为:

(1).DaoCore:库目录,即jar文件greendao-1.3.0-beta-1.jar的代码;

(2).DaoExample:android范例工程;

(3).DaoExampleGenerator:DaoExample工程的DAO类构造器,java工程;

(4).DaoGenerator:DAO类构造器,java工程;

(5).DaoTest、PerformanceTestOrmLite:其他测试相关的工程。



有3个必要的jar包
    1. freemaker.jar
    2. greendao-generator-1.3.0
    3. greendao-1.3.7.jar
前面两个jar是为了build出dao而用的,放在DaoExampleGenerator下
而后面第三个jar给我们app使用的!
在开始之前,先说明一下整体流程,
大致上分为两个步骤,
    1.产生 DAO files
    2.把DAO files 加到自己的androidproject中

  (1)generator --- greenDAO-generator.jar

   网上使用说明很少,搜到的都是对于我这个新人来说看的云里雾里,于是本人就干脆直接看官方文档,这篇文章也是边看边写的,可能会有些混乱。

    在github上下载的实例源码以及上面图中我们都会发现,会有一个generator。比如包里面会有greendao和greendao-generator,示例工程会有DaoExample和DaoExampleGenerator两个工程。之前一直不明白,看了官方文档终于理解了。

    “In order to use greenDao in your project, you need to create a second project, the "generator project". 这个额外的工程是一个普通的java工程,而非android工程。它的任务是生成你希望的java对象所对应的DAO接口对象。


  (2)核心的class -- greenDAO.jar

    DAO的core library(greenDAO.jar)中有以下几个核心类,也是后面比用到的,先来大概了解下他们的结构吧,不然直接看他们的使用会云里雾里。


DaoMaster:一看名字就知道它是Dao中的最大的官了。它保存了sqlitedatebase对象以及操作DAO classes(注意:不是对象)。其提供了一些创建和删除table的静态方法,其内部类OpenHelperDevOpenHelper实现了SQLiteOpenHelper并创建数据库的框架。

DaoSession:会话层。操作具体的DAO对象(注意:是对象),比如各种getter方法。

XXXDao:实际生成的某某DAO类,通常对应具体的java类,比如NoteDao等。其有更多的权限和方法来操作数据库元素。

XXXEntity:持久的实体对象。通常代表了一个数据库row的标准java properties。

引入了这个流程图,那么我们开始浅析关于这幅图。

居然GreenDao是用来帮我们简化建表、增删改查操作的,而且从上面的图中我们可以知道,原来不用GreenDao的时候,我们需要自己去写XyzEntity(实体类bean), 写完实体类之后,我们会写操作对应实体类的XyzDao

另外GreenDao引入了两个类,

DaoSession: 操作具体DAO对象的各种getter方法。

DaoMaster: 它保存了我们的SQLiteDataBase对象及操作DAO类。还有提供一些创建和删除Table的静态方法,它的内部类OpenHelper和DevOpenHelper实现了SQLiteOpenHelper并创建数据库的框架。

接著打開ExampleDaoGenerator這個class,
這隻java會幫你generate出4個files,
    1. DaoMaster
    2. DaoSession
    3. Model
    4. ModelDao
DAO就是用來負責db的一切操作, create table, insert, delete, query...etc.
model就單純是一個object而已!
這四個files都要加到我們的android project之中,


如下一个实例初始化代码:

?
1
2
3
4
5
helper = new DaoMaster.DevOpenHelper(this"notes-db"null);
db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
noteDao = daoSession.getNoteDao();

即:先创建了一个SQLiteOpenHelper并创建连接到一个具体数据库;再根据具体的datebase创建一个master对象用于;最后通过master创建一个数据库的会话操作。

 然后我们就要开始使用这些类了,根据我们上面的介绍,我们知道我们需要先从DaoMaster的内部类DevOpenHelper中得到我们想要的SQLiteDatabase对象,然后我们需要通过这个对象创建出对应的DaoMaster类对象daoMaster,有了这个daoMaster之后,我们就可以实例化一个新的会话Session, 通过这个Session再来得到相应的实体Dao, 最后操作这个Dao中的函数,就可以对数据库中相应的表进行增删改查了。



(一)产制DAO等文件


先从DaoExampleGenerator工程下的DaoExampleGenerator.java讲起,运行DaoExampleGenerator.java产制VO DAO DAOMASTER DAOSEESION文件


/* * Copyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package de.greenrobot.daogenerator.gentest;import de.greenrobot.daogenerator.DaoGenerator;import de.greenrobot.daogenerator.Entity;import de.greenrobot.daogenerator.Property;import de.greenrobot.daogenerator.Schema;import de.greenrobot.daogenerator.ToMany;/** * Generates entities and DAOs for the example project DaoExample. *  * Run it as a Java application (not Android). *  * @author Markus */public class ExampleDaoGenerator {    public static void main(String[] args) throws Exception {        Schema schema = new Schema(1000, "de.greenrobot.daoexample");        addNote(schema);        addCustomerOrder(schema);        new DaoGenerator().generateAll(schema, "../DaoExample/src-gen");    }    private static void addNote(Schema schema) {        Entity note = schema.addEntity("Note");        note.addIdProperty();        note.addStringProperty("text").notNull();        note.addStringProperty("comment");        note.addDateProperty("date");    }    private static void addCustomerOrder(Schema schema) {        Entity customer = schema.addEntity("Customer");        customer.addIdProperty();        customer.addStringProperty("name").notNull();        Entity order = schema.addEntity("Order");        order.setTableName("ORDERS"); // "ORDER" is a reserved keyword        order.addIdProperty();        Property orderDate = order.addDateProperty("date").getProperty();        Property customerId = order.addLongProperty("customerId").notNull().getProperty();        order.addToOne(customer, customerId);        ToMany customerToOrders = customer.addToMany(order, customerId);        customerToOrders.setName("orders");        customerToOrders.orderAsc(orderDate);    }}

在main方法中,

1

Schema schema = new Schema(3, "de.greenrobot.daoexample");

该方法第一个参数用来更新数据库版本号,通过更新版本号来更新数据库。第二个参数为要生成的代码所在包的路径。路径由系统自动生成

 

  默认Java package用来存放生成的entity、DAO文件、test代码。但也可以重新制定test文件的单独路径以及DAO文件的路径,代码:

?
1
2
schema.setDefaultJavaPackageTest("de.greenrobot.daoexample.test");
schema.setDefaultJavaPackageDao("de.greenrobot.daoexample.dao");


  另外,还有两个flag,用来标示entity是否是activie以及是否使用keep sections。代码:

?
1
2
schema2.enableKeepSectionsByDefault();
schema2.enableActiveEntitiesByDefault();

Keep sections:因为entity class在每次generator执行时均会覆盖原来的程序,为了能够添加用户自定义代码到entity中,需要设置该参数。只需要把自己的代码添加到下面的KEEP[]块中间就可以了。

?
1
2
3
4
5
6
7
8
// KEEP INCLUDES - put your custom includes here
// KEEP INCLUDES END
...
// KEEP FIELDS - put your custom fields here
// KEEP FIELDS END
...
// KEEP METHODS - put your custom methods here
// KEEP METHODS END

然后进行建表和设置要生成代码文件的摆放路径,可以是目标工程的项目路径。

1

2

3

addNote(schema);

addCustomerOrder(schema);

new DaoGenerator().generateAll(schema, "../DaoExample/src-gen");

其中src-gen这个目录名需要在运行前手动创建,否则会报错。

 

如果运行后出现以下错误,则导入DaoGenerator项目的dao.ftl文件即可(或者直接使用DaoGenerator来生成DAO文件)。

1

2

3

4

5

Exception in thread "main" java.io.FileNotFoundException: Template "dao.ftl" not found.

    at freemarker.template.Configuration.getTemplate(Configuration.java:742)

    at freemarker.template.Configuration.getTemplate(Configuration.java:665)

    at de.greenrobot.daogenerator.DaoGenerator.<init>(DaoGenerator.java:68)

    at de.greenrobot.daogenerator.gentest.ExampleDaoGenerator.main(ExampleDaoGenerator.java:41)

 

运行后出现以下的提示说明DAO文件自动生成成功了,刷新一下DaoExample项目即可看到。

1

2

3

4

5

6

7

8

9

10

11

12

13

greenDAO Generator

Copyright 2011-2013 Markus Junginger, greenrobot.de. Licensed under GPL V3.

This program comes with ABSOLUTELY NO WARRANTY

Processing schema version 3...

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\NoteDao.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Note.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\CustomerDao.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Customer.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\OrderDao.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Order.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\DaoMaster.java

Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\DaoSession.java

Processed 3 entities in 204ms

 

运行后可以看到,DaoExample项目src-gen下面自动生成了8个文件,3个实体对象,3个dao,1个DaoMaster,1个DaoSession.

 

(二)创建表

1.创建一个实体类

1

Entity note = schema.addEntity("Note");

默认表名就是实体类名,也可以自定义表名

1

dao.setTableName("NoteList");

greenDAO会自动根据实体类属性创建表字段,并赋予默认值。例如在数据库方面的表名和列名都来源于实体类名和属性名。默认的数据库名称是大写使用下划线分隔单词,而不是在Java中使用的驼峰式大小写风格。例如,一个名为“CREATIONDATE”属性将成为一个数据库列“CREATION_DATE”。

 

设置一个自增长ID列为主键:

1

dao.addIdProperty().primaryKey().autoincrement();

 

设置其他各种类型的属性:

1

2

3

dao.addIntProperty("cityId");

dao.addStringProperty("infoType").notNull();//非null字段

dao.addDoubleProperty("Id");

在生成的实体类中,int类型为自动转为long类型。

如果在编译过程中出现以下错误,那么有可能是主键的类型错误所致:

1

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

 

      在使用greenDAO时,一个实体类只能对应一个表,目前没法做到一个表对应多个实体类,或者多个表共用一种对象类型。后续的升级也不会针对这一点进行扩展。

 

(二)表的增删改查

     增删改查相当方便,完全的面向对象,不需要涉及到任何的sql语言。

1.查询

范例1:查询某个表是否包含某个id:

1
2
3
4
5
6
7
public boolean isSaved(int ID)
{
    QueryBuilder<SaveList> qb = saveListDao.queryBuilder();
    qb.where(Properties.Id.eq(ID));
    qb.buildCount().count();
    return qb.buildCount().count() > 0 true false;
}


范例2:获取整个表的数据集合,一句代码就搞定!

1
2
3
4
public List<PhotoGalleryDB> getPhotoGallery()
{
    return photoGalleryDao.loadAll();// 获取图片相册
}


范例3:通过一个字段值查找对应的另一个字段值(为简便直接使用下面方法,也许有更简单的方法,尚未尝试)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** 通过图片id查找其目录id */
public int getTypeId(int picId)
{
    QueryBuilder<PhotoGalleryDB> qb = photoGalleryDao.queryBuilder();
    qb.where(Properties.Id.eq(picId));
    if (qb.list().size() > 0)
    {
        return qb.list().get(0).getTypeId();
    }
    else
    {
        return -1;
    }
}


范例4:查找所有第一姓名是“Joe”并且以lastname排序。

1
2
3
4
List joes = userDao.queryBuilder()
.where(Properties.FirstName.eq("Joe"))
.orderAsc(Properties.LastName)
.list();


范例5:多重条件查询

(1)获取id为cityId并且infotype为HBContant.CITYINFO_SL的数据集合:

1
2
3
4
5
6
7
public List<CityInfoDB> getSupportingList(int cityId)
{
    QueryBuilder<CityInfoDB> qb = cityInfoDao.queryBuilder();
    qb.where(qb.and(Properties.CityId.eq(cityId),Properties.InfoType.eq(HBContant.CITYINFO_SL)));
    qb.orderAsc(Properties.Id);// 排序依据
    return qb.list();
}


(2)获取firstname为“Joe”并且出生于1970年10月以后的所有user集合:

1
2
3
4
5
QueryBuilder qb = userDao.queryBuilder();
qb.where(Properties.FirstName.eq("Joe"),
qb.or(Properties.YearOfBirth.gt(1970),
qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
List youngJoes = qb.list();


范例6:获取某列对象

1
picJsonDao.loadByRowId(picId);

  1.   public Note loadNote(long id) {  
  2.         return noteDao.load(id);  
  3.     }  
  1.     /** 
  2.      * query list with where clause 
  3.      * ex: begin_date_time >= ? AND end_date_time <= ? 
  4.      * @param where where clause, include 'where' word 
  5.      * @param params query parameters 
  6.      * @return 
  7.      */  
  8.       
  9.     public List<Note> queryNote(String where, String... params){  
  10.         return noteDao.queryRaw(where, params);  
  11.     }  


2.增添/插入、修改

插入数据更加简单,也是只要一句代码便能搞定!

1
2
3
4
public void addToPhotoTable(Photo p)
{
    photoDao.insert(p);
}

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Note note = new Note(null, noteText, comment, new Date());  
  2. noteDao.insert(note);  
  3. Log.d("DaoExample""Inserted new note, ID: " + note.getId());  

该示例只是创建并插入了一个java对象。但insert方法返回的时候,数据库的ID已经分发到了刚插入的Note对象上了。在log中可以看到。



插入时需要new一个新的对象,范例如下:

1
2
3
4
5
6
7
DevOpenHelper helper = new DaoMaster.DevOpenHelper(this"notes-db"null);
 db = helper.getWritableDatabase();
 daoMaster = new DaoMaster(db);
 daoSession = daoMaster.newSession();
 noteDao = daoSession.getNoteDao();
 Note note = new Note(null, noteText, comment, new Date());
 noteDao.insert(note);


修改更新:

1
2
photoDao.insertOrReplace(photo);
photoDao.insertInTx(photo);

  1.     /** 
  2.      * insert or update noteList use transaction 
  3.      * @param list 
  4.      */  
  5.     public void saveNoteLists(final List<Note> list){  
  6.             if(list == null || list.isEmpty()){  
  7.                  return;  
  8.             }  
  9.             noteDao.getSession().runInTx(new Runnable() {  
  10.             @Override  
  11.             public void run() {  
  12.                 for(int i=0; i<list.size(); i++){  
  13.                     Note note = list.get(i);  
  14.                     noteDao.insertOrReplace(note);  
  15.                 }  
  16.             }  
  17.         });  
  18.           
  19.     }  

3.删除:

(1)清空表格数据

1
2
3
4
5
/** 清空相册图片列表的数据 */
public void clearPhoto()
{
    photoDao.deleteAll();
}


(2)删除某个对象

1
2
3
4
5
6
public void deleteCityInfo(int cityId)
{
    QueryBuilder<DBCityInfo> qb = cityInfoDao.queryBuilder();
    DeleteQuery<DBCityInfo> bd = qb.where(Properties.CityId.eq(cityId)).buildDelete();
    bd.executeDeleteWithoutDetachingEntities();
}

  1.     /** 
  2.      * delete note by id 
  3.      * @param id 
  4.      */  
  5.     public void deleteNote(long id){  
  6.         noteDao.deleteByKey(id);  
  7.         Log.i(TAG, "delete");  
  8.     }  
  9.       
  10.     public void deleteNote(Note note){  
  11.         noteDao.delete(note);  
  12.     }  
  13.       

参考:https://github.com/greenrobot/greenDAO/issues/34


由上可见,使用greenDAO进行数据库的增删改查时及其方便,而且性能极佳。


(三)常用方法笔记

1.在Application实现得到DaoMaster和DaoSession的方法:

可以看到DaoMaster中封装了SQLiteDatabase和SQLiteOpenHelper

来看看如何使用GreenDao实现CRUD

如下代码实现插入一个Note对象:

[java] view plaincopy
  1. DevOpenHelper helper = new DaoMaster.DevOpenHelper(this"notes-db"null);  
  2.      db = helper.getWritableDatabase();  
  3.      daoMaster = new DaoMaster(db);  
  4.      daoSession = daoMaster.newSession();  
  5.      noteDao = daoSession.getNoteDao();  
  6.      Note note = new Note(null, noteText, comment, new Date());  
  7.      noteDao.insert(note);  
代码变得如此简单。

官方推荐将取得DaoMaster对象的方法放到Application层这样避免多次创建生成Session对象。

感觉这个框架和Web的Hibernate有异曲同工之妙。

这里列出自己实际开发中的代码方便记忆:

首先是在Application层实现得到DaoMaster和DaoSession的方法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private static DaoMaster daoMaster;
private static DaoSession daoSession;
/**
 * 取得DaoMaster
 *
 * @param context
 * @return
 */
public static DaoMaster getDaoMaster(Context context)
{
    if (daoMaster == null)
    {
        OpenHelper helper = new DaoMaster.DevOpenHelper(context, HBContant.DATABASE_NAME, null);
        daoMaster = new DaoMaster(helper.getWritableDatabase());
    }
    return daoMaster;
}
/**
 * 取得DaoSession
 *
 * @param context
 * @return
 */
public static DaoSession getDaoSession(Context context)
{
    if (daoSession == null)
    {
        if (daoMaster == null)
        {
            daoMaster = getDaoMaster(context);
        }
        daoSession = daoMaster.newSession();
    }
    return daoSession;
}


2.增删改查工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
public class DBHelper
{
    private static Context mContext;
    private static DBHelper instance;
                                                                                                                                                                                                                                                                                                                                   
    private CityInfoDBDao cityInfoDao;
                                                                                                                                                                                                                                                                                                                                   
    private DBHelper()
    {
    }
                                                                                                                                                                                                                                                                                                                                   
    public static DBHelper getInstance(Context context)
    {
        if (instance == null)
        {
            instance = new DBHelper();
            if (mContext == null)
            {
                mContext = context;
            }
                                                                                                                                                                                                                                                                                                                                           
            // 数据库对象
            DaoSession daoSession = HBApplication.getDaoSession(mContext);
            instance.cityInfoDao = daoSession.getCityInfoDBDao();
        }
        return instance;
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 添加数据 */
    public void addToCityInfoTable(CityInfo item)
    {
        cityInfoDao.insert(item);
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 查询 */
    public List<EstateLoveListJson> getCityInfoList()
    {
        QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
        return qb.list();
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 查询 */
    public List<CityInfo> getCityInfo()
    {
        return cityInfoDao.loadAll();// 查找图片相册
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 查询 */
    public boolean isSaved(int Id)
    {
        QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
        qb.where(Properties.Id.eq(Id));
        qb.buildCount().count();
        return qb.buildCount().count() > 0 true false;// 查找收藏表
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 删除 */
    public void deleteCityInfoList(int Id)
    {
        QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
        DeleteQuery<CityInfo> bd = qb.where(Properties.Id.eq(Id)).buildDelete();
        bd.executeDeleteWithoutDetachingEntities();
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 删除 */
    public void clearCityInfo()
    {
        cityInfoDao.deleteAll();
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 通过城市id查找其类型id */
    public int getTypeId(int cityId)
    {
        QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
        qb.where(Properties.Id.eq(cityId));
        if (qb.list().size() > 0)
        {
            return qb.list().get(0).getTypeId();
        }
        else
        {
            return 0;
        }
    }
                                                                                                                                                                                                                                                                                                                                   
    /** 多重查询 */
    public List<CityInfo> getIphRegionList(int cityId)
    {
        QueryBuilder<CityInfoDB> qb = cityInfoDao.queryBuilder();
        qb.where(qb.and(Properties.CityId.eq(cityId), Properties.InfoType.eq(HBContant.CITYINFO_IR)));
        qb.orderAsc(Properties.Id);// 排序依据
        return qb.list();
    }
}



另外,还有多表关联、惰性加载等功能,待后续研究。

1. 查询 -- Queries

    1)你可以使用原生的SQl(raw sql)语句;

    2)也可以使用推荐的方法:使用greenDAO提供的QueryBuilder的API。

    3)查询还支持结果延迟加载(lazy-loading),主要为操作较大查询结果是节约内存并提高性能。


(1)QueryBuilder

    使用过sql语句查询的人都会有一种感触(主要针对不是专职开发数据库并对sql不是很熟练的人),写起来复杂、不能再第一时间发现问题(只能在运行过程中验证sql的正确性)、查找bug麻烦等等。QueryBuilder的出现就是为了解决sql使用的问题,提高开发效率。

看一个略微复杂的例子,查询first name是Joe,并在1970年10月以及之后的所有人:

QueryBuilder qb = userDao.queryBuilder();

qb.where(Properties.FirstName.eq("Joe"),

qb.or(Properties.YearOfBirth.gt(1970),

qb.and(Properties.YearOfBirth.eq(1970)Properties.MonthOfBirth.ge(10))));

List youngJoes = qb.list();


不用我来解释了吧。


(2)Lazylist

    greenDAO支持返回唯一查询结果(如果没有返回null) ---- 调用Query或QueryBuilder的unique()方法;

    也支持返回list ---- 调用list()方法。

    当不希望返回null作为结果时,则调用uniqueOrThrow()方法,当结果null时将直接抛出异常。

返回多个结果解释:

list():     所有entity均会被加载到内存中。结果仅是一个简单的ArrayList。使用最简单。

listLazy():    查询结果会根据需要加载到内存中。列表中的元素仅在accessed for the first time,它才会被加载并缓存。该方法必须主动关闭(Must be closed)。

listLazyUncached():    虚拟的结果列表,任何对元素的方法实际都会到数据库中去加载数据。Must be closed

listIterator():    根据需要迭代结果(lazily)。数据不缓存。Must be closed


在greenDAO实现中,后3中其实都使用的LazyList类。为了实现根据需要加载,其内部实现上是保存了数据库cursor的引用。这也是为何这3中方式must be closed,其就是为了释放内部cursor和迭代器(通常是在try-finally块中完成close)。


(3)Query

    解释:Query类代表了一个可以被重复执行的查询。在QueryBuilder内部其实也是会定义一个Query并执行完成查询。

    这将带来极大地方便,因为任何人都不希望在每次查询的时候总是写一遍query代码。同时Query还可以根据需要改变参数。如下实例代码:

    使用Query对象查询名为Joe并出生在1970年的人:

Query query = userDao.queryBuilder().where(

Properties.FirstName.eq("Joe")Properties.YearOfBirth.eq(1970))

.build();

List joesOf1970 = query.list();

然后想再查询出生在1977年之后并叫Marias的人:

query.setParameter(0"Maria");

query.setParameter(11977);

List mariasOf1977 = query.list();

注意:参数的编号是创建query所设置的顺序。


(4)多线程查询

    有时我们希望在多线程中执行查询。从greenDAO 1.3版本开始,实例化Query对象均会绑定到其自己的线程,这样我们就可以安全的设置Query参数,因为其他线程无法影响到。如果其他线程使用别的线程的query(比如设置参数、执行查询)将会抛出异常。因此,我们也不需要做同步工作,而且不要加锁,因为加入相关的事务用到了该Query对象将导致死锁。

    为完全地避免可能产生的死锁,1.3版本引入了forCurrentThread()方法。该方法将返回本线程内的Query实例,每次调用该方法时,参数均会被重置为最初创建时的一样。


(5)原生sql查询

    推荐的方法执行原生sql语句是通过QueryBuilder和WhereCondition.StringCondition。如下代码:

Query query = userDao.queryBuilder().where(

new StringCondition("_ID IN " "(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();

    假如QueryBuilder没有提供你需要的特性,你也可以使用queryRaw() 和 queryRawCreate() 方法。具体就不再详细介绍了。


(6)删除操作(delete query)

    删除操作会删除所有满足条件的实体。为实现批量删除(bulk delete),调用QueryBuilder的 buildDelete方法并执行DeleteQuery。该部分API还不稳定,可能会改变就不介绍了。


(7)问题定位(日志

    你可能会遇到查询结果并不是预期的那样,这时候你就可以设置两个静态flag参数来打日志定位问题:

QueryBuilder.   LOG_SQL       =       true   ;
QueryBuilder.   LOG_VALUES       =       true   ;

    这将会将产生的sql命令以及传递的参数以日志方式输出,由此方便程序员定位问题。


更詳細的內容可以看

http://blog.csdn.net/xushuaic/article/details/24438841

http://blog.csdn.net/xushuaic/article/details/24496191


http://my.oschina.net/cheneywangc/blog/196354

http://my.oschina.net/cheneywangc/blog/196360

0 0