GreenDao基本功能的實(shí)現(xiàn)

greenDAO: Android ORM for your SQLite database

一.什么是GreenDao

Demo鏈接: https://github.com/liumaomao0209/GreenDaoDemo
GreenDAO是一個(gè)開(kāi)源的AndroidORM,使SQLite數(shù)據(jù)庫(kù)的開(kāi)發(fā)再次變得有趣。它在節(jié)省開(kāi)發(fā)時(shí)間的同時(shí)吵血,減輕了開(kāi)發(fā)人員對(duì)低級(jí)別數(shù)據(jù)庫(kù)需求的處理。SQLite是一個(gè)令人敬畏的嵌入式關(guān)系數(shù)據(jù)庫(kù)抛计。盡管如此,編寫(xiě)SQL和解析查詢結(jié)果仍然是非常繁瑣和耗時(shí)的任務(wù)照筑。GreenDAO通過(guò)將Java對(duì)象映射到數(shù)據(jù)庫(kù)表(稱為奧姆吹截,“對(duì)象/關(guān)系映射”)。通過(guò)這種方式凝危,您可以使用簡(jiǎn)單的面向?qū)ο驛PI來(lái)存儲(chǔ)波俄、更新、刪除和查詢Java對(duì)象蛾默。

二.GreenDao的特點(diǎn)

GreenDAO的特點(diǎn)一目了然

  • 性能強(qiáng)大 (可能是Android最快的ORM)
  • 易用 有強(qiáng)大的API
  • 極小內(nèi)存消耗
  • 體積小 GreenDAO小于100KB懦铺,所以對(duì)于應(yīng)用程序APK的大小影響很小。
  • 數(shù)據(jù)庫(kù)加密 支持SQLCiPHER支鸡,以確保用戶數(shù)據(jù)的安全

當(dāng)性能很重要時(shí)(數(shù)據(jù)訪問(wèn)頻繁)冬念,GreenDao是一個(gè)很快的解決方案,它能夠支持?jǐn)?shù)千條記錄的CRUD每秒牧挣,和OrmLite相比急前,GreenDAO要快幾乎4.5倍。(準(zhǔn)確數(shù)據(jù)請(qǐng)自行benchmark)瀑构。

greenDAO vs OrmLite

三.GreenDao的配置

1.導(dǎo)入插件
在project:build.gradle添加如下兩行(位置已注釋)


base.png
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
        mavenCentral() // 添加
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // 添加
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2.添加依賴和數(shù)據(jù)庫(kù)配置
(1)在app:build.gradle添加library和plugin(位置已經(jīng)注釋為// apply plugin // add library)
(2)數(shù)據(jù)庫(kù)配置信息,在android節(jié)點(diǎn)下


app.build.gradle
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.maomao.technology.greendaodemo"
        minSdkVersion 27
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    greendao {
        schemaVersion 1 //數(shù)據(jù)庫(kù)版本號(hào)裆针,數(shù)據(jù)庫(kù)升級(jí)使用
        daoPackage 'com.maomao.technology.greendaodemo.greendao' //代表GreenDao自動(dòng)生成的有關(guān)數(shù)據(jù)庫(kù)操作工具類所要存放的包名
        targetGenDir 'src/main/java' //路徑
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'org.greenrobot:greendao:3.2.2' // add library
}

四.GreenDao的使用

首先大概看一下整體構(gòu)建的樣子:

base:數(shù)據(jù)庫(kù)操作的基類
db:對(duì)用戶表專門自定義的操作類.
greendao:建表時(shí)自動(dòng)生成的類.

目錄

1.創(chuàng)建一個(gè)用戶類

Generated之下是build后自動(dòng)生成的.
項(xiàng)目的build目錄下或者自己設(shè)定的目錄下還可以看到自動(dòng)生成的三個(gè)類文件:
DaoMaster
DaoSession
UserDao

@Entity
public class UserBean {
    @Id(autoincrement = true)
    long id;
    @NotNull
    String name;
    String age;
    @Generated(hash = 47803367)
    public UserBean(long id, @NotNull String name, String age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Generated(hash = 1203313951)
    public UserBean() {
    }
    public long getId() {
        return this.id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return this.age;
    }
    public void setAge(String age) {
        this.age = age;
    }
}
創(chuàng)建好后.png

注解說(shuō)明:

@Id 注解選擇 long / Long 屬性作為實(shí)體ID。在數(shù)據(jù)庫(kù)術(shù)語(yǔ)中,它是主鍵据块。參數(shù)自動(dòng)增量码邻,是使ID值不斷增加(不會(huì)選用舊值)的標(biāo)志折剃。
@Property 讓你定義一個(gè)非默認(rèn)的列名另假,其屬性映射到。如果不存在怕犁,greenDAO將在SQL雜交方式使用字段名(大寫(xiě)边篮,下劃線,而不是駱駝情況下奏甫,例如 customName將成為 CUSTOM_NAME)戈轿。注意:您目前只能使用內(nèi)聯(lián)常量來(lái)指定列名。
@Transient 表明這個(gè)字段不會(huì)被寫(xiě)入數(shù)據(jù)庫(kù)阵子,只是作為一個(gè)普通的java類字段思杯,用來(lái)臨時(shí)存儲(chǔ)數(shù)據(jù)的,不會(huì)被持久化
@Entity 定義實(shí)體
@nameInDb 在數(shù)據(jù)庫(kù)中的名字挠进,如不寫(xiě)則為實(shí)體中類名
@indexes 索引
@schema 指定架構(gòu)名稱為實(shí)體
@active 無(wú)論是更新生成都刷新
@NotNull 不為null
@Unique 唯一約束
@ToMany 一對(duì)多
@OrderBy 排序
@ToOne 一對(duì)一
@Transient 不存儲(chǔ)在數(shù)據(jù)庫(kù)中
@generated 由greendao產(chǎn)生的構(gòu)造函數(shù)或方法

2.構(gòu)建兩個(gè)管理DB的基類

1.BaseDBManager 所有的數(shù)據(jù)庫(kù)操作類都繼承自此
public class BaseDBManager<T, K> {

    private AbstractDao<T, K> mDao;

    public BaseDBManager(AbstractDao dao) {
        this.mDao = dao;
    }

    public void insert(T item) {
        mDao.insert(item);
    }

    public void insert(T... items) {
        mDao.insertInTx(items);
    }

    public void insert(List<T> items) {
        mDao.insertInTx(items);
    }

    public void insertOrUpdate(T item) {
        mDao.insertOrReplace(item);
    }

    public void insertOrUpdate(T... items) {
        mDao.insertOrReplaceInTx(items);
    }

    public void insertOrUpdate(List<T> items) {
        mDao.insertOrReplaceInTx(items);
    }

    public void deleteByKey(K key) {
        mDao.deleteByKey(key);
    }

    public void delete(T item) {
        mDao.delete(item);
    }

    public void delete(T... items) {
        mDao.deleteInTx(items);
    }

    public void delete(List<T> items) {
        mDao.deleteInTx(items);
    }

    public void deleteAll() {
        mDao.deleteAll();
    }

    public void update(T item) {
        mDao.update(item);
    }

    public void update(T... items) {
        mDao.updateInTx(items);
    }

    public void update(List<T> items) {
        mDao.updateInTx(items);
    }

    /**
     * 根據(jù)主鍵查詢數(shù)據(jù)  如果沒(méi)有涉及主鍵 則會(huì)報(bào)錯(cuò)
     *
     * @param key 主鍵
     * @return T
     */
    public T query(K key) {
        return mDao.load(key);
    }

    public List<T> queryAll() {
        return mDao.loadAll();
    }

    public List<T> query(String where, String... params) {
        return mDao.queryRaw(where, params);
    }

    public QueryBuilder<T> getQueryBuilder() {
        return mDao.queryBuilder();
    }

    public long count() {
        return mDao.count();
    }

    public void refresh(T item) {
        mDao.refresh(item);
    }

    public void detach(T item) {
        mDao.detach(item);
    }

}


2.庫(kù)名類
public interface DBConfig {
    String DB_NAME = "User.db";
}
3.編寫(xiě)USER庫(kù)的操作類
操作類

三個(gè)類分別為

UserDBFactory 用戶數(shù)據(jù)庫(kù)工廠類 通過(guò)這個(gè)類統(tǒng)一下面兩個(gè)類的功能,使用時(shí)調(diào)用這個(gè)類.
UserDBManage 數(shù)據(jù)庫(kù)管理類,用于創(chuàng)建 刪除 關(guān)閉數(shù)據(jù)庫(kù) 獲取session
UserInfoManage 用戶信息管理類 對(duì)用戶列表的增刪改查放這里

public class UserDBFactory {
    private static UserDBFactory mInstance = null;
    private UserInfoManage userInfoManage;

    public static UserDBFactory getInstance() {
        if (mInstance == null) {
            synchronized (UserDBFactory.class) {
                if (mInstance == null) {
                    mInstance = new UserDBFactory();
                }
            }
        }
        return mInstance;
    }

    public UserInfoManage getUserInfoManage() {
        if (userInfoManage == null) {
            userInfoManage = new UserInfoManage(UserDBManage.getInstance(MyApplication.getApplication()).getDaoSession().getUserBeanDao());
        }
        return userInfoManage;
    }
}
public class UserDBManage {
    private static UserDBManage dbManage;
    private Context context;
    public static UserDBManage getInstance(Context context) {
        if (dbManage == null) {
            synchronized (UserDBManage.class) {
                if (dbManage == null) {
                    dbManage = new UserDBManage(context);
                }
            }
        }
        return dbManage;
    }
    private UserDBManage(Context context) {
        this.context = context;
    }
    private DaoMaster.DevOpenHelper mHelper;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    /**
     * 獲取DaoSession * * @return
     */
    public synchronized DaoSession getDaoSession() {
        if (null == mDaoSession) {
            mDaoSession = getDaoMaster().newSession();
        }
        return mDaoSession;
    }
    /**
     * 關(guān)閉數(shù)據(jù)庫(kù)
     */
    public synchronized void closeDataBase() {
        closeHelper();
        closeDaoSession();
    }
    /**
     * 判斷數(shù)據(jù)庫(kù)是否存在色乾,如果不存在則創(chuàng)建 * * @return
     */
    private DaoMaster getDaoMaster() {
        if (null == mDaoMaster) {
            mHelper = new DaoMaster.DevOpenHelper(context, DBConfig.DB_NAME, null);
            mDaoMaster = new DaoMaster(mHelper.getWritableDb());
        }
        return mDaoMaster;
    }
    private void closeDaoSession() {
        if (null != mDaoSession) {
            mDaoSession.clear();
            mDaoSession = null;
        }
    }
    private void closeHelper() {
        if (mHelper != null) {
            mHelper.close();
            mHelper = null;
        }
    }
}

/**
 * Describe:DB操作類
 */

public class UserInfoManage extends BaseDBManager<UserBean, String> {
    public UserInfoManage(AbstractDao dao) {
        super(dao);
    }
}

五.增刪改查功能實(shí)現(xiàn)

1.布局和代碼目錄展示


增刪改查功能.png

布局和條目布局代碼我就不寫(xiě)在這里了,各位自行定義.列表使用的是recyclerview;
2.自定義適配器

package com.maomao.technology.greendaodemo;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 創(chuàng)建日期:2019/4/19 on 15:45
 * 作   者:劉喵喵
 * 郵   箱:915850672@qq.com
 * 描   述:
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
public class MyAdapter extends RecyclerView.Adapter {

    private final int mLayoutId;
    private final List<UserBean> mData;
    private final Context mContext;
    private final LayoutInflater inflater;

    public MyAdapter(List<UserBean> mData, int mLayoutId, Context mContext) {
        this.mData = mData;
        this.mLayoutId = mLayoutId;
        this.mContext = mContext;
        inflater = LayoutInflater.from(mContext);
    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View view = inflater.inflate(mLayoutId, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        MyViewHolder holder = (MyViewHolder) viewHolder;
        holder.key.setText(mData.get(i).getId()+"");
        holder.name.setText(mData.get(i).getName()+"");
        holder.age.setText(mData.get(i).getAge()+"");

    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        private final TextView age;
        private final TextView name;
        private final TextView key;
        public MyViewHolder(View v) {
            super(v);
            name = v.findViewById(R.id.name);
            age = v.findViewById(R.id.age);
            key = v.findViewById(R.id.key);

        }


    }
}

3.主要功能邏輯

public class MainActivity extends Activity implements View.OnClickListener {

    private UserInfoManage userInfoManage;
    private List<UserBean> userBeanList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MyAdapter myAdapter;
    private EditText keyEdit;
    private EditText valueEdit;
    private TextView add;
    private TextView delete;
    private TextView search;
    private TextView show;
    private TextView update;
    private UserBean userBean;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initview();
        initdata();
        UserDBFactory userDBFactory = new UserDBFactory();
        userInfoManage = userDBFactory.getUserInfoManage();
    }

    private void initdata() {
        myAdapter = new MyAdapter(userBeanList, R.layout.user_item, this);
        recyclerView.setAdapter(myAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    private void initview() {
        add = findViewById(R.id.add_btn);
        delete = findViewById(R.id.delete_btn);
        search = findViewById(R.id.search_btn);
        show = findViewById(R.id.show_btn);
        recyclerView = findViewById(R.id.recyclerView);
        keyEdit = findViewById(R.id.key_edt);
        valueEdit = findViewById(R.id.value_edt);
        update = findViewById(R.id.update_btn);
        add.setOnClickListener(this);
        delete.setOnClickListener(this);
        search.setOnClickListener(this);
        show.setOnClickListener(this);
        update.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Random mRandom = new Random();
        String key = keyEdit.getText().toString();
        switch (v.getId()) {
            case R.id.add_btn:
                //添加數(shù)據(jù)
                for (int i = 0; i < 10; i++) {
                    userBean = new UserBean();
                    userBean.setId(i + "");
                    int age = mRandom.nextInt(10) + 10;
                    userBean.setAge(age + "");
                    userBean.setName("瑤瑤" + i);
                    userInfoManage.insertOrUpdate(userBean);//插入或替換
                }
                myAdapter.notifyDataSetChanged();
                //顯示
                show.performClick();
                break;
            case R.id.delete_btn:
                //刪除key為..的數(shù)據(jù)
                userInfoManage.deleteByKey(key);
                show.performClick();
                break;
            case R.id.show_btn:
                userBeanList.clear();
                //查詢所有并顯示
                List<UserBean> userBeans = userInfoManage.queryAll();
                userBeanList.addAll(userBeans);
                myAdapter.notifyDataSetChanged();
                break;
            case R.id.search_btn:
                //搜索key為..的數(shù)據(jù)
                UserBean query = userInfoManage.query(key);
                if (query != null) {
                    userBeanList.clear();
                    userBeanList.add(query);
                    myAdapter.notifyDataSetChanged();
                } else {
                    Toast.makeText(this, "沒(méi)有該條數(shù)據(jù)", Toast.LENGTH_SHORT).show();
                }
        break;
        case R.id.update_btn:
        //使用主鍵查詢需要修改的數(shù)據(jù)
        UserBean userBean = userInfoManage.query(key);
        if (userBean != null) {
            userBean.setName(valueEdit.getText().toString());
            //修改
            userInfoManage.update(userBean);
            show.performClick();
        } else {
            Toast.makeText(this, "沒(méi)有該條數(shù)據(jù)", Toast.LENGTH_SHORT).show();
        }
        break;
    }
}
}

4.全局context

public class MyApplication extends Application {

    //全局唯一的context
    private static MyApplication application;
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        application = this;
    }
    public static Context getContext() {
        return application;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }
    /**
     * 獲取全局唯一上下文
     *
     * @return BaseApplication
     */
    public static MyApplication getApplication() {
        return application;
    }
}

最后再放一次我的Demo鏈接

https://github.com/liumaomao0209/GreenDaoDemo
官方網(wǎng)站:http://greendao-orm.com/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市领突,隨后出現(xiàn)的幾起案子暖璧,更是在濱河造成了極大的恐慌,老刑警劉巖君旦,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澎办,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡金砍,警方通過(guò)查閱死者的電腦和手機(jī)局蚀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恕稠,“玉大人至会,你說(shuō)我怎么就攤上這事∑准螅” “怎么了奉件?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)昆著。 經(jīng)常有香客問(wèn)我县貌,道長(zhǎng),這世上最難降的妖魔是什么凑懂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任煤痕,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摆碉。我一直安慰自己塘匣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布巷帝。 她就那樣靜靜地躺著忌卤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪楞泼。 梳的紋絲不亂的頭發(fā)上驰徊,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音堕阔,去河邊找鬼棍厂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛超陆,可吹牛的內(nèi)容都是我干的牺弹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼时呀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼张漂!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起退唠,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鹃锈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后瞧预,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體屎债,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年垢油,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盆驹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滩愁,死狀恐怖躯喇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情硝枉,我是刑警寧澤廉丽,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站妻味,受9級(jí)特大地震影響正压,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜责球,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一焦履、第九天 我趴在偏房一處隱蔽的房頂上張望拓劝。 院中可真熱鬧,春花似錦嘉裤、人聲如沸郑临。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厢洞。三九已至,卻和暖如春侨把,著一層夾襖步出監(jiān)牢的瞬間犀变,已是汗流浹背妹孙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工秋柄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蠢正。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓骇笔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嚣崭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笨触,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354