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

版權聲明:本文爲博主原創文章,轉載請註明出處。 https://blog.csdn.net/leaf_130/article/details/56505316

前言

當初學習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進入查看頁面即可

源碼

Github:GreenDaoDemo

總結

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

感謝

慕課網:nate的 Android框架-GreenDao

後話

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章