Android Sqlite 框架 GreenDao的原理與使用簡介
(轉:http://blog.csdn.net/dawnranger/article/details/43231731)
一、背景知識
ORM(Object Relation Mapping):物件關係模型。用於實現面向物件程式語言裡不同型別系統的資料之間的轉換。從效果上說,它其實是建立了一個可在程式語言裡使用的“虛擬物件資料庫”。ORM作為專案中介軟體形式實現資料在不同場景下資料關係對映,物件關係對映是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。
Android常用幾個ORM框架:ORMLite、GreenDao、ormndroid、androrm等。ORMLite和GreenDao的比較:
- ORMLite:文件全面,社群活躍,維護良好,使用簡單,容易上手,但是因為基於反射,所效率較低
- GreenDao:使用code generation,效率很高;庫檔案較小(約87KB),佔用更少記憶體, 缺點是學習成本較高,需要弄清楚其原理才能方便使用
二、原理簡介
GreenDao向SQLite資料庫提供了一個物件導向的介面,它為使用者省下了很多重複的工作,而且提供了簡便的操作介面。
為了使用GreenDao,需要在新建一個Java工程(工程中需要匯入greendao-generator-x.x.x.jar,freemarker-x.x.xx.jar),根據GreenDao的規則在其中描述資料庫的表結構,執行之後它會構建你的實體模型和DAO工具類。具體包括:
DaoMaster:
- 持有資料庫物件(SQLiteDatabase) ,並管理一些DAO類(不是物件)
- 能夠建立和刪除資料庫表
- 它的內部類OpenHelper和DevOpenHelper是SQLiteOpenHelper的實現類,用於建立SQLite資料庫的模式
DaoSession:
- 管理制定模式下所有可用的DAO物件
- 能對實體進行插入、載入、更新、重新整理、刪除操作。
DAO:
- 每個實體都有一個DAO,相對於DaoSession,它有更多的方法,比如:載入全部、InsertTx
Entity
- 可持久化的物件,由generator 生成。相當於資料庫中的一張表,所有欄位都是使用標準的Java物件的屬性
通過generator生成的這些工具類,你就可以在自己的Android工程中對進行資料庫操作,完全不需要寫任何SQL語句。
三、建表
資料庫建立:在應用中通過DaoMaster的DevOpenHelper完成。
Schema schema =newSchema(1000,"de.greenrobot.daoexample");
Entity note = schema.addEntity("Note");
note.addIdProperty().primaryKey().autoincrement();
note.addStringProperty("text").notNull();
note.addStringProperty("comment");
note.addDateProperty("date");
注:在生成的實體類中,int型別會自動轉為long型別
dao.setTableName("NoteList");
greenDAO會自動根據實體類屬性建立表字段,並賦予預設值。例如在資料庫方面的表名和列名都來源於實體類名和屬性名。預設的資料庫名稱是大寫使用下劃線分隔單詞,而不是在Java中使用的駝峰式大小寫風格。例如,一個名為“CREATIONDATE”屬性將成為一個數據庫列“CREATION_DATE”。
在使用greenDAO時,一個實體類只能對應一個表,目前沒法做到一個表對應多個實體類,或者多個表共用一種物件型別。後續的升級也不會針對這一點進行擴充套件。
四、表的增刪改查
1.查詢:
(1)QueryBuilder:
普通用法:
List joes = userDao.queryBuilder()
.where(Properties.FirstName.eq("Joe"))
.orderAsc(Properties.LastName)
.list();
巢狀情況:(查詢1970年9月之後出生的使用者)
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();
(2)Query:
可多次執行的查詢,使用QueryBuilder實際上呼叫了Query類,若果相同的查詢要執行多次的話,那應該呼叫QueryBuilder的build()方法來建立Query,而不是直接使用Query。
只返回一個結果:呼叫Query或者QueryBuilder的unique()方法,如果不希望返回null,那麼可呼叫uniqueOrThrow()方法。
返回多個結果:
- list() 所有實體被載入到記憶體中,結果通常是一個ArrayList
- listLazy() 實體在需要時才載入記憶體。表中的一個元素被第一次訪問時會被快取,下次再訪問時使用快取
- listLazyUncached() 任何對列表元素的訪問都會導致從資料庫中載入
- listIterator() 以按需載入的方式來遍歷結果,資料沒有被快取。
後三種方式使用了LazyList類,持有了一個資料庫cursor來實現按需載入。這樣是為了確保關閉LazyList和iterators。
一旦所有元素都被訪問或遍歷過,來自listLazy()的cache lazy list和來自listIterator()方法的lazy iterator將會自動關閉cursor。
然而,如果list...的處理過早的完成了,你應該呼叫 close()手動關閉。
(3)提高多次查詢效率
一旦使用QueryBuilder建立了一個query,那麼這個Query物件就可以就可以被複用來執行查詢顯然這種方式逼重新建立一次Query效率要高。
具體來說:
- 如果Query的引數沒有變更,你只需要再次呼叫List/unuque方法即可
- 如果引數發生了變化,那麼就需要通過setParameter方法來處理每一個發生改變的引數。
舉例:
Query query = userDao.queryBuilder().where(Properties.FirstName.eq("Joe"),Properties.YearOfBirth.eq(1970)).build();
List joesOf1970 = query.list();
現在複用該Query物件:
query.setParameter(0,"Maria");
query.setParameter(1,1977);
List mariasOf1977 = query.list();
由此可見,Query在執行一次build之後會將查詢結果進行快取,方便下次繼續使用。
(4)原生SQL語句
兩種方法:
Query query = userDao.queryBuilder().where(
newStringCondition("_ID IN "+
"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();
如果這裡的QueryBuilder沒有提供你想要的特性,可以使用原始的queryRaw或queryRawCreate方法。
Query query = userDao.queryRawCreate(", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID","admin");
注:寫SQL語句時推薦定義常量來表示表名或者表項,這樣可以防止出錯,因為編譯器會檢查。
(5)刪除
一次性刪除多個指定條件的資料:呼叫QueryBuilder的buildDelete方法,它會返回一個DeleteQuery。
如果資料被快取過,你可以啟用那些將要被刪除的實體。如果導致了一些使用的問題。你可以考慮清除identity scope。
(6)除錯
如果你的query沒有返回期望的結果,這裡有兩個靜態的flag,可以開啟QueryBuilder身上的SQL和引數的log。
QueryBuilder.LOG_SQL =true;
QueryBuilder.LOG_VALUES =true;
它們會在任何build方法呼叫的時候打印出SQL命令和傳入的值。這樣你可以對你的期望值進行對比,或許也能夠幫助你複製SQL語句到某些
SQLite 資料庫的檢視器中,執行並獲取結果,以便進行比較。
(7)其它
統計查詢:queryBuilder.buildCount().count();
獲取全部記錄:noteDao.loadAll();
2.插入、更新
普通方法:
Note note =newNote(null, noteText, comment,newDate());
noteDao.insert(note);
更新、批量插入:
photoDao.insertOrReplace(photo);
photoDao.insertInTx(photo);
關於資料操作的效能問題:(摘自官網)
Inserting/updating/deleting entities runs very slow. What’s wrong?
Probably, you are inserting/updating/deleting entities without using a transaction. Thus each operation is considered a transaction and SQLite needs to write to disk and do a file sync for each operation. Running all operations in a single transaction
is essential for performance (and usually makes sense in terms of consistency). It will run a magnitude faster. For example, running 1,000 inserts in a single transaction ran 500 times faster (!) than 1000 individual transactions in one of our performance
tests.
In greenDAO, use DaoSession.runInTx(Runnable) to make the given Runnable run as a transaction. If you have a list of entities of the same type, you can use the insertInTx or updateInTx methods of the DAO class belonging to the entity.
效能對比:
普通用法:400條插入,大約5秒
long startTime =System.currentTimeMillis();
for(int i =0; i !=400; i++){
Person person =newPerson(null,i+"");
personDao.insert(person);
}
long endTime =System.currentTimeMillis();
Log.e("result",""+(endTime - startTime));
開多執行緒:0.1s以內
daoSession.runInTx(newRunnable(){
@Override
publicvoid run(){
long startTime =System.currentTimeMillis();
for(int i =0; i !=400; i++){
Person person =newPerson(null, i +"");
personDao.insert(person);
}
long endTime =System.currentTimeMillis();
Log.e("result",""+(endTime - startTime));
}
}
);
批量插入:0.1s以內
long startTime =System.currentTimeMillis();
Person[] persons =newPerson[400];
for(int i =0; i !=400; i++){
persons[i]=newPerson(null, i +"");
}
personDao.insertInTx(persons);
long endTime =System.currentTimeMillis();
Log.e("result",""+(endTime - startTime));
3.刪除
清空資料表:
noteDao.deleteAll()
刪除些資料:
QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
DeleteQuery<CityInfo> bd = qb.where(Properties.Id.eq(Id)).buildDelete();
bd.executeDeleteWithoutDetachingEntities();
Deletes all matching entities without detaching them from the identity scope
publicvoid deleteAllMessages(){
RcMessagesDao messageDao = daoSession.getRcMessagesDao();
QueryBuilder qb = messageDao.queryBuilder();
qb.where(ca.acesoft.reatchat.RcMessagesDao.Properties.Favorite.eq(false));
相關推薦
Android Sqlite 框架 GreenDao的原理與使用簡介
(轉:http://blog.csdn.net/dawnranger/article/details/43231731) 一、背景知識 ORM(Object Relation Mapping):物件關係模型。用於實現面向物件程式語言裡不同型別系統的資料之間的轉換。從效
Android SQLite框架greenDAO的使用
Android中集成了SQLite資料庫,Android本身提供了完備的SDK提供訪問存取SQLite的介面,通過SQLiteOpenHelper類來管理SQLite資料庫。在SQLiteOpenHelper類中的onCreate方法中建立資料庫,在onUpgr
Android 資料庫框架GreenDao與LitePal
更多幹貨 分散式實戰(乾貨) spring cloud 實戰(乾貨) mybatis 實戰(乾貨) spring boot 實戰(乾貨) React 入門實戰(乾貨) 構建中小型網際網路企業架構(乾貨) python 學習持
分布式開源調度框架TBSchedule原理與應用
中文 就會 ans exc 中心 崩潰 任務創建 集中 通過 主要內容: 第一部分 TBSchedule基本概念及原理 1. 概念介紹 2. 工作原理 3. 源代碼分析 4. 與其它開源調度框架對照 第二
Android ORM框架GreenDao入門學習
最近想了解一下關於Android ORM的東西,在網上一搜,框架還真不少,很多人都說GreenDao效能不錯,這週末就好好搞了下。 現在Goodle推出了Android studio這款開發利器,是用Gradle構建,感覺還不錯。以下專案都是用Android studio 0.8.14開發。
分散式開源排程框架TBSchedule原理與應用
主要內容: 第一部分 TBSchedule基本概念及原理 1. 概念介紹 2. 工作原理 3. 原始碼分析 4. 與其他開源排程框架對比 第二部分 TBSchedule分散式排程示例 1. TBSchedu
SpringMVC框架設計原理與實現
一、SpringMVC框架是什麼springmvc是一套封裝網路請求的半封裝Servlet框架,是站在巨人肩膀(JDK javax.servlet.*)上做下層類的結構圖:二、Servlet規範開發的時候讀取很多專案原始碼部署--->肯定存在Servlet規範Sprin
Android Wi-Fi P2P原理與原始碼學習
一,Wi-Fi P2P相關知識 (一)P2P及其依賴的技術項 (二)P2P工作流程 包括1.裝置的發現、2.組協調、3.認證關聯、4.WPS以及4次握手。總體流程如下圖: 1. Device
Android資料庫框架GreenDao&Realm實戰分析
Android開發的童鞋應該都知道,使用官方的SQLite資料庫,可以滿足我們大部分增刪改查的需求,然而隨著Android技術的逐步成長,你會慢慢發現SQLite越來越不能滿足我們的需求。總結為以下主要幾點: 1、創表,增刪改查需要些大量程式碼,開發效率極低
Android ORM框架 greenDAO 使用方法
最近在專案中要用到語音通話功能,後來測試發現通話過程中有聽不到對方聲音的情況,經過檢測 其中有部分原因是因為有些手機在app安裝後會被手機直接禁止錄音許可權,發現問題後去解決的過程發現,系統自己提供的檢查app所獲的許可權方法 boolean flag =
Android 資料庫框架 —— GreenDao
package cn.hlq.greendaostudy.entity; import org.greenrobot.greendao.annotation.Entity; import org.greenrobot.greendao.annotation.Id; import org.greenrobot
osgi框架基礎原理與例項一
OSGI(Open Services Gateway Initiative),或者通俗點說JAVA動態模組系統,定義了一套模組應用開發的框架。OSGI容器實現方案如Knopflerfish, Equinox, and Apache Felix允許你把你的應用分成多個功能模
Android資料庫框架greenDao學習筆記 2
引言 上篇部落格中介紹了greenDao的整合方式,這篇部落格,我們介紹如何使用greenDao建立我們需要的資料表。補一張圖(來自官網),來理解greenDao,大家意會吧。 註解 先上一張圖,來對greenDao的註解有一個直觀的認識: Schema 通過在Gr
Android Orm框架(GreenDao)
GreenDao與Ormlite對比 Ormlite:簡單好用,比較符合JavaEE開發者使用習慣,註解很方便; GreenDao:為Android大大優化 ,最小的記憶體使用 ,非常高的效能優勢。
Android 中資料庫框架GreenDao與LitePal對比、整合、使用詳解,greendao與原生SQLite效能對比
2.LitePal框架詳解。【操作非常簡單,適合於資料庫操作較少的專案】 3.greendao重要的3個類【GreenDaoManager管理類 MigrationHelper資料庫升級合併類 MyOpenHelper資料庫升級操作類】【greendao快取問題】
android sqlite 的建立與使用,sqlite自定義框架。
android的四大儲存型別中,我們常用的sqlite資料庫。改資料庫為輕型資料庫,支援sql語句,據說是某一位大學教師所編寫的輕型資料庫。所上傳程式碼其實已經有一段歷史了。在我剛參加工作的時候,我的一位亦師亦友的同事,領我進入了資料的輕鬆時代。整個資料無外乎增刪改查,沒別
《分布式服務框架原理與實踐》- 總結一下吧
配額 服務調用 全量 影響 ng- 依賴 線下 分布式服務框架 微服務架構 我們聽過無數的道理,卻仍舊過不好這一生。額,我說的是技術! 《分布式服務框架原理與實踐》這本書,一直在講一些大道理,和具體的業務和我本身的工作已經沒多大關系了。但是,不管怎麽樣,還得總結下吧
TLD視覺目標跟蹤框架原理與實踐
圖像 視頻 tld comm rec 計算機 認識 實踐 計算 最近花了不少時間,仔細的做了一個有關TLD視覺目標跟蹤框架的視頻課程,希望能夠幫助一些對計算機視覺感興趣的人,通過對該課程的學習,能夠對計算機視覺技術中的一些基本問題有一定的認識和理解,進而達到技術進階的目的。
Android框架之Volley與Glide
cat name 圖片緩存 上傳文件 bsp 怎麽 每一個 ons exc PS:在看到這個題目的同時,你們估計會想,Volley與Glide怎麽拿來一塊說呢,他們雖然不是一個框架,但有著相同功能,那就是圖片處理方面。首先我們先來看一下什麽volley,又什麽是glide。
滴滴開源Android外掛化框架VirtualAPK原理分析
概述 Activity 支援 Hook ActivityManagerService Hook Instrumentation 啟動外掛Acti