GreenDao的簡單使用2

GreenDao的進階

在上一篇的greendao的使用的介紹中,我們知道了利用XXXDao可以完成數據庫的一些基礎的操作,例如:增、刪、改、查

再次回憶三個自動生成的核心類:DaoMaster、DaoSession、XXXDao

  • DaoMaster稱作會話層,DaoMaster包含了一個DevOpenHelper(繼承自OpenHelper),DevOpenHelper包含了對數據庫的基礎操作,例如:創建表,刪除表,更新表,值得一提的是,DevOpenHelper類當中的升級數據庫的方式是先將所有的表格刪除,然後在重新創建表格,所有的數據就會消失掉,解決這個辦法請參考:greendao3.0以上使用步驟(二):數據庫到底該怎麼升級http://blog.csdn.net/huangxiaoguo1/article/details/54574713
  • DaoSession 管理XXXDao.class類,也提供了增刪改查的方法(其實是使用了AbstractDao抽象類)
  • XXXDao 每一個table實體(Entity)對應的Dao類,提供了數據的增刪改查等等一系列操作,比DaoSession類提供的方法更加具體

在項目中使用GreenDao操作數據的步驟:

1. (推薦)自己維護一個DaoManager的類,用來獲取DaoMaster和DaoSession實例,例如:

public class DaoManager {
    //數據庫名
    private static final String DB_NAME = "student.db";

    private Context mContext;
    //單例模式
    private volatile static DaoManager mDaoManager;

    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    private DaoMaster.DevOpenHelper mOpenHelper;

    private DaoManager(Context context) {
        this.mContext = context;
    }

    public static DaoManager getInstance(Context context) {
        if (mDaoManager == null) {
            synchronized (DaoManager.class) {
                mDaoManager = new DaoManager(context);
            }
        }

        return mDaoManager;
    }

    /**
     * 判斷是否存在數據庫,如果不存在,就創建數據庫
     *
     * @return
     */
    public DaoMaster getDaoMaster() {
        if (mDaoMaster == null) {
            mOpenHelper = new DaoMaster.DevOpenHelper(mContext, DB_NAME);

            //完成數據庫的創建
            mDaoMaster = new DaoMaster(mOpenHelper.getWritableDatabase());
        }
        return mDaoMaster;
    }


    public DaoSession getDaoSession() {
        if (mDaoSession == null) {
            if (mDaoMaster == null) {
                mDaoMaster = getDaoMaster();
            }
            mDaoSession = mDaoMaster.newSession();
        }

        return mDaoSession;
    }


    /**
     * 打開輸出日誌的操作,默認是關閉的
     */
    public void setDebug() {
        QueryBuilder.LOG_SQL = true;
        QueryBuilder.LOG_VALUES = true;
    }

    /**
     * 關閉
     */
    public void closeDaoSession() {
        if (mDaoSession != null) {
            mDaoSession.clear();
            mDaoSession = null;
        }
    }

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

    /**
     * 關閉數據庫連接
     */
    public void closeDBConncetion() {
        closeDaoSession();
        closeHelper();
    }

}

2. 創建每一張table表格對應的dao,如下

public class StudentDaoManager {
    private DaoManager mDaoManager;

    private StudentDaoManager(Context context) {
        mDaoManager = DaoManager.getInstance(context);
    }

    //單例模式
    private static volatile StudentDaoManager mStudentDaoManager;

    public static StudentDaoManager getInstance(Context context) {
        if (mStudentDaoManager == null) {
            synchronized (StudentDaoManager.class) {
                if (mStudentDaoManager == null) {
                    mStudentDaoManager = new StudentDaoManager(context);
                }
            }
        }

        return mStudentDaoManager;
    }

    /**
     * 插入單條數據
     *
     * @param student 需要插入的數據
     * @return 是否插入成功
     */
    public boolean insertStu(Student student) {
        boolean flag = false;
        flag = mDaoManager.getDaoSession().getStudentDao().insert(student) != -1 ? true : false;
        return flag;
    }

    /**
     * 插入或者更新單條數據,如果數據已經存在,那麼更新該條數據
     *
     * @param student
     * @return 是否插入成功
     */
    public boolean insertOrReplace(Student student) {
        boolean flag = false;
        flag = mDaoManager.getDaoSession().getStudentDao().insertOrReplace(student) != -1 ? true : false;
        return flag;
    }


    /**
     * 插入多條數據
     *
     * @param isUseTra 是否使用事物
     * @param list     需要批量插入的數據的列表
     * @return 是否插入成功
     */
    public boolean insertMutiStus(boolean isUseTra, List<Student> list) {
        boolean flag = false;
        try {

            if (isUseTra) {
                //使用事物批量插入
               mDaoManager.getDaoSession().getStudentDao().insertOrReplaceInTx(list);

            } else {
                for (Student student : list) {
                    //使用普通的方法,單條單條的插入
                    mDaoManager.getDaoSession().getStudentDao().insertOrReplace(student);
                }
            }
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 刪除單條數據
     *
     * @param student
     * @return 是否插入成功
     */
    public boolean delete(Student student) {
        boolean flag = false;
        try {
            mDaoManager.getDaoSession().getStudentDao().delete(student);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return flag;
    }

    /**
     * 更新數據
     *
     * @param student 需要更新的數據
     * @return 是否插入成功
     */
    public boolean update(Student student) {
        boolean flag = false;
        try {
            mDaoManager.getDaoSession().getStudentDao().update(student);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 返回所有的數據
     *
     * @return 列表
     */
    public List<Student> queryAll() {
        List<Student> students = mDaoManager.getDaoSession().getStudentDao().loadAll();
        return students;
    }

    /**
     * 返回單條記錄
     *
     * @param studentId Student對象的ID,主鍵
     * @return 單條記錄
     */
    public Student queryOne(long studentId) {
        return mDaoManager.getDaoSession().getStudentDao().load(studentId);
    }

    /**
     * 分頁查詢
     *
     * @param limit  查詢記錄的條數
     * @param offset 查詢的起始位置
     * @return
     */
    public List<Student> queryOffset(int limit, int offset) {
        QueryBuilder<Student> builder = mDaoManager.getDaoSession().getStudentDao().queryBuilder();
        builder.offset(offset).limit(limit);
        List<Student> list = builder.list();
        return list;
    }

    /**
     * 使用QueryBuilder進行查詢,
     *
     * @return
     */
    public List<Student> queryWithBuilder() {
        QueryBuilder<Student> builder = mDaoManager.getDaoSession().getStudentDao().queryBuilder();
        //1.使用了where(所有的where之間都是邏輯與的關係,相當於and)相當於:select * from student where name like "%樂" and sex = "男";
        builder.where(StudentDao.Properties.Name.like("%樂")).where(StudentDao.Properties.Sex.eq("男"));
        //2.上面相當於:
//        builder.where(StudentDao.Properties.Name.like("%樂"),StudentDao.Properties.Sex.eq("男"));

        //3.邏輯或,相當於or,將許多個查詢條件串聯起來
        builder.whereOr(StudentDao.Properties.Name.like("%樂%"), StudentDao.Properties.Sex.eq("男"));

        //4.和1中的查詢結果是一樣的
        List<Student> students = mDaoManager.getDaoSession().getStudentDao().queryRaw("where name like ? and sex = ?", new String[]{"%樂%", "男"});
        List<Student> studentList = builder.list();
        return students;
    }
}

上面的代碼有些長,需要注意的是:

1.使用事務將數據插入(insert)到數據庫的時候,對於數據量比較大的應該採取開啓事務

//使用事物批量插入
mDaoManager.getDaoSession().getStudentDao().insertOrReplaceInTx(list);

可以看到直接傳入一個List對象即可.另外需要注意的是,在批量插入數據的過程中,如果出現一個數據插入錯誤,那麼事務就會回滾到插入前的狀態.事務的開啓與關閉,在greendao中已經爲我們封裝好了,我們不用操心.

2.查詢數據是重中之重,對於SQL不是很熟悉的程序員來說,QueryBuilder是個好東西,先來看看怎麼用吧:

QueryBuilder<Student> builder = mDaoManager.getDaoSession().getStudentDao().queryBuilder();
        //1.使用了where(所有的where之間都是邏輯與的關係,相當於and)相當於:select * from student where name like "%樂" and sex = "男";
        builder.where(StudentDao.Properties.Name.like("%樂")).where(StudentDao.Properties.Sex.eq("男"));
        //2.上面相當於:
//        builder.where(StudentDao.Properties.Name.like("%樂"),StudentDao.Properties.Sex.eq("男"));

        //3.邏輯或,相當於or,將許多個查詢條件串聯起來
        builder.whereOr(StudentDao.Properties.Name.like("%樂%"), StudentDao.Properties.Sex.eq("男"));

        //4.和1中的查詢結果是一樣的
        List<Student> students = mDaoManager.getDaoSession().getStudentDao().queryRaw("where name like ? and sex = ?", new String[]{"%樂%", "男"});

3. 我們知道XXXDao是繼承自AbstractDao的,XXXDao封裝了基本的增刪改查的方法,而DaoSession也包含基本的增刪改查的方法,在維護自己的XXXDao的時候,就像上面的示例代碼中我自己定義了一個StudentDaoManager,裏面包含了許多的增刪改查的方法,這個StudentDaoManager只針對一張table,也就是Student,而日常的開發中數據庫中肯定有多張表格,我們針對一張表格就寫一個DaoManager這豈不是增加了開發的重複性.因此我建議直接將XXXDao這個自動生成的忽略掉,直接用DaoSession中的增刪改查方法來操作數據庫數據,示例如下:

//插入數據,T是泛型
public void insert(T t) {
    mDaoManager.getDaoSession().insert(t);
}

這樣此數據庫中的所有表格對應的數據就都能使用此方法了,而不用一個Entity就需要維護一個Dao

**4.**Properties是Student是StudentDao的一個內部類,維護了每一個table實體的列名
關於更多類似於where、whereOr、like等等的greendao關鍵詞的含義,請參考greendao官方API(http://greenrobot.org/files/greendao/javadoc/current/

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