1. 程式人生 > >Android常用資料庫ORM框架ORMlite和GreenDao比較

Android常用資料庫ORM框架ORMlite和GreenDao比較

一、關於ORM

物件關係對映(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程式技術,用於實現面向物件程式語言裡不同型別系統的資料之間的轉換。從效果上說,它其實是建立了一個可在程式語言裡使用的“虛擬物件資料庫”。

面向物件是從軟體工程基本原則(如耦合、聚合、封裝)的基礎上發展起來的,而關係資料庫則是從數學理論發展而來的,兩套理論存在顯著的區別。為了解決這個不匹配的現象,物件關係對映技術應運而生。

物件關係對映(Object-Relational Mapping)提供了概念性的、易於理解的模型化資料的方法。ORM方法論基於三個核心原則:

簡單:以最基本的形式建模資料。

傳達性:資料庫結構被任何人都能理解的語言文件化。

精確性:基於資料模型建立正確標準化的結構。

二、ORMLite簡介

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是一個可以幫助 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倍多。

七、參考資料

八、DEMO下載

點此下載