Android 关于greenDao 的使⽤教程
关于greenDao 的使⽤
第⼀篇How to get started ?
原⽂地址:
该教程会带你浏览⼀个简单的greenDao ⽰例⼯程。地址:,该⼯程包含两个⼦⼯程:
DaoExample 和DaoExampleGenerator 。你可以clone 到本地,运⾏或者直接在github 上直接浏览。
如果你从git 仓储中检出了DaoExample ,可以直接像Android 应⽤⼀样运⾏它。正如你所看到的,它就是⼀个简单的笔记本。可以添加新的note ,或者点击已存在的note 进⾏删除。
预⽣成代码和创建表
在src-gen ⽬录下,你可以到⼀些已经⽣成的⽂件
1)Note.java ⼀个包含⼀个Note 所有数据的java 类。
2)NoteDao.java ⼀个DAO 类,是操作Note 对象的接⼝。
你可以通过DaoExampleGenerator ⼯程再次⽣成Note 和NoteDao 。
使⽤DaoMaster 类可以获得⼀个⽅便的SQLiteOpenHelper:
new DaoMaster.DevOpenHelper(this, "notes-db", null)
你不必编写“CREATE TABLE” SQL 语句,greenDao 会为你完成。
插⼊和删除Note 对象
创建了Note 表后,就可以存储⼀些note 到数据库⾥了。这是在NoteActivity 类⾥完成的。在onCreate ⽅法⾥,我们准备了⼀个DAO 对象:添加⼀个新的note 到数据库中:
该⽰例只是创建并插⼊了⼀个java 对象。但insert ⽅法返回的时候,数据库的ID 已经分发到了刚插⼊的Note 对象上了。在log 中可以看到。删除⼀条note :⾮常简单明,在onListItemClick ⽅法中可以看到
你也可以看⼀下其它的DAO ⽅法:loadAll 、update 。
数据模型化和代码的⽣成
为了扩展note 或者创建新的实体,你可以看⼀下DaoExampleGenerator
⼯程。它包含了⼀个单例的类,该类中包含了数据模型的定义代码。
1
2
3daoMaster = new DaoMaster(db);
daoSession
= wSession();android简单教程
noteDao
= NoteDao();
1
2
3Note note = new Note(null ,
noteText, comment, new
Date());
noteDao.insert(note);
Log.d("DaoExample",
"Inserted
new note, ID: "
+ Id());
1noteDao.deleteByKey(id);
正如你所看到的,你可以创建⼀个Schema 对象,通过它你可以添加实体,⼀个实体连接了⼀张数据库表。
⼀个实体包含⼀些属性,它们可以被映射到数据库的columns 。
⼀旦schema 定义完成,你可以触发代码⽣成器,Note.java 和NoteDao.java ⽂件就是这样被创建的。
下⼀步:
对greenDao 有了初步的了解,你可以⾃⼰动⼿试试了。当然,请查看下⽂档,
如果没有到你想要的,可以使⽤
第⼆篇 介绍
GreenDao 是⼀个⽤于Android 开发的对象/关系映射(ORM)⼯具。它向SQLite 数据库提供了⼀个对象导向的接⼝。像GreenDao 这样的ORM ⼯具不仅为你省去了很多的重复⼯作,⽽且提供了更简便的操作接⼝。代码⽣成的⼯程结构图
为了在你的Android 项⽬中使⽤GreenDao ,你需要创建⼀个⼆级⼯程:“generator project”,它的任务就是为你的domain ⽣成具体的代码。这个⽣成器⼯程就是⼀个普通的java ⼯程。确保greenDao 的greenDao-generator.jar 和 freemarker.jar 在classpath 中。创建⼀个可执⾏的java 类,构建你的实体模型并触发代码⽣成器,更多细节,可以参看 ⽂档。
核⼼类
⼀旦⽣成了指定的代码,就可以在你的android ⼯程中使⽤greenDao 了。别忘记在你的android ⼯程中引⼊greenDao 的核⼼jar 包:greenDao.jar 。以下是GreenDao 的⼀些必要接⼝。
DaoMaster :
daomaster 以⼀定的模式持有数据库对象(SQLiteDatabase )并管理⼀些DAO 类(⽽不是对象)。
有⼀个静态的⽅法创建和drop 数据库表。它的内部类OpenHelper 和DevOpenHelper 是SQLiteOpenHelper 的实现类,⽤于创建SQLite 数据库的模式。DaoSession :
管理指定模式下所有可⽤的DAO 对象,你可以通过某个get ⽅法获取到。DaoSession 提供⼀些通⽤的持久化⽅法,⽐如对实体进⾏插⼊,加载,更新,刷新和删除。最后DaoSession 对象会跟踪identity scope ,更多细节,可以参看 ⽂档。
DAOs (Data access objects ):
数据访问对象,⽤于实体的持久化和查询。对于每⼀个实体,greenDao 会⽣成⼀个DAO ,相对于DaoSession 它拥有更多持久化的⽅法,⽐如:加载全部,插⼊(insertInTx ,语境不明了,暂且简单的翻译成插⼊)。
实体
可持久化的对象。通常,实体可以被⽣成,不⽤⼿动去写。在数据库的⾏中,使⽤的都是标准的java 对象的属性(⽐如POJO 或者JavaBean
)。
1
2
3
4
5
6
7Schema schema = new Schema(1, "de.greenrobot.daoexample");Entity note= schema.addEntity("Note");note.addIdProperty();note.addStringProperty("text").notNull();note.addStringProperty("comment");
note.addDateProperty("date");
new
DaoGenerator().generateAll("../DaoExample/src-gen",
schema);
在⽰例中有⼀个Note 实体,通过它的DAO ,我们可以对指定的实体进⾏持久化的操作。
第三篇 实体的模型化
使⽤greenDao 的第⼀步:创建⼀个代表持久化数据的实体模型。greenDao 会依赖该模型为Dao ⽣成java 代码。
该模型本⾝是⽤java 代码定义的,很简单:在DaoExampleGenerator ⼯程的基础上创建⼀个java 对
象。具体你可以参看:
下⾯的插图描绘了元模型,展⽰了⼀些⽤于描述domain 具体模型的类。
Schema
实体数据schema 是你定义的第⼀个对象,通过schema 的版本和缺省的java 包调⽤构造器。
这个缺省的java 包会在greenDao ⽣成实体、DAOs 、和JUnit 测试的时候使⽤。如果那些缺省值是正确的,那么就完成了第⼀步。
如果你希望将DAO 和测试类创建到不同的包中,可以重新定义schema 的定义代码:
对于实体,该schema 也有两个缺省的标记,它们是可以被复写的。这些标记可以区分实体是否是激活状态,是否应该使⽤sections 。这些特性在⽂档⾥并没有,你可以看⼀下发布源码中的测试⼯程。
实体
⼀旦你拥有了⼀个schema 对象,你就可以使⽤它去添加实体了。
⼀个实体有不同的可变更设置,更重要的是,你可以添加⼀些属性到实体。
除了实体,还可以添加,。
属性和主键
以上的实体部分展⽰了如何给⼀个实体添加属性,实体的addXXXProperty ⽅法返回⼀个PropertyBuilder 对象,可以⽤于配制属性,
例如,使⽤columnName 去复写缺省的或者你提供的column name 。在ProperyBuilder 对象上调⽤getProperty ⽅法去访问属性对象,
对于指数(indices )和关系的创建是有必要的。
创建主键的约束
现在实体必须拥有⼀个long 或者Long 类型的属性作为它们的主键,这是Android 和SQLite 推荐的实践⽅式。因为,在将来,greenDao 要准备处理很多主键的脚本,但并不是每件事都能完全实现。为了解决这个问题,你可以使⽤⼀个long 类型的键并且使⽤⼀个唯⼀的下标去处理这个预期的key
属性。
1
2
3
4user.addIdProperty();user.addStringProperty("name");user.addStringProperty("password");user.addIntProperty("yearOfBirth"
);
1Schema
schema = new
Schema(1, "de.greenrobot.daoexample"
);
1
2schema.setDefaultJavaPackageTest("de.st");schema.setDefaultJavaPackageDao("de.greenrobot.daoexample.dao"
);
1
1Entity
user = schema.addEntity("User"
);
1
2
3
4user.addIdProperty();user.addStringProperty("name");user.addStringProperty("password");user.addIntProperty("yearOfBirth");
缺省
greenDao 会尝试以合理的缺省值进⾏⼯作,所以开发者不⽤单个的配置它们。⽐如,表和其列名是从
实体和属性名中获取到的,⽽不是java 中的驼峰。缺省的数据库名是⼤写的,单词间⽤下划线分隔开。⽐如:属性“creationDate”在数据库列中的映射为“CREATION_DATE”,
关系
⼀对多和多对多的关系在中有注释。
继承、接⼝、序列化
实体可以从其他⾮实体类继承,其⽗类可以通过setSuperclass(String)⽅法指定,注意:它可能会有其它的实体作为⽗类(但这⾥没有多态查询)。⽐如:
通常,使⽤接⼝作为实体属性和⾏为的通⽤基类是⽐较好的。⽐如:⼀个实体A 和B 共享了⼀套属性,这些属性可以定义在C 中。下⾯是⼀个序列化B 的列⼦:触发⽣成器
⼀旦你的实体schema 放置好了,你可以触发代码⽣成器进⾏处理。在generator ⼯程中,你可以实例化DaGenerator 并调⽤generateAll 中的⼀个⽅法:你所需要的就是schema 对象和⽬标⽂件夹,通常该⽂件夹就是你android ⼯程的资源⽂件夹。如果你想把这些测试类放到其他⽬录下,可以把⽬的⽂件夹作为第三个参数传⼊。
保持独⽴性(Keep sections 保持⾃定义的代码不会被覆盖)
实体类在每⼀次⽣成器运⾏的时候都会被覆盖。greenDao 允许添加⾃定义的代码到实体,通过“keep” ,可以满⾜它们。在schema 中使⽤
enableKeepSectinsByDefault(),或者setHasKeepSections(true)在选中的实体中。⼀旦使⽤,3个独⽴的部分会在实体中⽣成:
现在,你可以在 KEEP [...] and KEEP [...] END.中写⼊你的代码。注意,不要修改KEEP 注释。在该范围的代码会在代码重新⽣成的时候不被覆盖。对于备份或者提交代码时出现的意外错误,这是⼀个不错的选择解决⽅案。
第四篇 ⾮技术类的常见问题
通常的疑问
为什么greenDao 使⽤的是code generation ,⽽不是注解?
对于greenDao ,代码⽣成是⾮常合理的。在Android 平台上,基于注解的解决⽅式是有缺陷的:它们不得不依赖于元数据的解析和反射。特别是反射,会显著降低ORM ⼯具的性能。另⼀⽅⾯,greenDao 会为Android ⽣成优化过的代码。这些⽣成的代码完全避免了反射。这也是greenDao
如此快的主要原1myEntity.setSuperclass("MyCommonBehavior"
);
1
2
3entityA.implementsInterface("C");entityB.implementsInterface("C");
entityB.implementsSerializable();
1
2DaoGenerator daoGenerator = new
DaoGenerator();
"../MyProject/src-gen"
);
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
因。另⼀个优势是⼤⼩。
greenDao 的核⼼lib 是⾮常⼩的(在100K 以下,包括单元测试)。这是因为对于⼀些ORM 的内部逻辑都在generator 中,⽽不是在核⼼库中。
greenDao 包含了:DaoCore ,DaoGenerator 和DaoTest 。DaoCore 是需要你加⼊到android 项⽬中的,在Apache License 2版本以下是许可的。DaoGenerator 是java 程序,负责实体的⽣成,DAO 和其它的⽂件。DaoTest 是单元测试⽤例额,确保了greenDao 本⾝和其稳定性。
DaoGenerator 和DaoTest 在GPL V3以下是可⽤的。这些许可条款可以满⾜⼤部分的开发者使⽤。
第五篇 查询
查询会返回符合某些特定标准的实体。你可以使⽤原始的SQL 定制查询语句,或者更好的⽅式:使⽤GreenDao 的QueryBuilder API 。该查询也⽀持lazy-loading 的结果集。这样在操作⼤量结果集的时候可以节省内存和性能。
QueryBuilder
QueryBuilder 可以帮助你构建⾃定义的查询语句,⽽不使⽤SQL 的情况。并不是每个⼈都喜欢书写SQL 语句,当然很容易就会出⼀些错,这些错误只有在运⾏的时候才会被发现。⽽QueryBuilder 很容易使⽤,节省了你书写SQL 语句的时间。当然,由于语法的检验是在编译时才执⾏,所以在查询语句中发现bug 是很困难的。
QueryBuilder 的编译时间会检验属性的引⽤,这样能够在greenDao 后⾯,通过代码⽣成的⽅法发现bug 。
⽐如:查所有以“Joe”为first name 的⽤户,并以last name 排序:
嵌套情况:
获取⽤户名字为“Joe”并且在1970年9⽉之后出⽣的⽤户
这⾥要说明下:user 的birthday 对于year ,month ,和day 是⼀个分离的属性。我们可以以⼀种更正常的⽅式表达这种条件:
First name is “Joe” AND (year of birth is greater than 1970 OR (year of birth is 1970 AND month of birth is equal to or greater than 10 (October).Query 和 LazyList
Query 类代表⼀个可以多次执⾏的查询。当你使⽤QueryBuilder 之⼀的⽅法去获取结果的时候,QueryBuilder 内部使⽤了Query 类。
如果你想运⾏更多相同的查询,你应该调⽤build()在QueryBuilder 上,去创建Query ,⽽不是执⾏它。
greenDao ⽀持唯⼀的结果和结果列表。如果你想得到⼀个唯⼀的结果,可以调⽤Query 或者QueryBuilder 的unique()⽅法,这样在没有匹配条件的时候会返回⼀个唯⼀的结果,⽽不是null 。如果你希望禁⽌⽤例中返回null ,可以调⽤uniqueOrThrow(),该⽅法会保证返回⼀个⾮null 的实体。否则就会抛出⼀个DaoException 。
如果你期望⼀次性返回多个实体,可以使⽤以下⽅法:
list():所有的实体被加载到内存中。该结果通常是⼀个没有magic involved 的ArrayList 。使⽤起来最简单。
listLazy():实体按照需求加载进⼊内存。⼀旦列表中的⼀个元素被第⼀次访问,它将被加载同时缓存以便以后使⽤。必须close 。
ListLasyUncached(): ⼀个“虚拟”的实体列表:任何对列表元素的访问都会导致从数据库中加载,必须close 。
listIterator(): 遍历通过需要的时候加载(lazily )获得的结果,数据没有缓存,必须close 。
listLazy, listLazyUncached 和 listIterator 类使⽤了greenDao 的LazyList 类。为了根据需求加载数据,它持有了⼀个数据库cursor 的引⽤。
这是做是为了确保关闭 lazy list 和iterators (通常在try/finally 代码块中)。
⼀旦有的元素被访问或者遍历过,来⾃lsitLazy()的cache lazy list 和来⾃listIterator()⽅法的lazy iterator 将会⾃动关闭cursor 。
然⽽,如果list 的处理过早的完成了,你应该调⽤ close()⼿动关闭。
多次执⾏查询
⼀旦你使⽤QueryBuilder 构建了⼀个query ,该query 对象以后可以被重复使⽤。这种⽅式⽐总是重复创建query 对象要⾼效。
如果query 的参数没有变更,你只需要再次调⽤list/unique ⽅法即可。如果有参数变更,你就需要调⽤setParameter ⽅法处理每⼀个变更的参数。现在,个别参数由基于零的参数索引寻址。该下标基于你传递到querybuilder 的参数。
使⽤query 对象获取出⽣在1970年 并且 first name 为 joe
的⽤户:1
2
3
4List joes = userDao.queryBuilder().where(Properties.FirstName.eq("Joe")).orderAsc(Properties.LastName)
.list();
1
2
3
4
5QueryBuilder qb = userDao.queryBuilder();qb.where(Properties.FirstName.eq("Joe"),qb.or((1970),qb.and(Properties.YearOfBirth.eq(1970),
(10))));
List
youngJoes = qb.list();
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论