自己動手寫DB資料庫框架(增)

weixin_34377065發表於2017-12-14

###1. 概述


在Android開發中我們經常要進行各種網路訪問,比如檢視各類新聞、檢視各種圖片。但有一種情形就是我們在規定的時間內每次重複傳送的網路請求其實返回的資料可能都是一樣的。比如一個電影類APP,每一次向伺服器申請某個電影的相關資訊,如封面、簡介、演員表等等,它們的資訊都是一樣的,這樣就有點浪費資源,最主要的是這些重複的請求產生了沒有必要的流量。流量、流量、流量!!!重要的事情說三遍!而流量是要付費的,而且超貴,公司那麼小,一個月要支付寬頻運營商鉅額的流量費用。所以領導們都想方設法地要節省頻寬,其實這在整個軟體開發中隨時可見,解決的一般套路都是把重複請求的資料快取在本地,並設定超時時間,在規定時間內,客戶端不再向遠端請求資料,而是直接從本地快取中取資料。這樣一來提高了響應速度,二來節省了網路頻寬(也就是節省了錢)。

所有分享大綱:2017Android進階之路與你同行

視訊講解地址:http://pan.baidu.com/s/1pLM1X3t     
###2. 快取的分類


2.1 服務端快取

常見的服務端有Ngix和Apache。服務端快取又分為代理伺服器快取和反向代理伺服器快取。常見的CDN就是伺服器快取。這個好理解,當瀏覽器重複訪問一張圖片地址時,CDN會判斷這個請求有沒有快取,如果有的話就直接返回這個快取的請求回覆,而不再需要讓請求到達真正的服務地址,這麼做的目的是減輕服務端的運算壓力。

2.2 客戶端快取

客戶端主要指瀏覽器(如IE、Chrome等),當然包括我們的前面所講的OkHttpClient.客戶端第一次請求網路時,伺服器返回回覆資訊。如果資料正常的話,客戶端快取在本地的快取目錄。當客戶端再次訪問同一個地址時,客戶端會檢測本地有沒有快取,如果有快取的話,資料是有沒有過期,如果沒有過期的話則直接運用快取內容,宣告一下這是一般套路。

###3. 第三方網路快取分析


伺服器的快取處理對於我們來說是可以不用關心的,只需要關心客戶端的請求快取處理,我們來看一下第三方的網路框架的處理方式,我就直接拿Okhttp為例吧,原理就是我們上面所講的顯而易見,你也可以自行看Okhttp的原始碼,這裡我直接上張流程圖:

###3. 特有的快取場景

上面所說的針對大部分app是沒有任何問題的,我們在開發中可以直接使用第三方的網路開源框架自帶的快取,但是內涵段子這個專案比較奇葩,因為內容更新比較頻繁我們要確保每次獲取的資料都是最新的,所以我們必須每次請求都要訪問最新資料,這對於我們來說第三方的網路快取框架然並卵,我們需要按需定製。      既然如此我們需要使用自己的快取邏輯,那麼大致的邏輯是我們每次請求之前都會去本地快取拿,如果本地有先拿過來顯示確保使用者體驗,然後去伺服器上獲取資料如果獲取的資料不一樣,那麼重新重新整理介面並將獲取到的資料加入快取,如果獲取的資料和快取裡面的一致那麼什麼都不做。

講到這裡我們必須瞭解一下資料庫了,因為我打算把資料快取到資料庫中,那我們上網找找第三方的開源資料庫吧。ORMLite,GreenDao,DB4O,Perst,Litepal 等等,這個時候問題又來了,我們第三方的資料庫一般都是快取在data/data/包名/database下面,這樣一來如果快取的資料比較多,多少有點對不住人家。所以我們打算把資料庫放到記憶體卡中,這樣的話你多一點就多一點,而且如果手抖解除安裝了內涵段子然後發現還是忘不了裡面的某個女主播你懂的,這個時候重新裝上app的時候我們的快取資料庫也都還在。你也可以看到自己的記憶體卡中有很多的資料庫,那些都是某些app特意寫到外部儲存卡的。

###3. 資料庫動員大會

各位同事各位精英,為了我們公司的明天,大家作為核心的程式設計師我希望你們必須對你們用的東西瞭如指掌,不然出了bug就非常的麻煩了。直接使用別人的是初級,看完了會模仿著寫一個是中級,自己按照需求來寫一個框架就是高階。大家一定要努力好好學習好好提升自己的能力,今天每人先領一臺Iphone7,只要國家公務員的工資漲了,我一定給你們漲工資。說得好聽,我要是老闆也這樣反正有錢就是爺。

有了這個接下來我就上一段程式碼:

/**
 * Created by Darren on 2017/2/28.
 * Email: 240336124@qq.com
 * Description: 工廠設計模式  IDaoSupport的工廠
 */

public class DaoSupportFactory {

    public static DaoSupportFactory mFactory;
    // 資料庫SQLiteDatabase
    private SQLiteDatabase mDatabase;

    public DaoSupportFactory() {
        File databaseDir = new File(Environment.getExternalStorageDirectory()
                + File.separator + "nhdz" + File.separator + "database");
        if (!databaseDir.exists()) {
            databaseDir.mkdirs();
        }
        // 資料庫放在外部儲存卡下面  nhdz/database/nhdz.db
        File dataBaseFile = new File(databaseDir, "nhdz.db");
        mDatabase = SQLiteDatabase.openOrCreateDatabase(dataBaseFile, null);
    }

    /**
     * 獲取DaoSupportFactory例項
     *
     * @return
     */
    public static DaoSupportFactory getFactory() {
        if (mFactory == null) {
            synchronized (DaoSupportFactory.class) {
                if (mFactory == null) {
                    mFactory = new DaoSupportFactory();
                }
            }
        }
        return mFactory;
    }

    /**
     * 獲取IDaoSupport
     */
    public <T> IDaoSupport<T> getDaoSupport(Class<T> clazz) {
        IDaoSupport<T> daoSupport = new DaoSupport<>();
        // 初始化資料
        daoSupport.init(mDatabase, clazz);
        return daoSupport;
    }
}
複製程式碼

再看看使用方式:

// 直接從工廠裡面獲取
IDaoSupport<Person> daoSupport = DaoSupportFactory.getFactory().getDaoSupport(Person.class);
// 插入資料物件
daoSupport.insert(new Person("Darren", 23));
複製程式碼

所有分享大綱:2017Android進階之路與你同行

視訊講解地址:http://pan.baidu.com/s/1pLM1X3t

相關文章