1. 程式人生 > >Android 資料庫ORM框架——GreenDao

Android 資料庫ORM框架——GreenDao

  • 最近在對開發專案的效能進行優化。由於專案裡涉及了大量的快取處理和資料庫運用,需要對資料庫進行頻繁的讀寫、查詢等操作。因此首先想到了對整個專案的資料庫框架進行優化。

    原先使用android本身內建的sqllite,也就是用的最基本的SQLiteOpenHelper方法,這種方法對自己來說比較方便易懂。但是在使用過程中感覺很繁瑣,從建表到對錶的增刪改查等操作,如果表物件的屬性很多,就需要使用大量的程式碼來執行建表、插入等。在程式碼執行中還需要對資料庫和遊標的進行及時關閉(開啟使用,用完關閉),而且還需要部分sql語言,這在開發中產生bug進行除錯時尤其不方便。

    目前android經常用的orm框架主要有greenDAO、OrmLite、AndrORM。 綜合了網上的各種評價,greenDAO的執行效率最高,記憶體消耗最少,效能最佳。因此決定採用greenDAO框架,對專案的orm框架進行改進。

    技術分享

    greenDAO與ORMLite效能對比

    經過兩天的修改,終於將專案裡的資料庫相關的都優化完了。在這過程中,發現greenDAO的效能確實不錯,而且使用相當方便,不再需要涉及到任何的sql語言,可以直接通過物件類進行建表、增刪改查等,尤其是api介面又方便易懂。在摸索學習中發現國內相關學習資料實在實在是太少,遂決定在此記錄下自己對使用這個orm框架的一些心得和方法總結。

    一、greenDAO相關

    1.greenDAO官網:http://greendao-orm.com/

    2.專案下載地址:https://github.com/greenrobot/greenDAO(或者官網)

    greenDAO是一個可以幫助

    Android開發者快速將Java物件對映到SQLite資料庫的表單中的ORM解決方案,通過使用一個簡單的面向物件API,開發者可以對Java物件進行儲存、更新、刪除和查詢。

    greenDAO的主要設計目標:

    *最大效能(最快的Android ORM)

    *易於使用API

    *高度優化

    *最小記憶體消耗

    二、使用步驟

    官方Demo裡共有六個工程目錄,分別為:

    (1).DaoCore:庫目錄,即jar檔案greendao-1.3.0-beta-1.jar的程式碼;

    (2).DaoExample:android範例工程;

    (3).DaoExampleGenerator:DaoExample工程的DAO類構造器,java工程;

    (4).DaoGenerator:DAO類構造器,java工程;

    (5).DaoTest、PerformanceTestOrmLite:其他測試相關的工程。

    (一)DAO類構造

    首先需要新建一個java工程來生成DAO類檔案,該工程需要匯入greendao-generator.jar和freemarker.jar檔案到專案中。

    package de.greenrobot.daogenerator.gentest;
            import de.greenrobot.daogenerator.DaoGenerator;
            import de.greenrobot.daogenerator.Entity;
            import de.greenrobot.daogenerator.Property;
            import de.greenrobot.daogenerator.Schema;
            import de.greenrobot.daogenerator.ToMany;
            /**
     08.* Generates entities and DAOs for the example project DaoExample.
     09.*
     10.* Run it as a Java application (not Android).
     11.*
     12.* @author Markus
     13.*/
    public class ExampleDaoGenerator
            {
    
                public static void main(String[] args) throws Exception
                {
                    Schema schema = new Schema(3, "de.greenrobot.daoexample");
    
                    addNote(schema);
                    addCustomerOrder(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");
                }
    
                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 key<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>
    order.addIdProperty();
                    Property orderDate = order.addDateProperty("date").getProperty();
                    Property customerId = order.addLongProperty("customerId").notNull().getProperty();
                    order.addToOne(customer, customerId);
    
                    ToMany customerToOrders = customer.addToMany(order, customerId);
                    customerToOrders.setName("orders");
                    customerToOrders.orderAsc(orderDate);
                }
    
            }

    在main方法中,

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

    該方法第一個引數用來更新資料庫版本號,第二個引數為要生成的DAO類所在包路徑。

    然後進行建表和設定要生成DAO檔案的目標工程的專案路徑。

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

    其中src-gen這個目錄名需要在執行前手動建立,否則會報錯。

    如果執行後出現以下錯誤,則匯入DaoGenerator專案的dao.ftl檔案即可(或者直接使用DaoGenerator來生成DAO檔案)。

    Exception in thread "main" java.io.FileNotFoundException: Template "dao.ftl" not found. at freemarker.template.Configuration.getTemplate(Configuration.java:742) at freemarker.template.Configuration.getTemplate(Configuration.java:665) at de.greenrobot.daogenerator.DaoGenerator.<init>(DaoGenerator.java:68) at de.greenrobot.daogenerator.gentest.ExampleDaoGenerator.main(ExampleDaoGenerator.java:41)

    執行後出現以下的提示說明DAO檔案自動生成成功了,重新整理一下DaoExample專案即可看到。

    greenDAO Generator Copyright 2011-2013 Markus Junginger, greenrobot.de. Licensed under GPL V3. This program comes with ABSOLUTELY NO WARRANTY Processing schema version 3... Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\NoteDao.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Note.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\CustomerDao.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Customer.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\OrderDao.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\Order.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\DaoMaster.java Written F:\Android_Ex\work_10\DaoExample\src-gen\de\greenrobot\daoexample\DaoSession.java Processed 3 entities in 204ms

    執行後可以看到,DaoExample專案src-gen下面自動生成了8個檔案,3個實體物件,3個dao,1個DaoMaster,1個DaoSession.

    (二)建立表

    1.建立一個實體類

    Entity note = schema.addEntity("Note");

    預設表名就是類名,也可以自定義表名

    1.dao.setTableName("NoteList");

    greenDAO會自動根據實體類屬性建立表字段,並賦予預設值。例如在資料庫方面的表名和列名都來源於實體類名和屬性名。預設的資料庫名稱是大寫使用下劃線分隔單詞,而不是在Java中使用的駝峰式大小寫風格。例如,一個名為“CREATIONDATE”屬性將成為一個數據庫列“CREATION_DATE”。

    設定一個自增長ID列為主鍵:

    1.dao.addIdProperty().primaryKey().autoincrement();

    設定其他各種型別的屬性:

    dao.addIntProperty("cityId");
    dao.addStringProperty("infoType").notNull();//非null欄位
    dao.addDoubleProperty("Id");

    在生成的實體類中,int型別為自動轉為long型別。

    如果在編譯過程中出現以下錯誤,那麼有可能是主鍵的型別錯誤所致:

    1.java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

    在使用greenDAO時,一個實體類只能對應一個表,目前沒法做到一個表對應多個實體類,或者多個表共用一種物件型別。後續的升級也不會針對這一點進行擴充套件。

    (二)表的增刪改查

    增刪改查相當方便,完全的面向物件,不需要涉及到任何的sql語言。

    1.查詢

    範例1:查詢某個表是否包含某個id:

    1.public boolean isSaved(int ID) 2.{ 3.QueryBuilder<SaveList> qb = saveListDao.queryBuilder(); 4.qb.where(Properties.Id.eq(ID)); 5.qb.buildCount().count(); 6.return qb.buildCount().count() > 0 true false; 7.}

    範例2:獲取整個表的資料集合,一句程式碼就搞定!

    public List<PhotoGalleryDB> getPhotoGallery()
    {
        return photoGalleryDao.loadAll();// 獲取圖片相簿
    }

    範例3:通過一個欄位值查詢對應的另一個欄位值(為簡便直接使用下面方法,也許有更簡單的方法,尚未嘗試)

    01./** 通過圖片id查詢其目錄id */ 02.public int getTypeId(int picId) 03.{ 04.QueryBuilder<PhotoGalleryDB> qb = photoGalleryDao.queryBuilder(); 05.qb.where(Properties.Id.eq(picId)); 06.if (qb.list().size() > 0) 07.{ 08.return qb.list().get(0).getTypeId(); 09.} 10.else 11.{ 12.return -1; 13.} 14.}

    範例4:查詢所有第一姓名是“Joe”並且以lastname排序。

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

    範例5:多重條件查詢

    (1)獲取id為cityId並且infotype為HBContant.CITYINFO_SL的資料集合:

    1.public List<CityInfoDB> getSupportingList(int cityId) 2.{ 3.QueryBuilder<CityInfoDB> qb = cityInfoDao.queryBuilder(); 4.qb.where(qb.and(Properties.CityId.eq(cityId),Properties.InfoType.eq(HBContant.CITYINFO_SL))); 5.qb.orderAsc(Properties.Id);// 排序依據 6.return qb.list(); 7.}

    (2)獲取firstname為“Joe”並且出生於1970年10月以後的所有user集合:

    1.QueryBuilder qb = userDao.queryBuilder(); 2.qb.where(Properties.FirstName.eq("Joe"), 3.qb.or(Properties.YearOfBirth.gt(1970), 4.qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10)))); 5.List youngJoes = qb.list();

    範例6:獲取某列物件

    1.picJsonDao.loadByRowId(picId);

    2.增添/插入、修改

    插入資料更加簡單,也是隻要一句程式碼便能搞定!

    1.public void addToPhotoTable(Photo p) 2.{ 3.photoDao.insert(p); 4.}

    插入時需要new一個新的物件,範例如下:

    1.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this"notes-db"null); 2.db = helper.getWritableDatabase(); 3.daoMaster = new DaoMaster(db); 4.daoSession = daoMaster.newSession(); 5.noteDao = daoSession.getNoteDao(); 6.Note note = new Note(null, noteText, comment, new Date()); 7.noteDao.insert(note);

    修改更新:

    1.photoDao.insertOrReplace(photo); 2.photoDao.insertInTx(photo);

    3.刪除:

    (1)清空表格資料

    1./** 清空相簿圖片列表的資料 */ 2.public void clearPhoto() 3.{ 4.photoDao.deleteAll(); 5.}

    (2)刪除某個物件

    1.public void deleteCityInfo(int cityId) 2.{ 3.QueryBuilder<DBCityInfo> qb = cityInfoDao.queryBuilder(); 4.DeleteQuery<DBCityInfo> bd = qb.where(Properties.CityId.eq(cityId)).buildDelete(); 5.bd.executeDeleteWithoutDetachingEntities(); 6.}

    參考:https://github.com/greenrobot/greenDAO/issues/34

    由上可見,使用greenDAO進行資料庫的增刪改查時及其方便,而且效能極佳。

    (三)常用方法筆記

    1.在Application實現得到DaoMaster和DaoSession的方法:

    private static DaoMaster daoMaster;
        private static DaoSession daoSession;
    
            * 取得DaoMaster
            *
            * @param context
            * @return
    */
            public static DaoMaster getDaoMaster(Context context)
               {
                   if (daoMaster == null)
                      {  
                         OpenHelper helper = new DaoMaster.DevOpenHelper(context, HBContant.DATABASE_NAME, null);
                         daoMaster = new DaoMaster(helper.getWritableDatabase());
                      }
            return daoMaster;
            }
    /**
     * 取得DaoSession
     *
     * @param context
    * @return
    */
    public static DaoSession getDaoSession(Context context)
            {
              if (daoSession == null)
                { 
                  if (daoMaster == null)
                    {
                       daoMaster = getDaoMaster(context);
                    }
                  daoSession = daoMaster.newSession();
                }
              return daoSession;
            }

    2.增刪改查工具類:

    public class DBHelper
    {
            private static Context mContext;
            private static DBHelper instance;
    
            private CityInfoDBDao cityInfoDao;
    
            private DBHelper()
            {
            }
    
            public static DBHelper getInstance(Context context)
            {
            if (instance == null)
            {
            instance = new DBHelper();
            if (mContext == null)
            {
            mContext = context;
            }
    
            // 資料庫物件
    DaoSession daoSession = HBApplication.getDaoSession(mContext);
            instance.cityInfoDao = daoSession.getCityInfoDBDao();
            }
            return instance;
            }
    
            /** 新增資料 */
    public void addToCityInfoTable(CityInfo item)
            {
            cityInfoDao.insert(item);
            }
    
            /** 查詢 */
    public List<EstateLoveListJson> getCityInfoList()
            {
            QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
            return qb.list();
            }
    
            /** 查詢 */
    public List<CityInfo> getCityInfo()
            {
            return cityInfoDao.loadAll();// 查詢圖片相簿
    }
    
            /** 查詢 */
    public boolean isSaved(int Id)
            {
            QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
            qb.where(Properties.Id.eq(Id));
            qb.buildCount().count();
            return qb.buildCount().count() > 0 ? true : false;// 查詢收藏表
    }
    
            /** 刪除 */
    public void deleteCityInfoList(int Id)
            {
            QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
            DeleteQuery<CityInfo> bd = qb.where(Properties.Id.eq(Id)).buildDelete();
            bd.executeDeleteWithoutDetachingEntities();
            }
    
            /** 刪除 */
    public void clearCityInfo()
            {
            cityInfoDao.deleteAll();
            }
    
            /** 通過城市id查詢其型別id */
    public int getTypeId(int cityId)
            {
            QueryBuilder<CityInfo> qb = cityInfoDao.queryBuilder();
            qb.where(Properties.Id.eq(cityId));
            if (qb.list().size() > 0)
            {
            return qb.list().get(0).getTypeId();
            }
            else
    {
            return 0;
            }
            }
    
            /** 多重查詢 */
    public List<CityInfo> getIphRegionList(int cityId)
            {
            QueryBuilder<CityInfoDB> qb = cityInfoDao.queryBuilder();
            qb.where(qb.and(Properties.CityId.eq(cityId), Properties.InfoType.eq(HBContant.CITYINFO_IR)));
            qb.orderAsc(Properties.Id);// 排序依據
    return qb.list();
            }
    }
  • 相關推薦

    Android 資料庫ORM框架——GreenDao

    最近在對開發專案的效能進行優化。由於專案裡涉及了大量的快取處理和資料庫運用,需要對資料庫進行頻繁的讀寫、查詢等操作。因此首先想到了對整個專案的資料庫框架進行優化。 原先使用android本身內建的sqllite,也就是用的最基本的SQLiteOpenHelper方法,這種方法對自己來說比較方便易懂。但是

    Android開源:資料庫ORM框架GreenDao學習(三)封裝工具類使用

    部落格轉載地址:http://www.it165.net/pro/html/201401/9026.html         上一篇中講解了基本的增刪改查,本篇繼續講解 QureyBuilder 使用,及工具類封裝使用   一、使用QureyBuilder實現表的增刪改查

    Android資料庫ORM框架用法、原始碼和效能比較分析

    基本用法 LitePal LitePal是一款開源的Android資料庫框架,它採用了物件關係對映(ORM)的模式,LitePal很“輕”,jar包只有100k不到,使用起來也比較簡單,原始碼地址為Github地址。 首先需要引入lib,可以通過g

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

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

    Android 資料庫ORM開源框架greenDAO

    我相信,在平時的開發過程中,大家一定會或多或少地接觸到 SQLite。然而在使用它時,我們往往需要做許多額外的工作,像編寫 SQL 語句與解析查詢結果等。所以,適用於 Android 的ORM 框架也就孕育而生了,現在市面上主流的框架有 OrmLite、Suga

    Android ORM框架GreenDao入門學習

    最近想了解一下關於Android ORM的東西,在網上一搜,框架還真不少,很多人都說GreenDao效能不錯,這週末就好好搞了下。 現在Goodle推出了Android studio這款開發利器,是用Gradle構建,感覺還不錯。以下專案都是用Android studio 0.8.14開發。

    Android ORM框架 greenDAO 使用方法

    最近在專案中要用到語音通話功能,後來測試發現通話過程中有聽不到對方聲音的情況,經過檢測 其中有部分原因是因為有些手機在app安裝後會被手機直接禁止錄音許可權,發現問題後去解決的過程發現,系統自己提供的檢查app所獲的許可權方法 boolean flag =

    Android Orm框架(GreenDao)

    GreenDao與Ormlite對比 Ormlite:簡單好用,比較符合JavaEE開發者使用習慣,註解很方便; GreenDao:為Android大大優化 ,最小的記憶體使用 ,非常高的效能優勢。 

    手把手帶你擼一套Android簡易ORM框架

    ORM概念 實體模型建立 註解列 ID 主鍵 自增長 資料表的列

    java中輕量級資料庫ORM框架:JOOQ

    1、使用maven下載 <!-- https://mvnrepository.com/artifact/org.jooq/jooq --> <dependency> <gro

    提高android資料庫效能,GreenDao初步使用

    前言 基本上android開發都會用到資料庫,資料庫的出現就是為了快取資料,但是一但我們的資料很多很多的時候呢?哪該怎麼處理呢,所以最近我在網上了解了下一些有關android資料庫的框架,發現有那麼幾款資料庫框架的。我初步對比了一下,發現GrennDao還是非

    Python元類實戰,通過元類實現資料庫ORM框架

    本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是Python專題的第19篇文章,我們一起來用元類實現一個簡易的ORM資料庫框架。 本文主要是受到了廖雪峰老師Python3入門教程的啟發,不過廖老師的部落格有些精簡,一些小白可能看起來比較吃力。我在他的基礎上做了一些補充和註釋

    Android ORM 框架GreenDao 資料庫升級

    前言 一,GreenDao 預設的升級方式 GreenDao 預設的升級方式是刪除所有舊版,在重新建新表,這樣一來使用者的本地歷史資料則會丟失,這點我們通過DaoMaster 的內部類 DevOpenHelper 原始碼可以瞭解到。

    Android 資料庫框架GreenDao與LitePal

    更多幹貨 分散式實戰(乾貨) spring cloud 實戰(乾貨) mybatis 實戰(乾貨) spring boot 實戰(乾貨) React 入門實戰(乾貨) 構建中小型網際網路企業架構(乾貨) python 學習持

    Android ORM 框架greenDAO 使用心得

    前言 我相信,在平時的開發過程中,大家一定會或多或少地接觸到 SQLite。然而在使用它時,我們往往需要做許多額外的工作,像編寫 SQL 語句與解析查詢結果等。所以,適用於 Android 的ORM 框架也就孕育而生了,現在市面上主流的框架有 OrmLite、SugarOR

    Android ORM 框架GreenDao 使用詳解(進階篇)

    前言 一、複雜表結構 a, 使用 @ToOne 建立一對一 ( 1 : 1) 關係 @Entity public class Order { @Id private Long id; private lo

    Android 進階】ORM 框架greenDAO學習筆記

    前言 當初學習Hibernate的時候就非常驚歎這種ORM思想,後來才知道原來Android中也有這種基於ORM思想的開源框架greenDAO。 greenDAO簡介: 簡單的講,greenDAO 是一個將物件對映到 SQLite 資料庫

    Android ORM 框架GreenDao 使用詳解

        一、GreenDao 簡介greenDAO 是一款開源的面向 Android 的輕便、快捷的 ORM 框架,將 Java 物件對映到 SQLite   資料庫中,我們操作資料庫的時候,不在需要編寫複雜的 SQL語句, 在效能方面,greenDAO 針對 Android

    Android資料庫框架GreenDao&Realm實戰分析

    Android開發的童鞋應該都知道,使用官方的SQLite資料庫,可以滿足我們大部分增刪改查的需求,然而隨著Android技術的逐步成長,你會慢慢發現SQLite越來越不能滿足我們的需求。總結為以下主要幾點: 1、創表,增刪改查需要些大量程式碼,開發效率極低

    Android資料庫框架一、GreenDao

    簡述:greenDAO 是一個將物件對映到 SQLite 資料庫中的輕量且快速的 ORM 解決方案。 其優點還包括以下幾點: 1.存取速度快;  2.支援資料庫加密;  3.輕量級;  4.啟用實體;  5.支援快取;  6.程式碼自動生成; 7.greenDAO 支援 pr