介紹
GreenDao是一個開源的 Android ORM嵌入式關系數據庫,通過將 Java 對象映射到數據庫表(稱為 ORM,“對象/關系映射”) ,使用一個簡單的面向對象的 API 來存儲、更新、刪除和查詢 Java 對象。
GreenDao特點
- 最佳性能 (可能是 Android 中最快的 ORM) ,基准測試也是開源的;
- 易於使用的功能強大的 api,涵蓋關系和連接;
- 最小的內存消耗;
- 小型庫大小(< 100KB) ,以保持較低的構建時間,並避免65k 方法限制;
- 數據庫加密:greenDAO 支持 SQLCipher 來保證用戶數據的安全;
- 強大而活躍的社區交流支持。
Github地址 https://github.com/greenrobot/greenDAO
項目配置
-
項目目錄下
.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' } }
-
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
包下生成了三個對應類文件DaoMaster
、DaoSession
和UserDao
,之后所有相關的數據庫操作都依靠這三個文件了:
- 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,我也會繼續補充其它有用的知識及例子在項目上。
歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!