android ORM框架--greenDao简介

来源:互联网 发布:排名前十的网络作家 编辑:程序博客网 时间:2024/05/17 06:50
 数据库是开发过程中经常要打交道的模块,android的sqlite的基本操作也是基本功。相对于传统的自己封装sql语句实现业务逻辑的增删改查,ORM框架的出现大大简化了数据库开发的成本。把我们从纷繁复杂的sql世界回归到熟悉的面向对象的世界。简单介绍下ORM的概念,其全称叫做对象关系映射(Object Relation Mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

  android下比较热门的ORM框架有ORMLite、greendao、ormndroid、androrm、ActiveAndroid。几种框架的优缺点这里就不一一罗列,感兴趣可以自行百度。greenDao在这几个框架的对比中

  优点:效率很高,插入和更新的速度是sqlite的2倍,加载实体的速度是ormlite的4.5倍。官网测试结果:http://greendao-orm.com/features/。文件较小(<100K),占用更少的内存 ,但是需要create Dao,操作实体灵活:支持get,update,delete等操作

  缺点:

  学习成本较高。其中使用了一个java工程根据一些属性和规则去generate一些基础代码,类似于javaBean但会有一些规则,另外还有QueryBuilder、Dao等API,所以首先要明白整个过程,才能方便使用。没有ORMLite那样封装的完整,不过greenDao的官网上也提到了这一点,正是基于generator而不是反射,才使得其效率高的多。

  下面就简单介绍下greenDao在项目中的使用。

  1、导入工程

  新建module->Android Liabry,目录结构如图,我这里是手动导入三个jar包,当然也可以在build.gradle中定义。

  2、daoGenerator工程和GreenDao相关概念的介绍

  这里的ExampleDaoGenerator就是生成数据库bean和dao的java工程,是有main方法需要单独以java工程的方式run.一个简单的daoGenerator如下:

public class ExampleDaoGenerator {    public static void main(String[] args) throws Exception {        //1代表数据库版本号,第二个代表生成数据库的名称        Schema schema = new Schema(1, "de.greenrobot.daoexample");        addNote(schema);        addCustomerOrder(schema);        //在DaoExample/src-gen目录下生成bean和dao.这里的src-gen目录必须手动创建,不然会报错        new DaoGenerator().generateAll(schema, "../DaoExample/src-gen");    }}

下面的插图描绘了元模型,展示了一些用于描述domain具体模型的类。

Schema:schema是你定义的第一个对象,通过schema的版本和缺省的java包调用构造器。

//1代表数据库版本号,第二个代表要创建的package名称Schema schema = new Schema(1, "de.greenrobot.daoexample");

schema.enableKeepSectionsByDefault();

因为每次run DaoGenerator工程都会重新生成src-gen下的文件,所以对于一些需要手动增加和数据库设计无关的代码会被清除掉,为了防止这种情况,可以调用schema.enableKeepSectionsByDefault();

它会让在每个class里有// KEEP INCLUDES - put your custom includes here   // KEEP INCLUDES END  这样的注释,分别有三组,对应import, field ,method,在这里面的代码不会被下一次run覆盖。

一旦你拥有了一个schema对象,你就可以使用它去添加实体了。

Entity(实体): 一个Entity对应数据库的一张表,entity有addBooleanProperty(String propertyName),addIntProperty(String propertyName) etc,基本的数据类型都有对应的方法。其中addIdProperty()默认以一个long型字段作为主键。

Entity note = schema.addEntity("Note");note.addIdProperty();note.addStringProperty("text").notNull();note.addStringProperty("comment");note.addDateProperty("date");

除了实体,还可以添加,一对一和一对多的关系。

属性和主键

以上的实体部分展示了如何给一个实体添加属性,实体的addXXXProperty方法返回一个PropertyBuilder对象,可以用于配制属性,
例如,使用columnName去复写缺省的或者你提供的column name。在ProperyBuilder对象上调用getProperty方法去访问属性对象,

对于指数(indices )和关系的创建是有必要的。

 

创建主键的约束

现 在实体必须拥有一个long或者Long类型的属性作为它们的主键,这是Android和SQLite推荐的实践方式。因为,在将来,greenDao要 准备处理很多主键的脚本,但并不是每件事都能完全实现。为了解决这个问题,你可以使用一个long类型的键并且使用一个唯一的下标去处理这个预期的key 属性。

 

缺省

greenDao 会尝试以合理的缺省值进行工作,所以开发者不用单个的配置它们。比如,表和其列名是从实体和属性名中获取到的,而不是java中的驼峰。缺省的数据库名是 大写的,单词间用下划线分隔开。比如:属性“creationDate”在数据库列中的映射为“CREATION_DATE”,

 

单个的entity添加很简单,只需要定义一个static方法,new一个Entity,把数据库的字段用对应的addProperty加上去。当表之间存在关联关系时,

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();        //order添加两个属性,并获得引用        Property orderDate = order.addDateProperty("date").getProperty();        Property customerId = order.addLongProperty("customerId").notNull().getProperty();        //order:customer = 1:n        //customerId作为Customer表的外键被Order持有        order.addToOne(customer, customerId);        //定义一个ToMany对象,customer作为N的一方,customer和order就通过customerId实现关联        ToMany customerToOrders = customer.addToMany(order, customerId);        customerToOrders.setName("orders");        customerToOrders.orderAsc(orderDate);    }

在实际开发中,可以定义全局的entity方便复用。需要注意的是每个entity的属性名不能有重复。

 

src-gen目录下生成的有每个entity对应的bean和dao,还有两个核心的DaoMaster和DaoSession.

DaoMaster:

daomaster以一定的模式持有数据库对象(SQLiteDatabase)并管理一些DAO类(而不是对象)。

有一个静态的方法创建和drop数据库表。它的内部类OpenHelper和DevOpenHelper是SQLiteOpenHelper的实现类,用于创建SQLite数据库的模式。

DaoSession:

管理指定模式下所有可用的DAO对象,你可以通过某个get方法获取到。DaoSession提供一些通用的持久化方法,比如对实体进行插入,加载,更新,刷新和删除。最后DaoSession对象会跟踪identity scope,更多细节,可以参看session文档.

 

  3、使用

  在程序入口处创建数据库。

    

DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);        SQLiteDatabase db = helper.getWritableDatabase();        DaoMaster daoMaster = new DaoMaster(db);        DaoSession daoSession = daoMaster.newSession();        NoteDao noteDao = daoSession.getNoteDao();

流程是获得DevOpenHelper对象,获得SQLiteDatabase,new DaoMaster,new DaoSession,daoSession对象get要操作的bean的到dao对象。各个Dao都有readEntity(),insert(), insertInTx()(批量插入),insertOrReplace(), insertOrReplaceInTx(),更新,删除等方法。

 

  4、小结

(1)使用greenDao的难点在于daoGenerator这个生成工程的理解和编写,当数据库的表足够复杂,创建一个个entity和它们之间的关系并不轻松。greenDao的schema,Entity,property,toOne,toMany以及DaoMaster,DaoSession概念的理解。

(2)daoGenerator工程创建好之后,对数据库的操作就很简单了,基本上就是调用现有的方法就足够应付数据库的增删改查。实际中可能还是会碰到一些问题,这就需要具体问题具体分析。比如在FlymeRedmine App开发中,Gson解析的对象,直接用对应的Dao插入,Project对象中有User类型的成员变量,插入没有问题,但是调用project.getUser()时就会出问题,因为数据库中没有存对应的user对象,project只持有user的id,并没有user对象的引用。而getUser()方法其实是通过user的外键去数据库中查找而来。

 

参考文章:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1127/2069.html

http://greendao-orm.com/

另附上官方的一个demo


0 0
原创粉丝点击