Android數據庫GreenDao使用說明

介紹

GreenDao是一個開源的 Android ORM嵌入式關係數據庫,通過將 Java 對象映射到數據庫表(稱爲 ORM,“對象/關係映射”) ,使用一個簡單的面向對象的 API 來存儲、更新、刪除和查詢 Java 對象。

GreenDao特點

  • 最佳性能 (可能是 Android 中最快的 ORM) ,基準測試也是開源的;
  • 易於使用的功能強大的 api,涵蓋關係和連接;
  • 最小的內存消耗;
  • 小型庫大小(< 100KB) ,以保持較低的構建時間,並避免65k 方法限制;
  • 數據庫加密:greenDAO 支持 SQLCipher 來保證用戶數據的安全;
  • 強大而活躍的社區交流支持。

Github地址 https://github.com/greenrobot/greenDAO

項目配置

  1. 項目目錄下.gradle文件配置:

    buildscript {
        repositories {
            google()
            jcenter()
            // GreenDao倉庫
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.4'
            // GreenDao插件
            classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
        }
    }
    
  2. app目錄下.gradle配置

    apply plugin: 'com.android.application'
    //GreenDao插件
    apply plugin: 'org.greenrobot.greendao'
    
    dependencies {
            //GreenDao依賴添加
        implementation 'org.greenrobot:greendao:3.2.2'
    }
    
    greendao {
        // 數據庫版本號
        schemaVersion 1
        // 生成數據庫文件的目錄
        targetGenDir 'src/main/java'
        // 生成的數據庫相關文件的包名
        daoPackage 'com.nianlun.greendao.gen'
    }
    

使用說明

1、 首先新建用戶實體類,如下:

@Entity
public class User {

    @Id(autoincrement = true)
    private Long id;

    @Unique
    private String userId;

    @Property
    private String userName;

    @Property
    private int age;

}

實體類中詳細註解說明:

  • @Entity:表明這個實體類會在數據庫中生成一個與之相對應的表,其中可配置項:

    nameInDb:可以自定義表名,表明該實體對應數據庫中的那張表,默認爲實體類名;

    indexes:定義索引,這裏可跨越多個列;

    createInDb:如果是有多個實體都關聯這個表,可以把多餘的實體裏面設置爲false避免重複創建(默認是true);

    schema:一個項目中有多個schema時,表明要讓這個dao屬於哪個schema;

    active:是否應該生成更新/刪除/刷新方法。如果Entity定義了 @ToOne 或 @ToMany關係,那麼獨立於該值是有效的。意爲是否支持實體類之間update,refresh,delete等操作。

  • @Id:對應數據表中的主鍵,是一條數據的唯一標識。如果實體沒有聲明主鍵,默認創建Long類型主鍵"_id"自增。使用Long類型主鍵時可以通過@Id(autoincrement = true)設置爲自增。

  • @Property(nameInDb = "USER_NAME" ):可以自定義字段名,注意外鍵不能使用該屬性。表明這個屬性對應數據表中的 USER_NAME 字段。

  • @NotNull:該屬性值不能爲空。

  • @Transient:該屬性不會被存入數據庫中。

  • @Unique:表明該屬性在數據庫中只能有唯一值。

  • @Index:創建一個索引。通過name設置索引別名,也可以通過unique給索引添加約束。

  • @Convert:指定一個PropertyConverter用於支持自定義類型(沒用過)。

  • @ToOne:定義自己與一個實體對象的關係。

  • @ToMany:定義自己與多個實體對象的關係(可不與@ToOne聯合使用)。@ToMany的屬性referencedJoinProperty,類似於外鍵約束。

  • @JoinProperty:對於更復雜的關係,可以使用這個註解標明目標屬性的源屬性,起關聯作用。

  • @JoinEntity:如果你在做多對多的關係,有其他的表或實體參與,可以給目標屬性添加這個額外的註解。

  • @OrderBy:指定{@ToMany}關係的相關集合的排序,(propertyA, propertyB)默認爲按主鍵ASC排序。

  • @Generated:這個是build後greendao自動生成的,這個註解理解爲防止重複,每一塊代碼生成後會加個hash作爲標記。

2、 實體類建完畢後,通過點擊AndroidStudio中的Make Project(小錘子的圖標),便發現GreenDao爲我們的User實體類生成了對應的Getter、Setter方法以及倆個構造函數,同時在我們配置的com.nianlun.greendao.gen包下生成了三個對應類文件DaoMasterDaoSessionUserDao,之後所有相關的數據庫操作都依靠這三個文件了:

  • DaoMaster:使用greenDAO的切入點。DaoMaster保存數據庫對象(SQLiteDatabase)並管理特定模式的DAO類(而不是對象)。 它具有靜態方法來創建表或將它們刪除。 其內部類OpenHelper和DevOpenHelper是在SQLite數據庫中創建模式的SQLiteOpenHelper實現。一個DaoMaster就代表着一個數據庫的連接;
  • DaoSession:管理特定模式的所有可用DAO對象,您可以使用其中一個getter方法獲取。 DaoSession還爲實體提供了一些通用的持久性方法,如插入,加載,更新,刷新和刪除。 DaoSession可以讓我們使用一些Entity的基本操作和獲取Dao操作類,DaoSession可以創建多個,每一個都是屬於同一個數據庫連接的;
  • XxDAO:數據訪問對象(DAO)持續存在並查詢實體。 對於每個實體,GreenDAO生成一個DAO。 它比DaoSession有更多的持久化方法,例如:count,loadAll和insertInTx等。

3、數據庫操作

(1) 編寫DaoManager,用於創建數據庫、創建數據庫表、包含增刪改查的操作。

/**
 * 創建數據庫、創建數據庫表、包含增刪改查的操作 
 */
public class DaoManager {
    private static final String TAG = DaoManager.class.getSimpleName();
    private static final String DB_NAME = "RECORD_DB";

    private Application mApplication;

    //多線程中要被共享的使用volatile關鍵字修飾
    private volatile static DaoManager manager = new DaoManager();
    private DaoMaster mDaoMaster;
    private DaoMaster.DevOpenHelper mHelper;
    private DaoSession mDaoSession;

    /**
     * 單例模式獲得操作數據庫對象
     */
    public static DaoManager getInstance() {
        return manager;
    }

    private DaoManager() {
        setDebug();
    }

    public void init(Application application) {
        this.mApplication = application;
    }

    /**
     * 判斷是否有存在數據庫,如果沒有則創建
     */
    public DaoMaster getDaoMaster() {
        if (mDaoMaster == null) {
            DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(mApplication, DB_NAME, null);
            mDaoMaster = new DaoMaster(helper.getWritableDatabase());
        }
        return mDaoMaster;
    }

    /**
     * 完成對數據庫的添加、刪除、修改、查詢操作,僅僅是一個接口
     */
    public DaoSession getDaoSession() {
        if (mDaoSession == null) {
            if (mDaoMaster == null) {
                mDaoMaster = getDaoMaster();
            }
            mDaoSession = mDaoMaster.newSession();
        }
        return mDaoSession;
    }

    /**
     * 打開輸出日誌,默認關閉
     */
    public void setDebug() {
        if (BuildConfig.DEBUG) {
            QueryBuilder.LOG_SQL = true;
            QueryBuilder.LOG_VALUES = true;
        }
    }

    /**
     * 關閉所有的操作,數據庫開啓後,使用完畢要關閉
     */
    public void closeConnection() {
        closeHelper();
        closeDaoSession();
    }

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

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

(2)編寫CommonDaoUtils,用於完成對數據表的操作。

public class CommonDaoUtils<T> {

    private DaoSession mDaoSession;
    private Class<T> entityClass;
    private AbstractDao<T, Long> entityDao;

    public CommonDaoUtils(Class<T> pEntityClass, AbstractDao<T, Long> pEntityDao) {
        DaoManager mManager = DaoManager.getInstance();
        mDaoSession = mManager.getDaoSession();
        entityClass = pEntityClass;
        entityDao = pEntityDao;
    }

    /**
     * 插入記錄,如果表未創建,先創建表
     */
    public boolean insert(T pEntity) {
        return entityDao.insert(pEntity) != -1;
    }

    /**
     * 插入多條數據,在子線程操作
     */
    public boolean insertMultiple(final List<T> pEntityList) {
        try {
            mDaoSession.runInTx(new Runnable() {
                @Override
                public void run() {
                    for (T entity : pEntityList) {
                        mDaoSession.insertOrReplace(entity);
                    }
                }
            });
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 修改一條數據
     */
    public boolean update(T entity) {
        try {
            mDaoSession.update(entity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 刪除單條記錄
     */
    public boolean delete(T entity) {
        try {
            //按照id刪除
            mDaoSession.delete(entity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 刪除所有記錄
     */
    public boolean deleteAll() {
        try {
            //按照id刪除
            mDaoSession.deleteAll(entityClass);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 查詢所有記錄
     */
    public List<T> queryAll() {
        return mDaoSession.loadAll(entityClass);
    }

    /**
     * 根據主鍵id查詢記錄
     */
    public T queryById(long key) {
        return mDaoSession.load(entityClass, key);
    }

    /**
     * 使用native sql進行查詢操作
     */
    public List<T> queryByNativeSql(String sql, String[] conditions) {
        return mDaoSession.queryRaw(entityClass, sql, conditions);
    }

    /**
     * 使用queryBuilder進行查詢
     */
    public List<T> queryByQueryBuilder(WhereCondition cond, WhereCondition... condMore) {
        QueryBuilder<T> queryBuilder = mDaoSession.queryBuilder(entityClass);
        return queryBuilder.where(cond, condMore).list();
    }
}

(3)編寫DaoUtilsStore,用於存放及提取DaoUtils。

/**
 * 初始化、存放及獲取DaoUtils
 */
public class DaoUtilsStore {
    private volatile static DaoUtilsStore instance = new DaoUtilsStore();
    private CommonDaoUtils<User> mUserDaoUtils;

    public static DaoUtilsStore getInstance() {
        return instance;
    }

    private DaoUtilsStore() {
        DaoManager mManager = DaoManager.getInstance();
        UserDao _UserDao = mManager.getDaoSession().getUserDao();
        mUserDaoUtils = new CommonDaoUtils<>(User.class, _UserDao);
    }

    public CommonDaoUtils<User> getUserDaoUtils() {
        return mUserDaoUtils;
    }

}

(4)調用DaoUtilsStore,進行數據操作及查看:

  • 初始化生成數據,進行批量插入:

    private void initUser() {
    
        //用戶ID生成器
        mIdWorker = new SnowflakeIdGenerator(0, 0);
    
        DaoUtilsStore.getInstance().getUserDaoUtils().deleteAll();
    
        mUserList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setId((long) i);
            user.setUserId(String.valueOf(mIdWorker.nextId()));
            // 隨機生成漢語名稱
            user.setUserName(NameUtils.createRandomZHName(random.nextInt(4) + 1));
            user.setAge(18 + random.nextInt(10));
            mUserList.add(user);
        }
    
        mUserAdapter = new UserAdapter(mUserList);
        rvUser.setAdapter(mUserAdapter);
    
        DaoUtilsStore.getInstance().getUserDaoUtils().insertMultiple(mUserList);
    }
    
  • 查詢數據

    private void queryAllUser() {
        mUserList = DaoUtilsStore.getInstance().getUserDaoUtils().queryAll();
        mUserAdapter.setNewData(mUserList);
        rvUser.smoothScrollToPosition(mUserList.size() - 1);
    }
    
  • 插入數據

    User user = new User();
    user.setId((long) mUserList.size());
    user.setUserId(String.valueOf(mIdWorker.nextId()));
    user.setUserName(NameUtils.createRandomZHName(new Random().nextInt(4) + 1));
    user.setAge(18 + new Random().nextInt(10));
    
    // 插入新用戶
    DaoUtilsStore.getInstance().getUserDaoUtils().insert(user);
    
  • 修改數據

    User user = mUserList.get(mUserList.size() - 1);
    
    //刪除最末用戶
    DaoUtilsStore.getInstance().getUserDaoUtils().delete(user);
    
  • 刪除數據

    User user = mUserList.get(mUserList.size() - 1);
    user.setUserName(NameUtils.createRandomZHName(new Random().nextInt(4) + 1));
    
    //更新最末用戶
    DaoUtilsStore.getInstance().getUserDaoUtils().update(user);
    

以上就是GreenDao的簡單介紹接使用說明,更多進階用法如升級、加密等將慢慢補充,並且進一步探索官方推薦的從GreenDao到ObjectBox數據庫的集成過程。

訪問Github項目查看具體代碼實現:

https://github.com/MickJson/DevelopmentRecord

歡迎點擊查閱及Star,我也會繼續補充其它有用的知識及例子在項目上。

歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!

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