1. 程式人生 > >【Android 進階】ORM 框架之 greenDAO學習筆記

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

前言

當初學習Hibernate的時候就非常驚歎這種ORM思想,後來才知道原來Android中也有這種基於ORM思想的開源框架greenDAO。

greenDAO簡介

簡單的講,greenDAO 是一個將物件對映到 SQLite 資料庫中的輕量且快速的 ORM 解決方案。(greenDAO is a light & fast ORM solution that maps objects to SQLite databases.) Dao全稱是Data Access Object – 資料訪問物件.它是一箇中間件,物件正是通過它才能和資料庫中的表建立聯絡.

什麼是ORM

ORM全稱是Object Relationship Mapping – >物件關係對映,將一個物件對映為資料庫中的一個表.
物件關係對映,簡單的說就是物件模型和關係模型的一種對映。為什麼要有這一個對映?因為現在的開發語言基本是oop的,但是傳統的資料庫卻是關係型的,為了可以靠貼近面向物件開發,我們想要像操作物件一樣操作資料庫。

ORM 的優點

  • 讓業務程式碼訪問物件,而不是資料庫表
  • 隱藏面向物件的邏輯SQL查詢詳情
  • 無需處理資料庫實現

原生操作資料庫的api的缺點

  • 手動拼接sql
  • 大量而重複操作資料庫程式碼
  • 不能自動把資料中的資料對映為物件
  • 沒有實現級聯查詢

主流的ORM框架:

  • OrmLiet
  • SugarORM
  • LitePal
  • GreenDAO

對比一個開源框架是否更優秀,一般從下面幾個點來對比

  • 效能:效能好一般指的是效率問題
  • 文件:完整的文件可以避免很多彎路,方便學習
  • 流行性:流行證明使用者群體多,也方便交流合作
  • 使用是否簡單:學習成本問題
  • 拓展性:拓展性當然需要

greenDao優點

  • 一個精簡的庫
  • 效能最大化
  • 記憶體開銷最小化
  • 易於使用的 APIs
  • 對 Android 進行高度優化

學習方法

對於一項新技術,我本人非常推崇看官方的英文介紹,這樣原汁原味。
- 官網:官網
- 官方github:

greenDao

接下來總結下使用步驟。

如何使用GreenDAO

第一步

使用AS新建專案

app module 裡面新增gradle依賴:

compile 'de.greenrobot:greendao:2.1.0'

不要忘記同步一下

第二步

在專案中新建一個module,型別選擇Java Library如下圖,命名為greendaogenerate

這裡寫圖片描述

在該module的gradle裡面新增依賴:

compile 'de.greenrobot:greendao-generator:2.1.0'

不要忘記同步一下

第三步

在greendaogenerate這個module裡面D的MyClass類里根據greenDAO的api配置資料庫幫助類以及建表。示例如下:

public class MyClass {
 public static void main(String arg[]){
        //第一個引數是db的版本號,第二個是生成的包名(該包下若干資料庫操作幫助類)
        Schema schema = new Schema(1,"www.greendao.com");

        Entity son = schema.addEntity("Son");//建立一個son表
        //給son表新增屬性
         son.addStringProperty("name");
         son.addIntProperty("age");
         son.addIdProperty();
         Property fatherId =  son.addLongProperty("fatherId").getProperty();//設定外來鍵


         Entity father = schema.addEntity("Father");//建立一個father表
         //給father表新增屬性
         father.addIdProperty();
         father.addStringProperty("name");
         father.addIntProperty("age");

         son.addToOne(fater,fatherId);//建立關聯

 try {
            //設定生成的包(www.greendao.com)所存放的的路徑
            new DaoGenerator().generateAll(schema,"app/src/main/java");
        }catch (Exception e){
            e.printStackTrace();
        }

     }
}

執行該MyClass類,結果如下:
這裡寫圖片描述

這裡寫圖片描述

這時候就可以在專案中使用這些由greenDAO框架生成的資料庫幫助類進行測試了。

第四步

在MainActivity裡面具體使用,api的使用示例以及介紹見下面程式碼


public class MainActivity extends AppCompatActivity {

    //greenDAO提供的幫助類
    private DaoMaster master;
    private DaoSession session;
    private SQLiteDatabase db;
    private SonDao sonDao;
    private FatherDao fatherDao;
    private void openDb(){
        //建立一個名為person.db的資料庫
        db = new DaoMaster.DevOpenHelper(MainActivity.this,"person.db",null).getWritableDatabase();
        master = new DaoMaster(db);
        session = master.newSession();
        //獲得son表操作資料庫類的物件
        sonDao = session.getSonDao();
        //獲得father表操作資料庫類的物件
        fatherDao = session.getFatherDao();
    }

    //插入資料
    private void addPerson(){
    //下面程式碼具體得根據資料庫表的關係,這裡只是示例(son有多個father)
        Son son = new Son();
        son.setName("nate");
        son.setAge(29);
        sonDao.insert(son);

        Father father = new Father();
        father.setName("Tom");
        father.setSon(son);
        fatherDao.insert(father);

        Father father2 = new Father();
        father2.setName("Jane");
        father2.setSon(son);
        fatherDao.insert(father2);

    }

//常用api:
//list() 直接取出資料返回一個list並快取資料
//listLazy() 不直接取出資料返回一個list有快取,需手動close
//listLazyUncached() 延遲載入返回一個list不快取資料,需手動close
//listIterator() 遍歷資料,返回一個迭代器

    public void queryAll(){
        //listLazy()懶載入,多個表級聯查詢使用最佳
       List<Son> list = sonDao.queryBuilder().list();//查詢son表中的所有資料,返回集合
       for (Son son: list){
           Log.d("nate","queryAll() called with: "+son);
       }
    }

    //條件查詢: Eq 查詢
    public void queryEq(){
       Son nate =  sonDao.queryBuilder().where(SonDao.Properties.Name.eq("nate")).unique();
       Log.d("nate","queryEq called with:"+ nate);
    }

    //條件查詢: like 查詢
    public void queryLike(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Name.like("nate%")).list();
        Log.d("nate","queryEq called with:"+ data);
    }

    //條件查詢: between 查詢
    public void queryBetween(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Age.between(16,20)).list();
        Log.d("nate","queryBetween called with:"+ data);
    }

    //條件查詢: > 大於 查詢
    public void queryGt(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Age.gt(16)).list();
        Log.d("nate","queryGt called with:"+ data);
    }

    //條件查詢: < 小於 查詢
    public void queryLt(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Age.lt(16)).list();
        Log.d("nate","queryLt called with:"+ data);
    }

    //條件查詢: NotEq 查詢
    public void queryNotEq(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Age.notEq(16)).list();
        Log.d("nate","queryNotEq called with:"+ data);
    }

    //條件查詢: GE 大於等於 查詢
    public void queryGE(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Age.ge(16)).list();
        Log.d("nate","queryGE called with:"+ data);
    }

    //條件查詢: 排序 查詢
    public void queryOrder(){
        List data =  sonDao.queryBuilder().where(SonDao.Properties.Name.like("nate%"))
                .orderDesc(SonDao.Properties.Age).list();
        Log.d("nate","queryOrder called with:"+ data);
    }

    //拼裝sql語句查詢,在api無法滿足查詢需求的情況下使用
    public void querySQL(){
        List data =  sonDao.queryBuilder()
                .where(new WhereCondition.StringCondition(
                        "FATHER_ID IN" +"{SELECT _ID FROM FATHER WHERE AGE <50}"
                )).list();
        Log.d("nate","querySQL called with:"+ data);
    }

    //多執行緒查詢:有興趣可以看原始碼
    public void queryThread(){
        final Query query = sonDao.queryBuilder().build();
        new Thread(){
            @Override
            public void run() {
                List data = query.forCurrentThread().list();
                Log.d("nate","queryThread called with:"+ data);
            }
        };
    }
    //一對多查詢:具體得看資料表關係
    public void queryOneToMany(){
        List<Son> sons = sonDao.queryBuilder().list();//查詢son表中的所有資料,返回集合
        for (Son son:sons){
            List<Father> fathers = son.getFathers();
            for (Father father:fathers){
                Log.d("nate","queryOneToMany() called with: "+son.getName()+" father:"+father.getName());
            }
        }
    }
    //一對一查詢:具體得看資料表關係
    public void queryOneToOne(){
        List<Son> sons = sonDao.queryBuilder().list();//查詢son表中的所有資料,返回集合
        for (Son son:sons){
           // Log.d("nate","queryOneToOne() called with: "+son.getFather().getName());
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //開啟一個數據庫
         openDb();

        //向資料庫新增person
         addPerson();

        //設定列印sql語句,方便檢視
        QueryBuilder.LOG_SQL = true;
        QueryBuilder.LOG_VALUES = true;

        //選擇具體需要的查詢方式測試:如queryOrder
        queryOrder();

    }
}

對資料庫的操作後必然想檢視資料庫的資料是否有變化,但是android檢視資料庫不是很方便,幸好有如下這個好工具。

推薦工具:stetho

facebook推出的一款可以在Chrome檢視app資料庫的工具
在專案中新增依賴:

compile 'com.facebook.stetho:stetho:1.3.1'

初始化:

 public class MyApplication extends Application {
   public void onCreate() {
     super.onCreate();
     Stetho.initializeWithDefaults(this);
   }
 }

執行App, 開啟Chrome輸入chrome://inspect/#devices

chrome會檢測到我們的app,點選inspect進入檢視頁面即可

原始碼

總結

如果學過JavaEE開發,用過Hibernate框架的就會非常容易理解greenDAO框架,兩者都是基於ORM的思想:ORM-物件關係對映,將一個物件對映為資料庫中的一個表。
此外,學習一個框架,我認為不只是要學會怎麼使用,最重要的是深入學習這種設計思想以及欣賞底層封裝的程式碼的藝術。

感謝

後話

歡迎關注我的微信公眾號,不定時推送乾貨
這裡寫圖片描述

相關推薦

Android ORM 框架 greenDAO學習筆記

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

Android 圖片載入框架Glide

生活 cannot 簡單介紹 style codes 詳細 npr 濾鏡 ive 簡單介紹 在泰國舉行的谷歌開發人員論壇上,谷歌為我們介紹了一個名叫 Glid

Android 仿抖音系列翻頁上下滑切換視訊(四)

大家好,我們又見面了。這是這個系列的第四篇,在這篇文章之前,建議可以先看下之前系列的文章,為了節省篇幅,之前詳細說過的地方,這裡就不再詳細描述了,下面是目錄: 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊

Android 仿抖音系列列表播放視訊(三)

在上一篇【Android 進階】仿抖音系列之列表播放視訊(二)中,我們實現列表播放視訊,這一篇我們來對其做些優化。 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊(二) 【Android 進階】仿抖音

Android 仿抖音系列列表播放視訊(二)

上一篇中,我們實現了仿抖音上下翻頁切換視訊的效果,詳見【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一),這一篇,我們來實現抖音列表播放視訊。 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊(二)

Android 仿抖音系列翻頁上下滑切換視訊(一)

最近公司在做個短視訊的專案,其中借鑑了很多抖音的設計,其中就有抖音的上下滑切換視訊。 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊(二) 【Android 進階】仿抖音系列之列表播放視訊(三)

Android 仿抖音系列視訊預覽和錄製(五)

大家好,又見面了。在前幾篇中,我們通過2種方式實現了仿抖音的翻頁切換視訊,仿抖音列表播放視訊功能,這一篇,我們來說說視訊的錄製。 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊(二) 【Android

Android如何寫一個很屌的動畫(1)---先實現一個簡易的自定義動畫框架

class MyView extends View { public void onDraw(Canvas canvas) { super.onDraw(canvas); invalidate(); } } 這樣一來,View每次繪製都是觸發下一次繪製,不過

Android(3)Android圖像處理

progress chang etc geo xtend static ogr arch 取出 1. 概念 色調/色相:物體傳遞的顏色 飽和度:顏色的純度,從0(灰)到100%(飽和)來進行描寫敘述 亮度/明度:顏色的相對明暗程度 2. 調整圖像小Demo 創建一個

AndroidJunit單元測試環境搭建以及簡單有用

rar theme 選擇 http 技術分享 才幹 ack package family 單元測試的目的 首先。Junit單元測試要實現的功能,就是用來測試寫好的方法是否可以正確的運行,一般多用於對業務方法的測試。 單元測試的環境配置 1.在Andro

Android 一鍵清理

一鍵清理流程圖 系統快取分析 Android 已安裝 app /data/data/packagename/cache 資料夾和 /sdcard/Android/data/packagename/cache 資料夾組成 原生設定(Settings

Android實現各種各樣的Tab切換效果

一、View  + ViewPager 使用ViewPager和View實現切換效果,效果如下: 主佈局介面: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

Android Android自定義系列:邊緣凹凸的卡劵效果

所謂前人栽樹,後人乘涼,在此感謝博主的貢獻。 原文:邊緣凹凸的卡劵效果 先上效果圖: 我實現的效果和原博主實現的效果是不一樣的,我是左右邊緣凹凸,而博主是上下邊緣凹凸。其實理解了原理,哪個邊緣實現這個效果都是可以的。 實現原理: 直接

Android判斷網路連線狀態並自動介面跳轉

用於判斷軟體開啟時的網路連線狀態,若無網路連線,提醒使用者跳轉到設定介面 /** * 設定在onStart()方法裡面,可以在介面每次獲得焦點的時候都進行檢測 */ @Override

Android CSDN新聞類客戶端-練手專案

無圖無真相: 宣告: 本專案資料全部來自CSDN官網,純練手之作,個人未從中獲取任何利益,資料的獲取與共享可能會侵犯到CSDN的權益,若被告知需停止共享與使用,本人會立即刪除整個專案。

Android 淘寶頭條:向上滾動廣告條ViewFlipper

所謂前人栽樹,後人乘涼,在此感謝博主的貢獻。 參考博文: 仿淘寶首頁的淘寶頭條View垂直滾動 歡迎關注我的微信公眾號 不只是原創技術文章,更多的是對生活的思考總結 我在博主的基礎上做了如下工作: 修復了滾動條第二條點選事件無法觸發這個

14.特徵提升特徵抽取----DictVectorizer

說明:DictVectorizer的處理物件是符號化(非數字化)的但是具有一定結構的特徵資料,如字典等,將符號轉成數字0/1表示。 #-*- coding:utf-8 -*- #學習目標:使用DictVectorizer對使用字典儲存的資料進行特徵抽取和

androidFirefly-RK系列(eg:RK3288 RK3368)App實現重啟、靜默安裝應用

本文的方法只是實現手段的一種,不可能完全適用所有裝置哦,試試才知道。 實現重啟 考慮到裝置需要遠端或自動重啟的場景(比如通過遠端推送的方式下發重啟指令、裝置定時重啟緩解資源緊張等),下面提供一種思路: public static void

SQL03.執行計劃旅1

聽到大牛們說執行計劃,總是很惶恐,是對知識的缺乏的惶恐,所以必須得學習執行計劃,以減少對這一塊知識的惶恐,下面是對執行計劃的第一講-理解執行計劃。 本系列【T-SQL】主要是針對T-SQL的總結。   一、為什麼需要執行計劃? (1)幫助分析 當我們想要去分析SQL語句存在很慢時,需要有一個

Android學習監聽EditText的變化

監聽EditText的變化 使用EditText的addTextChangedListener(TextWatcher watcher)方法對EditText實現監聽,TextWatcher是一個介面類,所以必須實現TextWatcher裡的抽象方法:  當Edi