greenDAO的使用

greenDAO的使用:
总体来说:

你需要在你的主Android工程之外再建立一个generator project.这是一个纯java的项目。

 

在这个项目里你需要在classpath中引用greenDAO-generator.jar,和freemarker.jar这两个jar包。
然后在这个工程中使用greenDAO-generator中的方法定义你数据库的实体和关系。
最后通过freemarker生成你的android工程要生用的DAO和Entiities代码。具体的定义方法我们后面再讲。

 

 

做完了上面的步骤,下面就可以愉快的写我们的android工程了。
这里别忘了,为了使用generator生成的Entities和DAO方法,我们需要在我们的Android工程中引入greenDAO.jar这个包。
---------------------------------------------------------
 
具体的,我们需要创建两个工程,一个工程是java工程(非Android工程),是用来生产entity类(这个java类内部各种getter和setter方法均自动创建实现了,entity类里面的属性叫做Property,对应着数据库表的一个字段。一个数据库的表对于着一个entity类,entity的创建过程下面会说)、 生成DAO文件(dao文件内部自动生产了查询数据库的各种方法,dao文件的创建过程下面会说)。
那么我们就看看怎么生成entity和dao文件。

1)创建Java工程(generator工程

(2)导入greenDao-generator.jar和freemarker.jar两个包。

(3)创建一个类(名字都可以),创建main方法。在这个main方法中创建一个schema对象,创建该对象时,需要制定数据库的版本号、默认的Java package等参数。默认Java package用来存放生成的entity、DAO文件、test代码。如:

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

那么接下来就是向schema 中添加想要生成的entity,以及entity中想要的property(对应着数据表的字段)。如:

Entity note = schema.addEntity("Note");
                 
        note.addIdProperty();
        note.addStringProperty("text").notNull();
        note.addStringProperty("comment");
        note.addDateProperty("date”);
这样就会自动产生了Note这个java类(它是 Entity 类的对象,这个对象对应一个数据库表,而不是对应数据库表的一行,数据库表的一行对应的是Note类的一个对象) 和Note这个类中的各种property属性。(对应着一个Note表和Note表中的各个字段把,表和字段不用自己创建应该,这里entity的对象产生了,那边也应该自动产生了把。)。
 
那么Note这个java类对应的Dao类或着说对应用来操作Note表的Dao类是怎么产生的呢?
new DaoGenerator().generateAll(schema, "../DaoExample/src-gen");通过这句就自动产生了NoteDao,里面自动产生了操作Note表的各种方法。
 
这时候我们运行我们刚创建的这个java工程,会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件。(如果刚才那个main方法中会生产若干个entity对象,那么这里dao对象,entity对象就会有若干个,但是只会有一个DaoMaster、DaoSession来管理这些entity类的对象)
这时候我们就可以在Android 工程中使用我们创建好的类了。也就是我们需要创建的第二个工程--Android工程。

完成了generator工作之后后面的东西就简单了:

    (1)创建一个android工程

    (2)在一个.java文件写一个应用:note表中插入一个Note对象(一行数据):

 
 
DevOpenHelper helper =  new  DaoMaster.DevOpenHelper( this "notes-db" null ); //上面生成的entity所对应的表生成在哪个数据库中
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);  
noteDao.deleteByKey(id);
 
如果有两个表,一个是note表,一个是picture表,note表的一行数据对应着picture表的唯一一行数据,那么我们现在想通过Note这个entity对象的实例note1 直接调用getPicture()方法来得到这个note1(对应着note表的一行)所唯一对应的picture表中的那一行数据(也就是Picture(java类)这个entity对象对应的一个Picture实例picture1)
那么怎么得到呢?
既然我们想通过Note这个entity对象的实例note1 直接调用getPicture()方法来得到这个note1,那么我们要对Note这个entity对象addToOne(),需要的参数是entity对象对应的Picture(entity对象,不是对象的对象)和Note类中的pictureId属性(如果Note这个java类中没有pictureId属性,我们需要先在其创建这个property属性,说明一点的是picture表肯定实现就有pictureid这个字段或者说picture这个entity对象(java类)肯定事先有这个pictureid property,不然也不会根据这个创建关系查询了),如:
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty();
user.addToOne(picture, pictureIdProperty);
(这里的user,picture都是entity的对象,不是一个User类或picture类的对象
 )
 
这样以后我们就可以调用note 类(这个类是entity的对象)的一个实例
note1的getPicture()方法(get picture的picture是指的表的名字,而不是getpictureid,因为我们得到的确实是picture的实例。不用传参数,因为我这个note1对应的pictureid是已知的,直接对能对应picture表中有该pictureid值的那一行了,所以不用传参,这个getPicture方法是我们按上面的步骤做了 自动产生的)来得到picture表对应的那一行数据。
 
如果我们还想我们的note1直接得到picture表中对应的另一个唯一数据picturesmall(和pictureid一样,note 表和picture表都有这个字段,也是唯一对应的,因为我们的get picture方法是同一个表的表明,没法区分,所以要再设名字),例如:
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty();
Property thumbnailIdProperty = user.addLongProperty("thumbnailId").getProperty();
user.addToOne(picture, pictureIdProperty);
user.addToOne(picture, thumbnailIdProperty, "thumbnail");
这时候我们想得到note1所对应的picture表中相同的picturesmall的那一行的时候,我们要调用
note1.getThumbnail()。
 
刚才所的是一对一的关系,还有一对多的关系。也就是说我们这时候picture表中pictureid不是唯一的,多行都可以有相同的pictureid,这时候我们就不能使用刚才说的addToOne,而是使用addToMany,这样我们调用note1这个Note类实例的getPictures(多了一个s)方法,就得到了picture表中pictureid为note1中的pictureid值的所有行(返回的是一个List )。
 
注意通过getpcitures以后得到的list是会缓存的,我们之后在查询时就会从缓存中拿,所以在删除或者增加修改picture数据库表以后,我们要重置清空list这个缓存,这个缓存存在note1中,所以要
note1.resetPictures()。
 
最后说一下查询:
 
举个例子:

查询以Joe为名,以姓排序的所有用户.

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

dao里面的方法都是生成dao文件时自动产生的,所以不用多讲。这里有一点不是很明白,
properties这个类是在哪里写的呢?我们知道entity类中有各种property,为什么不直接调用
那里面的property,而又创建了一个properties类?并且这个是在哪创建的?自动还是手动创建的??
都不是很清楚??✨

再说一个查询例子:嵌套条件的例子:获取出生在1970年10月以后名为Joe的所有用户. 我们将用户生日对应到实体的年、月、日属性.
我们使用更正式的形式将查询条件表达为:名是Joe AND(生日的年份大于1970 OR(生日的年是1970 AND 生日的月等于或大于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();
qb.or()和qb.and()都可以看成是whereConditon类型的参数传入到where()中

当你使用QueryBuilder对象的一个方法来获取结果,
QueryBuilder内部使用Query类来进行处理。所以如果你要以相同的条件多次进行查询的时候,你可以调用QueryBuilder的build()方法来产生一个Query,先不需要执行它,之后需要多次查询的时候就可以直接使用这个query对象来进行查询(调用unique()或者list()),而没必要再创建QueryBuilder。具体的:

如果查询条件没有变,你只需要再次调用其中一个list/unique方法.如果参数有改变,你必须对改变的参数调用setParameter方法.目前,各个参数以0开始的索引来区分.对应你传入参数到QueryBuilder的索引.
下面的例子使用Query对象来查询"名"为Joe,出生在1970年的用于:

Query query = userDao.queryBuilder().where(
Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970))
.build();
List joesOf1970 = query.list();

使用这个Query对象,我们查找名为Marias,出生在1977年的用户:

query.setParameter(0, "Maria");
query.setParameter(1, 1977);
List mariasOf1977 = query.list();
 
调用Query或者QueryBuilder的unique()方法,它会给你唯一的结果或者null(如果没有找到匹配的实体).如果你的情况不允许null作为结果,调用uniqueOrThrow(),它会保证返回非空的实体(如果没有匹配的结果,它会抛出DaoException异常).
如果查询时你期望返回多个结果,你可以调用list...中的一个方法:结果是一个典型的ArrayList.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/happylion/p/4788051.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值