1. 程式人生 > >greendao 3.0整合和使用封裝

greendao 3.0整合和使用封裝

現在專案中要用到資料庫,最終選擇使用了greendao ,至於原因,肯定是效能原因了。本文將著重介紹資料庫的非同步操作,因為網上很多都是配置整合+簡單的使用,並且都還是同步的(重要的是 都是一樣的文章!!!)。我想說,如果是百萬級的資料就GG了。
一般來說,我們需要資料時,先訪問資料庫看是否有資料,如果有,就從資料庫取,如果沒有,就訪問網路,成功後,將開啟執行緒將資料插入資料庫中,同事更新UI 如下圖所示:
這裡寫圖片描述
1:整合配置


apply plugin: 'org.greenrobot.greendao'

greendao {
    schemaVersion 1
    daoPackage 'com.app.test.textgreendao.db'
//這個填寫你自己建立的路徑 targetGenDir 'src/main/java' }
buildscript { repositories { mavenCentral() } dependencies { classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0' } } dependencies { compile'org.greenrobot:greendao:3.0.1' compile'org.greenrobot:greendao-generator:3.0.0'
}

2:接下來就是建立實體類了:

/**
 * Created by ${liumengqiang} on 2017/7/10.
 */
@Entity
public class User {
    @Id
    private long memberId;
    @Property
    private String name;
    @Property
    private String age;


}

然後點選 Build —— make build 就是那個綠色小錘子按鈕,就會自動幫你生成相應的方法;
至於@Id,@Property 這一類的標記 大家可以上網搜一下 這個不再贅述。

3:然後就是自己封裝GreenDao了,首先網上很多都是同步資料 在這裡 我用的是非同步處理的也就是使用的是AsyncSession類,這個是GreenDao內部封裝好的 再次我們可以在封裝一下,專門用於非同步操作資料庫的成功和失敗;
首先 我定義了返回操作資料庫結果的回撥介面

package com.app.test.textgreendao.user;

import java.util.List;

/**
 * Created by ${liumengqiang} on 2017/7/12.
 */

public interface UserInterface {

    /**
     * type true 成功。 false 失敗
     * @param <T>
     */

    interface OnIsertInterface<T>{//單個插入成功
        void onIsertInterface(boolean type);
    }

    interface OnQuerySingleInterface<T>{//單個查詢成功
        void onQuerySingleInterface(T entry);
    }

    interface OnDeleteInterface<T>{//單個刪除成功
        void onDeleteInterface(boolean type);
    }

    interface OnUpdateInterface<T>{//單個修改成功
        void onUpdateInterface(boolean type);
    }

    interface OnQueryAllInterface<T>{//批量查詢資料回撥
        void onQueryAllBatchInterface(List<T> list);
    }

}

然後 我們宣告這些介面:

package com.app.test.textgreendao.db;

import com.app.test.textgreendao.user.UserInterface;

/**
 * Created by ${liumengqiang} on 2017/7/12.
 */

public class DaoInterface<T>  {

    protected UserInterface.OnQueryAllInterface<T> onQueryAllInterface;
    protected UserInterface.OnUpdateInterface<T> onUpdateInterface;
    protected UserInterface.OnIsertInterface<T> onIsertInterface;
    protected UserInterface.OnQuerySingleInterface<T> onQuerySingleInterface;
    protected UserInterface.OnDeleteInterface<T> onDeleteInterface;

    public UserInterface.OnQueryAllInterface<T> getOnQueryAllInterface() {
        return onQueryAllInterface;
    }

    public void setOnQueryAllInterface(UserInterface.OnQueryAllInterface<T> onQueryAllInterface) {
        this.onQueryAllInterface = onQueryAllInterface;
    }

    public UserInterface.OnUpdateInterface<T> getOnUpdateInterface() {
        return onUpdateInterface;
    }

    public void setOnUpdateInterface(UserInterface.OnUpdateInterface<T> onUpdateInterface) {
        this.onUpdateInterface = onUpdateInterface;
    }

    public UserInterface.OnIsertInterface<T> getOnIsertInterface() {
        return onIsertInterface;
    }

    public void setOnIsertInterface(UserInterface.OnIsertInterface<T> onIsertInterface) {
        this.onIsertInterface = onIsertInterface;
    }

    public UserInterface.OnQuerySingleInterface<T> getOnQuerySingleInterface() {
        return onQuerySingleInterface;
    }

    public void setOnQuerySingleInterface(UserInterface.OnQuerySingleInterface<T> onQuerySingleInterface) {
        this.onQuerySingleInterface = onQuerySingleInterface;
    }

    public UserInterface.OnDeleteInterface<T> getOnDeleteInterface() {
        return onDeleteInterface;
    }

    public void setOnDeleteInterface(UserInterface.OnDeleteInterface<T> onDeleteInterface) {
        this.onDeleteInterface = onDeleteInterface;
    }
}

首先封裝一下資料庫 DaoManager ,這個網上很多 ,直接看下程式碼吧

package com.app.test.textgreendao.db;

import android.content.Context;

/**
 * Created by ${liumengqiang} on 2017/7/10.
 */

public class DaoManager {
    private static DaoManager daoManager;
    private DaoMaster daoMaster;
    private DaoSession daoSession = null;
    private DaoMaster.DevOpenHelper devOpenHelper;

    private DaoManager(){};
    public static DaoManager getInstance(){
        if(daoManager == null){
            daoManager = new DaoManager();
        }
        return daoManager;
    }
    public DaoMaster getDaoManager(Context context, String DB_NAME){
        if(daoMaster == null){
            devOpenHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
            daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        }
        return daoMaster;
    }
    public DaoSession getDaoSession(){
        if(daoSession == null){
            daoSession = daoMaster.newSession();
        }
        return  daoSession;
    }

    /**
     * 關閉DaoSession
     */
    private void closeDaoSession(){
        if(daoSession != null){
            daoSession.clear();
            daoSession = null;
        }
    }
    /**
     * 關閉Helper
     */
    private void closeHelper(){
        if(devOpenHelper != null){
            devOpenHelper.close();
            devOpenHelper = null;
        }
    }
    /**
     * 關閉所有的操作
     */
    public void closeConnection(){
        closeDaoSession();
        closeHelper();
    }
}

然後就是我們核心部分了,就是處理建立一個類DaoUtils繼承UserInterface類,
daoSession.startAsyncSession()返回一個AsyncSession物件,通過該物件我們可以通過setListenerMainThread 方法監聽操作資料庫的結果, 然後在執行增刪改查,比如:asyncSession.queryUnique(query);

package com.app.test.textgreendao.db;

import android.content.Context;
import org.greenrobot.greendao.async.AsyncOperation;
import org.greenrobot.greendao.async.AsyncOperationListener;
import org.greenrobot.greendao.async.AsyncSession;
import org.greenrobot.greendao.query.DeleteQuery;
import org.greenrobot.greendao.query.Query;
import org.greenrobot.greendao.query.WhereCondition;
import java.util.List;

/**
 * Created by ${liumengqiang} on 2017/7/11.
 */

public class DaoUtils<T> extends DaoInterface{
    private DaoManager daoManager;
    public DaoSession daoSession;

    public DaoUtils(Context context, String dao_name){
        daoManager = DaoManager.getInstance();
        daoManager.getDaoManager(context, dao_name);
        daoSession = daoManager.getDaoSession();
    }

    /**
     * 條件查詢資料
     * @param cls
     * @return
     */
    public <T>void query(Class cls, WhereCondition whereCondition){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onQuerySingleInterface  != null){
                    onQuerySingleInterface.onQuerySingleInterface(operation.getResult());
                }else if(onQuerySingleInterface  != null){
                    onQuerySingleInterface.onQuerySingleInterface(null);
                }
            }
        });
        Query query = daoSession.queryBuilder(cls).where(whereCondition).build();
        asyncSession.queryUnique(query);
    }
    public T query(Class cls, String whereString, String[] params){
        return (T) daoSession.getDao(cls).queryRaw(whereString, params);
    }

    /**
     * 批量查詢
     * @param object
     * @return
     */
    public void queryAll(Class object, Query<T> query){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                List<T> result = (List<T>)operation.getResult();
                onQueryAllInterface.onQueryAllBatchInterface(result);
            }
        });
        if(query == null){
            asyncSession.loadAll(object);
        }else{
            asyncSession.queryList(query);
        }
//        return objects;
    }
    /**
     * 刪除
     */
    public  void deleteSingle(T entry){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onDeleteInterface  != null){
                    onDeleteInterface.onDeleteInterface(true);
                }else if(onDeleteInterface  != null){
                    onDeleteInterface.onDeleteInterface(false);
                }
            }
        });
        asyncSession.delete(entry);
    }
    /**
     * 批量刪除
     */
    public void deleteBatch(Class cls,final List<T> list){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onDeleteInterface  != null){
                    onDeleteInterface.onDeleteInterface(true);
                }else if(onDeleteInterface  != null){
                    onDeleteInterface.onDeleteInterface(false);
                }
            }
        });
        asyncSession.deleteInTx(cls, list);
    }
    /**
     * 根據Id單個刪除
     */
    public void deleteByIdSingle(Class cls,long longParams){//此處longParams數值型別必須為主鍵id的型別
        daoSession.getDao(cls).deleteByKey(longParams);
    }
    /**
     * 根據Id批量刪除
     */
    public void deleteByIdBatch(Class cls, List<Long> longList){//同上
        daoSession.getDao(cls).deleteByKeyInTx(longList);
    }
    /**
     * 刪除所有資料
     */
    public void deleteAll(Class cls){
        final AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onDeleteInterface != null){
                    onDeleteInterface.onDeleteInterface(true);
                }else if(onDeleteInterface != null){
                    onDeleteInterface.onDeleteInterface(false);
                }
            }
        });
        asyncSession.deleteAll(cls);
    }
    /**
     * 插入一條資料
     */
    public void insertSingle(final T  entity){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onIsertInterface != null){
                    onIsertInterface.onIsertInterface(true);
                }else if(onIsertInterface != null){
                    onIsertInterface.onIsertInterface(false);
                }
            }
        });
        asyncSession.runInTx(new Runnable() {
            @Override
            public void run() {
                daoSession.insert(entity);
            }
        });
    }
    /**
     * 批量插入
     */
    public <T>void insertBatch(final Class cls,final List<T> userList){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onIsertInterface != null){
                    onIsertInterface.onIsertInterface(true);
                }else if(onIsertInterface != null){
                    onIsertInterface.onIsertInterface(false);
                }
            }
        });
        asyncSession.runInTx(new Runnable() {
            @Override
            public void run() {
                for (T object : userList) {
                    daoSession.insertOrReplace(object);
                }
            }
        });
    }
    /**
     * 更新一個數據
     */
    public <T>void updateSingle(Class cls,T entry){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onUpdateInterface != null){
                    onUpdateInterface.onUpdateInterface(true);
                }else if(onUpdateInterface != null){
                    onUpdateInterface.onUpdateInterface(false);
                }
            }
        });
        asyncSession.update(entry);
    }
    /**
     * 批量更新資料
     */
    public <T>void  updateBatch(final Class cls, final List<T> tList){
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully() && onUpdateInterface != null){
                    onUpdateInterface.onUpdateInterface(true);
                }else if(onUpdateInterface != null){
                    onUpdateInterface.onUpdateInterface(false);
                }
            }
        });
        asyncSession.updateInTx(cls, tList);
    }

}

上面的核心類,有幾個我搞的不太懂 就是那個根據id刪除的,如何整成非同步的;再有就是刪除非同步裡面的迭代器我不太會用。小夥伴們知道的話 可以交流溝通一下。
由於greendao是通過類的不同來識別的,所以當我們操作不同表時,都建立一個相應的操作資料庫Utils 繼承自DaoUtils。比如我建立的User類 就可以建立一個相應的操作資料庫utils類如下:

package com.app.test.textgreendao.user;

import android.content.Context;

import com.app.test.textgreendao.db.DaoUtils;
import com.app.test.textgreendao.db.UserDao;

import org.greenrobot.greendao.async.AsyncOperation;
import org.greenrobot.greendao.async.AsyncOperationListener;
import org.greenrobot.greendao.async.AsyncSession;
import org.greenrobot.greendao.query.Query;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by ${liumengqiang} on 2017/7/11.
 */

public class UserDaoUtils extends DaoUtils<User>{

    public UserDaoUtils(Context context, String dao_name) {
        super(context, dao_name);
    }

    /**
     * 單個插入
     * @param user
     */
    public void insertUser(User user){
        insertSingle(user);
    }
    /**
     * 批量插入
     */
    public void insertBatchUser(List<User> list){
        insertBatch(User.class,list);
    }
    /**
     * 條件查詢
     */
    public void queryWhereUser(long memberId){
        query(User.class, UserDao.Properties.MemberId.eq(memberId));
    }
    /**
     * 查詢全部
     */
    public void queryAllUser(){
        queryAll(User.class, null);
//        return users;
    }
    /**
     * 條件刪除
     */
    public void deleteSingleUser(long memberId){
        User user = new User();
        user.setMemberId(memberId);
        deleteSingle(user);
    }
    /**
     * 批量刪除
     */
    public void deleteBatchUser(List<Integer> integerList){
        List<User> userList = new ArrayList<>();
        for(int i = 0;i < integerList.size(); i++){
            User user = new User();
            user.setMemberId(integerList.get(i));
            userList.add(user);
        }
        deleteBatch(User.class, userList);
    }
    /**
     * 單個更新
     */
    public void updateSingleUser(User user){
        updateSingle(User.class, user);
    }
    /**
     * 批量更新
     */
    public void updateBatchUser(List<User> list){
        updateBatch(User.class,list);
    }
    /**
     * 根據Id 單個刪除
     */
    public void deleteByIdSingleUser(long memberId){
        deleteByIdSingle(User.class, memberId);
    }
    /**
     * 根據Id批量刪除
     */
    public void deleteByIdBatchUser(List<Long> longList){
        deleteByIdBatch(User.class, longList);
    }
    /**
     * 刪除所有
     */
    public void deleteAll(){
        deleteAll(User.class);
    }
    /**
     * 條件批量刪除
     */
    public void deleteWhereBatch(String ageString){
        Query<User> build = daoSession.queryBuilder(User.class).where(UserDao.Properties.Age.eq(ageString)).build();
        AsyncSession asyncSession = daoSession.startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if(operation.isCompletedSucessfully()){
                    deleteBatch(User.class, (List<User> )operation.getResult());
                }
            }
        });
        asyncSession.queryList(build);
    }
}

當我們需要在view層操作資料庫的結果時,比如插入結果,我們可以通過:

userDaoUtils = new UserDaoUtils(getApplicationContext(), "123456789");

userDaoUtils.setOnIsertInterface(new UserInterface.OnIsertInterface() {
            @Override
            public void onIsertInterface(boolean type) {
                if(type){
                    /**
                     * 插入一條資料成功 
                     */
                }
            }
});

這樣是不是方便多了。
其次有幾個坑大家共勉:

1: 刪除資料時, greendao是根據Id進行刪除的。
2:新增或刪除欄位時,需要刪除重新安裝apk
3: 建立的實體類 ,不要建立成內部類。