Android常用数据库ORM框架ORMlite和GreenDao比较

版权声明:本文为天涯原创文章,未经天涯允许不得转载。 https://blog.csdn.net/tyyj90/article/details/50450901

一、关于ORM

对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。

对象关系映射(Object-Relational Mapping)提供了概念性的、易于理解的模型化数据的方法。ORM方法论基于三个核心原则:

简单:以最基本的形式建模数据。

传达性:数据库结构被任何人都能理解的语言文档化。

精确性:基于数据模型创建正确标准化的结构。


二、ORMLite简介

官网:http://ormlite.com/

OrmLite- Lightweight Object Relational Mapping (ORM) Java Package


三、ORMLite使用

1、工程中引入ormlite-android-4.45.jar、ormlite-core-4.45.jar两个jar包。

 

2、使用Annotation修饰,实体类中的类名映射为表名,field将映射成为对应表中的字段,还可以实现外键功能。

@DatabaseTable(tableName = "Student")
public class Student implements Serializable {
	private static final long serialVersionUID = 1230456789L;
	@DatabaseField(generatedId = true)
	private Long id;
	@DatabaseField(columnName = "name")
	private String name;
	@DatabaseField(columnName = "gender")
	private Boolean gender;
	@DatabaseField(columnName = "grade")
	private Integer grade;
	@DatabaseField(columnName = "cls")
	private Integer cls;
	@DatabaseField(columnName = "point")
	private Integer point;

3、建立helper类,helper类中辅助创建数据库、升级数据库等操作;

@Override
	public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
		try {
			TableUtils.createTable(connectionSource, Student.class);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
		try {
			TableUtils.dropTable(connectionSource, Student.class, true);
			onCreate(database, connectionSource);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

并提供单例方式获取Helper对象,获取数据操作Dao实例。

 

DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。

 

在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共API中。用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口在逻辑上对应这个特定的数据存储。

public static synchronized DatabaseHelper getHelper(Context context) {
		context = context.getApplicationContext();
		if (instance == null) {
			synchronized (DatabaseHelper.class) {
				if (instance == null)
					instance = new DatabaseHelper(context);
			}
		}
		
		return instance;
	}
	
	@SuppressWarnings("unchecked")
	public synchronized Dao getDao(Class clazz) throws SQLException {
		Dao dao = null;
		String className = clazz.getSimpleName();
		
		if (daos.containsKey(className)) {
			dao = daos.get(className);
		}
		if (dao == null) {
			dao = super.getDao(clazz);
			daos.put(className, dao);
		}
		return dao;
	}

4、实现数据库内容的增删查改具体业务逻辑,在Dao类中实现。

/** 添加数据 */
	public void addStudent(Student item) {
		try {
			daoOpe.createOrUpdate(item);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/** 删除by Name */
	public void deleteStudentByName(String name) {
		DeleteBuilder<Student, Long> deleteBuilder = daoOpe.deleteBuilder();
		Where<Student, Long> deleteWhere = deleteBuilder.where();
		try {
			deleteWhere.eq("name", name);
			deleteBuilder.delete();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
/** 根据名字查询一条数据 */
	public List<Student> getStudentByName(String name) {
		List<Student> temp = null;
		try {
			QueryBuilder<Student, Long> queryBuilder = daoOpe.queryBuilder();
			Where<Student, Long> whereBuilder = queryBuilder.where().eq("name", name);
			temp = whereBuilder.query();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return temp;
	}
/** 更新数据 */
	public void updateStudent(Student item) {
		try {
			daoOpe.update(item);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

以上就是使用ORMLite框架的基本方法。


四、GreenDao简介

GreenDao官网:http://greendao-orm.com/

greenDAO是一个可以帮助 Android 开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储、更新、删除和查询。 
greenDAO的主要设计目标:


*最大性能(最快的 Android ORM) 
*易于使用API
*高度优化
*最小内存消耗

官方Demo里共有六个工程目录,分别为:
(1).DaoCore:库目录,即jar文件如reendao-1.3.0-beta-1.jar;
(2).DaoExample:android范例工程;
(3).DaoExampleGenerator:DaoExample工程的DAO类构造器,java工程;
(4).DaoGenerator:DAO类构造器,java工程;
(5).DaoTest、PerformanceTestOrmLite:其他测试相关的工程。

 

五、GreenDao使用

 

如果是第一次使用可能对这个框架有些生疏,这个框架首先需要构建一个java工程用于自动生成一些代码,可以将代码直接生成到我们的android工程中。如果已经知道这一点以后使用这个框架就会非常迅速。

 

1.  下载greenDAO

 

要使用肯定要先下载他的软件包了,官网上有它的连接,对于maven和gradle环境直接到serarch.maven.org上下载jar包就好了。


下载的jar导入到工程里面就可以了,通常都是/libs目录下。

 

2. 前言

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

在github上下载的实例源码以及上面图中我们都会发现,会有一个generator。比如包里面会有greendao和greendao- generator,示例工程会有DaoExample和DaoExampleGenerator两个工程。

“In order to use greenDao in your project, you need tocreate a second project, the "generator project".

这个额外的工程是一个普通的java工程,而非android工程。它的任务是生成你希望的java对象所对应的DAO接口对象。

 

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

DAO的core library(greenDAO.jar)中有以下几个核心类,也是后面比用到的,先来大概了解下他们的结构。

 

DaoMaster:它保存了sqlitedatabase对象以及操作DAO classes。其提供了一些创建和删除table的静态方法,其内部类OpenHelperDevOpenHelper实现了SQLiteOpenHelper并创建数据库的框架。

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

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

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

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

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

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

 

3. 创建generator工程

(1)创建Java工程

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

freemarker是一个用java写的模板引擎,它能够基于模板来生成文本输出。应该就是用来自动生成DAO文件的。eclipse下面就是在          

properties --> Java build path --> libraries下面导入jar包。

(3)创建schema

搭建自己应用的数据库框架,包括table。创建schema时需要制定数据库的版本号、默认的Java package等参数。

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

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

schema.setDefaultJavaPackageTest("de.greenrobot.daoexample.test");

schema.setDefaultJavaPackageDao("de.greenrobot.daoexample.dao");

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

schema2.enableKeepSectionsByDefault();

schema2.enableActiveEntitiesByDefault();

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

// 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

(4)创建entity

schema中可以添加entity,简单的理解应该是entity对应一个具体的java class,entity可以添加property。Entity通常也是对应一个table。除了添加property之外,entity也可以添加to-one和to-many关系,即添加一对一的关系和一对多的关系。

public static void main(String[] args) throws Exception {
  Schema schema = new Schema(3, "de.greenrobot.daoexample");
  addNote(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");
 }

系统会自动以传入的参数作为表的名字,但也可以自定义表名称:note.setTableName("NoteTable");

(5)生成DAO文件

生成DAO文件就是使用main函数的最后一句话,其中后面的参数就是希望自动生成的代码对应的项目路径。

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

注:设置的路径必须存在,否则会抛出异常。该路径是另外的工程下面的目录,当然也可以自己不这么做,只要这个目录存在就行。在schema创建的时候指定的package接口也是相对于该路径的。

 

执行generator工程,会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件,Note是一个纯Java 类,内部各种getter和setter接口均自动创建实现了。NoteDao文件则是创建Note这个表的各个接口,包括sql语句等。

 

我的Demo代码如下:

public class MyDaoGenerator {
	
	public static void main(String[] args) throws Exception {
		// 此处配置为目标Android工程存放数据库操作相关类的包名
		Schema schema = new Schema(1, "com.example.dbdemo.greendao");
		add(schema);
		// Android工程存放源码相对路径
		new DaoGenerator().generateAll(schema, "../dbDemo/src");
	}
	
	private static void add(Schema schema) {
		// 实体类类名
		Entity infraredObj = schema.addEntity("Stundent");
		// 实体类中的id字段,自增长
		infraredObj.addIdProperty().primaryKey().autoincrement();
		// 实体类中的field(即属性)
		// 姓名
		infraredObj.addStringProperty("name").notNull();
		// 性别,true-男性;false-女性
		infraredObj.addBooleanProperty("gender");
		// 年级
		infraredObj.addIntProperty("grade");
		// 班级
		infraredObj.addIntProperty("cls");
		// 考试总分
		infraredObj.addIntProperty("point");
	}
	
}

4. 创建基于greenDao的android工程

完成了generator工作之后后面的东西就简单了,在工程中实现业务逻辑的增删查改,Demo中把这些操作都封装到了一个Helper类中。

package com.example.dbdemo.greendao;
……
public class StudentDbHelper {
	private static Context mContext;
	private static StudentDbHelper instance;
	private StundentDao stundentDao;
	private StudentDbHelper() {}
	public static StudentDbHelper getInstance(Context context) {
		if (instance == null) {
			instance = new StudentDbHelper();
			if (mContext == null) {
				mContext = context;
			}
			// 数据库对象
			DaoSession daoSession = MainApp.getDaoSession(mContext);
			instance.stundentDao = daoSession.getStundentDao();
		}
		return instance;
	}

	/** 添加数据 */
	public void addStundent(Stundent item) {
		stundentDao.insert(item);
	}
	
	/** 删除by Name */
	public void deleteStundentByName(String name) {
		QueryBuilder<Stundent> qb = stundentDao.queryBuilder();
		DeleteQuery<Stundent> bd = qb.where(Properties.Name.eq(name)).buildDelete();
		bd.executeDeleteWithoutDetachingEntities();
	}
	
	/** 删除全部 */
	public void deleteStundentAll() {
		stundentDao.deleteAll();
	}
	
	/** 获取全部数据 */
	public List<Stundent> getStundentAll() {
		return stundentDao.loadAll();
	}
	
	/** 根据名字查询一条数据 */
	public List<Stundent> getStundentByName(String name) {
		QueryBuilder<Stundent> qb = stundentDao.queryBuilder();
		qb.where(Properties.Name.eq(name));
		return qb.list();
	}
	
	/** 根据性别查询数据 */
	public List<Stundent> getStundentByGender(boolean gender) {
		QueryBuilder<Stundent> qb = stundentDao.queryBuilder();
		qb.where(Properties.Gender.eq(gender));
		return qb.list();
	}
	
	/** 更新数据 */
	public void updateStundent(Stundent item) {
		stundentDao.update(item);
	}
	
	/** 更新数据by Id */
	public void updateStundent(Stundent item, long rowId) {
		stundentDao.updateKeyAfterInsert(item, rowId);
	}
}


六、ORMLite与GreenDao的比较

 

1.性能比较

以下是我建立的一个测试DEMO的实验数据,将测试DEMO部署到Nexus 5 android 5.1.1系统上运行得到如下数据,可能不同的手机会有一定的差异。

每次插入1000条数据耗时Log图如下:


每次插入10000条数据耗时Log图如下:


查询全部数据耗时Log图如下:


更新一条数据耗时Log图如下:


删除数据耗时Log图如下:


使用ORMLite删除全部数据,Log出现一些error信息,ORMLite没有支持全部删除数据的API,实际上只能通过间接方式全部删除(查询所有数据并逐条删除)。

 

操作

ORMLite与GreenDao性能比较

插入1000条数据

耗时均在11000ms左右,二者性能差不多

插入10000条数据

耗时均在120000ms左右,二者性能差不多

查询全部数据

ORMLite耗时在2500+ms;GreenDao耗时小于2000ms,GreenDao性能较优

更新一条数据

耗时均在10ms左右,性能差不多

删除所有数据

ORMLite耗时在2900+ms;GreenDao耗时在12ms,GreenDao性能较优

 

2.易用性比较

 

①API设计上都使用了Builder的方式拼接条件操作数据库,但在整体API考虑上ORMLite

在全部数据删除时欠佳,整体API设计上GreenDao较优;

②GreenDao需要额外工程辅助生成代码,对于初次使用者而言,较难使用,但上手后使用起来非常快捷;ORMLite采用注解的方式,更加灵活,使用方便。

 

总之,如果学会了GreenDao这个第三方ORM框架后,整体性能和使用上都比ORMLite优秀。

 

写在最后,GreenDao官方放出的性能对比图如下:


greendao的insert和update效率要比ormlite快两倍左右,load效率达到4倍多。

 

七、参考资料

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

2. http://blog.csdn.net/u012565107/article/details/21546829?utm_source=tuicool&utm_medium=referral


八、DEMO下载


点此下载



猜你喜欢

转载自blog.csdn.net/tyyj90/article/details/50450901