GreenDao的实用封装

Posted 金杰米

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GreenDao的实用封装相关的知识,希望对你有一定的参考价值。

       前面简单介绍了下GreenDao的使用,从前面的介绍看来是不是觉得有点 so easy。对就是这么简单。曾经有位大神说作为一位合格的程序员就要在学习别人的东西时,有点自己的想法。为了表示我是位比较合格的程序员,今天和大家介绍下GreenDao的比较实用的封装。如果您还没来得及学习greenDao的实用详解,请前往GreenDao的使用详解学习。长话短说我们正式开始介绍。首先我们新建两个表,分别是Customer和Student表。其生成的文件如下所示。

 (一)封装下DaoMaster,DaoSession,DevOpenHelper对象


其具体代码如DaoManager.java所示。

package com.jamy.DaoUtils;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import com.jamy.dao.DaoMaster;
import com.jamy.dao.DaoSession;

import de.greenrobot.dao.query.QueryBuilder;

/**
 * Created by jamy on 2016/6/16.
 * 进行数据库的管理
 * 1.创建数据库
 * 2.创建数据库表
 * 3.对数据库进行增删查改
 * 4.对数据库进行升级
 */
public class DaoManager {
    private static  final String   TAG = DaoManager.class.getSimpleName();
    private static  final String  DB_NAME="jamy.db";//数据库名称
    private volatile  static DaoManager mDaoManager;//多线程访问
    private  static DaoMaster.DevOpenHelper mHelper;
    private static  DaoMaster mDaoMaster;
    private static DaoSession mDaoSession;
    private static SQLiteDatabase db;
    private Context context;

    /**
     * 使用单例模式获得操作数据库的对象
     * @return
     */
    public  static DaoManager getInstance(){
        DaoManager instance = null;
        if (mDaoManager==null){
            synchronized (DaoManager.class){
                if (instance==null){
                    instance = new DaoManager();
                    mDaoManager = instance;
                }
            }
        }
        return mDaoManager;
    }

    /**
     * 初始化Context对象
     * @param context
     */
    public void init(Context context){
        this.context = context;
    }

    /**
     * 判断数据库是否存在,如果不存在则创建
     * @return
     */
    public DaoMaster getDaoMaster(){
        if (null == mDaoMaster){
            mHelper =  new DaoMaster.DevOpenHelper(context,DB_NAME,null);
            mDaoMaster = new DaoMaster(mHelper.getWritableDatabase());
        }
        return mDaoMaster;
    }

    /**
     * 完成对数据库的增删查找
     * @return
     */
    public DaoSession getDaoSession(){
        if (null == mDaoSession){
            if (null == mDaoMaster){
                mDaoMaster = getDaoMaster();
            }
            mDaoSession = mDaoMaster.newSession();
        }
        return mDaoSession;
    }

    /**
     * 设置debug模式开启或关闭,默认关闭
     * @param flag
     */
    public void setDebug(boolean flag){
        QueryBuilder.LOG_SQL = flag;
        QueryBuilder.LOG_VALUES = flag;
    }

    /**
     * 关闭数据库
     */
    public void closeDataBase(){
        closeHelper();
        closeDaoSession();
    }

    public void closeDaoSession(){
        if (null != mDaoSession){
            mDaoSession.clear();
            mDaoSession = null;
        }
    }

    public  void  closeHelper(){
        if (mHelper!=null){
            mHelper.close();
            mHelper = null;
        }
    }

}
        DaoManager主要是通过单列模式获取对应的对象,以及对所有的对象进行初始化。


(二)封装一可操作不同数据表的公共基类

其集体代码BaseDao.java所示。

package com.jamy.DaoUtils;

import android.content.Context;
import android.util.Log;
import com.jamy.dao.CustomerDao;
import com.jamy.dao.DaoSession;
import java.util.List;
import de.greenrobot.dao.query.QueryBuilder;


/**
 * 将所有创建的表格相同的部分封装到这个BaseDao中
 * Created by jamy on 16/6/16.
 */
public class BaseDao<T>{
    public static final String TAG = BaseDao.class.getSimpleName();
    public static final boolean DUBUG = true;
    public DaoManager manager;
    public DaoSession daoSession;

    public BaseDao(Context context) {
        manager = DaoManager.getInstance();
        manager.init(context);
        daoSession = manager.getDaoSession();
        manager.setDebug(DUBUG);
    }

    /**************************数据库插入操作***********************/
    /**
     * 插入单个对象
     * @param object
     * @return
     */
    public boolean insertObject(T object){
        boolean flag = false;
        try {
            flag = manager.getDaoSession().insert(object) != -1 ? true:false;
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return flag;
    }

    /**
     * 插入多个对象,并开启新的线程
     * @param objects
     * @return
     */
    public boolean insertMultObject(final List<T> objects){
        boolean flag = false;
        if (null == objects || objects.isEmpty()){
            return false;
        }
        try {
            manager.getDaoSession().runInTx(new Runnable() {
                @Override
                public void run() {
                    for (T object : objects) {
                        manager.getDaoSession().insertOrReplace(object);
                    }
                }
            });
            flag = true;
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            flag = false;
        }finally {
//            manager.CloseDataBase();
        }
        return flag;
    }

    /**************************数据库更新操作***********************/
    /**
     * 以对象形式进行数据修改
     * 其中必须要知道对象的主键ID
     * @param object
     * @return
     */
    public void  updateObject(T object){

        if (null == object){
            return ;
        }
        try {
            manager.getDaoSession().update(object);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    /**
     * 批量更新数据
     * @param objects
     * @return
     */
    public void updateMultObject(final List<T> objects, Class clss){
        if (null == objects || objects.isEmpty()){
            return;
        }
        try {

            daoSession.getDao(clss).updateInTx(new Runnable() {
                @Override
                public void run() {
                    for(T object:objects){
                        daoSession.update(object);
                    }
                }
            });
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }


    /**************************数据库删除操作***********************/
    /**
     * 删除某个数据库表
     * @param clss
     * @return
     */
    public boolean deleteAll(Class clss){
        boolean flag = false;
        try {
            manager.getDaoSession().deleteAll(clss);
            flag = true;
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            flag = false;
        }
        return flag;
    }

    /**
     * 删除某个对象
     * @param object
     * @return
     */
    public void deleteObject(T object){
        try {
            daoSession.delete(object);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    /**
     * 异步批量删除数据
     * @param objects
     * @return
     */
    public boolean deleteMultObject(final List<T> objects, Class clss){
        boolean flag = false;
        if (null == objects || objects.isEmpty()){
            return false;
        }
        try {

            daoSession.getDao(clss).deleteInTx(new Runnable() {
                @Override
                public void run() {
                    for(T object:objects){
                        daoSession.delete(object);
                    }
                }
            });
            flag = true;
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            flag = false;
        }
        return flag;
    }

    /**************************数据库查询操作***********************/

    /**
     * 获得某个表名
     * @return
     */
    public String getTablename(Class object){
        return daoSession.getDao(object).getTablename();
    }

    /**
     * 查询某个ID的对象是否存在
     * @param
     * @return
     */
    public boolean isExitObject(long id,Class object){
        QueryBuilder<T> qb = (QueryBuilder<T>) daoSession.getDao(object).queryBuilder();
        qb.where(CustomerDao.Properties.Id.eq(id));
        long length = qb.buildCount().count();
        return length>0 ? true:false;
    }

    /**
     * 根据主键ID来查询
     * @param id
     * @return
     */
    public T QueryById(long id,Class object){
        return (T) daoSession.getDao(object).loadByRowId(id);
    }

    /**
     * 查询某条件下的对象
     * @param object
     * @return
     */
    public List<T> QueryObject(Class object,String where,String...params){
        Object obj = null;
        List<T> objects = null;
        try {
            obj = daoSession.getDao(object);
            if (null == obj){
                return null;
            }
            objects = daoSession.getDao(object).queryRaw(where,params);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }

        return objects;
    }
    /**
     * 查询所有对象
     * @param object
     * @return
     */
    public List<T> QueryAll(Class object){
        List<T> objects = null;
        try {
            objects = (List<T>) daoSession.getDao(object).loadAll();
        } catch (Exception e) {
            Log.e(TAG,e.toString());
        }
        return objects;
    }

    /***************************关闭数据库*************************/
    /**
     * 关闭数据库一般在Odestory中使用
     */
    public void CloseDataBase(){
        manager.closeDataBase();
    }


}
(三)让不同的数据表对象继承BaseDao

其具体代码如StudentManager.java以及CustomerManager.java所示(由于本Demo中这两个Manager比较类似,所以只展示StudentManager.java)。

package com.jamy.DaoUtils;

import android.content.Context;

import com.jamy.dao.CustomerDao;
import com.jamy.entity.Customer;
import com.jamy.entity.Student;

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

import de.greenrobot.dao.query.QueryBuilder;

/**
 * Created by jamy on 16/6/16.
 * 在这个类中添加不同的查询条件
 */
public class StudentManager extends BaseDao<Student>{
    public StudentManager(Context context) {
        super(context);
    }

    /***************************数据库查询*************************/

    /**
     * 通过ID查询对象
     * @param id
     * @return
     */
    private Student loadById(long id){

       return daoSession.getStudentDao().load(id);
    }

    /**
     * 获取某个对象的主键ID
     * @param student
     * @return
     */
    private long getID(Student student){

        return daoSession.getStudentDao().getKey(student);
    }

    /**
     * 通过名字获取Customer对象
     * @return
     */
    private List<Student> getStudentByName(String key){
        QueryBuilder queryBuilder =  daoSession.getStudentDao().queryBuilder();
        queryBuilder.where(CustomerDao.Properties.Name.eq(key));
        int size = queryBuilder.list().size();
        if (size > 0){
            return queryBuilder.list();
        }else{
            return null;
        }
    }

    /**
     * 通过名字获取Customer对象
     * @return
     */
    private List<Long> getIdByName(String key){
        List<Student> students = getStudentByName(key);
        List<Long> ids = new ArrayList<Long>();
        int size = students.size();
        if (size > 0){
            for (int i = 0;i < size;i++){
                ids.add(students.get(i).getId());
            }
            return ids;
        }else{
            return null;
        }
    }

    /***************************数据库删除*************************/

    /**
     * 根据ID进行数据库的删除操作
     * @param id
     */
    private void deleteById(long id){

        daoSession.getStudentDao().deleteByKey(id);
    }


    /**
     * 根据ID同步删除数据库操作
     * @param ids
     */
    private void deleteByIds(List<Long> ids){

        daoSession.getStudentDao().deleteByKeyInTx(ids);
    }

    /***********************************
     * 在次添加一些Student特有的数据库操作语句
     * ************************************/

}
针对不同的数据表可以将一些特有的查询条件放在StudentManager类中(因为不同的数据表可能需要的查询条件不近相同),这样方便查询。

(四)将已创建的多表Manager对象封装在一个类

其具体代码如DaoUtils.java所示。

package com.jamy.DaoUtils;

import android.content.Context;
import android.util.Log;

import com.jamy.dao.CustomerDao;
import com.jamy.dao.DaoSession;
import com.jamy.dao.StudentDao;
import com.jamy.entity.Customer;
import com.jamy.entity.Student;

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

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.query.QueryBuilder;


/**
 * Created by jinfangmei on 2016/6/16.
 */
public class DaoUtils{
    private  static CustomerManager customerManager;
    private  static StudentManager studentManager;
    public  static Context context;

    public static void init(Context context){
        DaoUtils.context = context.getApplicationContext();
    }

    /**
     * 单列模式获取CustomerManager对象
     * @return
     */
    public static CustomerManager getCustomerInstance(){
        if (customerManager == null) {
            customerManager = new CustomerManager(context);
        }
        return customerManager;
    }

    /**
     * 单列模式获取StudentManager对象
     * @return
     */
    public static StudentManager getStudentInstance(){
        if (studentManager == null) {
            studentManager = new StudentManager(context);
        }
        return studentManager;
    }
}
     上面有一点需注意,由于在DaoUtils中的Context是由static修饰,所以这里的context要用ApplicationContext(防止Activity被结束而造成内存泄漏)。
     上面的一步步封装已经完成,下面在MainActivity中调用试试好不好用。哈哈。

      MainActivity.java的具体代码如下所示。

package com.jamy.testgreendao;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.jamy.DaoUtils.DaoUtils;
import com.jamy.entity.Customer;
import com.jamy.entity.Student;
import java.util.ArrayList;
import java.util.List;



public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button mAddButton;
    public Button mDeleteButton,mUpdateButton,mQueryButton;
    private List<Object> students;
    private List<Customer> customers;
    private Context context;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        DaoUtils.init(MainActivity.this);

    }

    private void initView() {
        customers = new ArrayList<Customer>();
        students  = new ArrayList<Object>();
        mAddButton = (Button) findViewById(R.id.addbutton);
        mDeleteButton = (Button) findViewById(R.id.deletebutton);
        mUpdateButton = (Button) findViewById(R.id.uodatebutton);
        mQueryButton = (Button) findViewById(R.id.queryButton);
        mAddButton.setOnClickListener(this);
        mDeleteButton.setOnClickListener(this);
        mUpdateButton.setOnClickListener(this);
        mQueryButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
      switch (v.getId()){
          case R.id.addbutton:
              for (int i=0;i<4;i++){
                  Student student = new Student();
                  student.setName("jamy");
                  student.setAge(110+i);
                  student.setDepartment("A1113"+i);
                  students.add(student);
              }
              for (int i=0;i<4;i++){
                  Customer customer = new Customer();
                  customer.setName("jin"+i);
                  customer.setAddress("shenzhen"+i);
                  customer.setType("CEO");
                  customers.add(customer);
              }
              DaoUtils.getCustomerInstance().insertMultObject(customers);
              break;
          case R.id.deletebutton:
              DaoUtils.getCustomerInstance().deleteByIds(DaoUtils.getCustomerInstance().getIdByName("jin2"));

              break;
          case R.id.queryButton:
             List<Customer> list = DaoUtils.getCustomerInstance().QueryAll(Customer.class);
              for (int i=0;i<list.size();i++){
                  Customer customer = list.get(i);
                  Log.d("JAMY","id:"+customer.getId()+" name:"+customer.getName()
                          +"  Address:"+customer.getAddress()+"  Type:"+customer.getType());
              }

              break;
          case R.id.uodatebutton:

              Customer customer = new Customer();
              customer.setId(1l);
              customer.setName("jinfangmei");
              customer.setType("CEO");
              customer.setAddress("shenzhen0");
              DaoUtils.getCustomerInstance().updateObject(customer);
//              if (null != customers){
//                  for (int i=0;i<customers.size();i++){
//                      Log.d("JAMY",customers.get(i).getId().toString());
//                  }
//              }
//              List<Long> ids = daoUtils.getIdByKey("jin1");
//              Log.d("JAMY",ids.toString());
              break;
      }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        DaoUtils.getCustomerInstance().CloseDataBase();
    }
}

好了,调用了下,感觉还是不错的。虽说不是很完美,但最起码凑合凑合能用。以上就是鄙人对GreenDao进行的一些简单的封装,知道还不是很完善,希望各位多给批评建议,没有你们的建议就没有我的逐步成长。两篇博客搞定,哈哈。









  

以上是关于GreenDao的实用封装的主要内容,如果未能解决你的问题,请参考以下文章

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包括新闻图片视频3个大模块,代码封装良好

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包含新闻图片视频3个大模块,代码封装良好

[Android] Android 使用 Greendao 操作 db sqlite-- 封装DaoUtils类1

优雅设计封装基于Okhttp3的网络框架:多线程下载添加数据库支持(greenDao)及 进度更新

Android 实用代码片段

Android 实用代码片段