一.前言
官方文檔是這樣解釋的:
greenDAO是一款開放源代碼的Android ORM,使SQLite數(shù)據(jù)庫的開發(fā)變得有趣。 它減輕開發(fā)人員處理低級數(shù)據(jù)庫需求,同時節(jié)省開發(fā)時間。 SQLite是一個令人敬畏的嵌入式關系數(shù)據(jù)庫。 不過,編寫SQL和解析查詢結(jié)果是相當乏味和耗時的任務。 通過將Java對象映射到數(shù)據(jù)庫表(稱為ORM“對象/關系映射”),greenDAO可以將它們從這些映射釋放出來。 這樣,您可以使用簡單的面向?qū)ο蟮腁PI來存儲,更新,刪除和查詢Java對象。
簡單來說 GreenDAO 是一個將對象映射到 SQLite 數(shù)據(jù)庫中的輕量且快速的 ORM解決方案。

二.優(yōu)點
超簡單:簡潔直觀的API
?。簬?lt;150K,它只是純Java jar(沒有CPU依賴的本機部分)
快速:可能是由智能代碼生成驅(qū)動的Android中最快的ORM
安全和表達式的查詢API:QueryBuilder使用屬性常量來避免打字錯誤
強大的連接:跨實體查詢,甚至鏈接復雜關系
靈活的屬性類型:使用自定義類或枚舉來表示實體中的數(shù)據(jù)
加密:支持SQLCipher加密數(shù)據(jù)庫
代碼自動生成
開源
支持緩存
GreenDao與其他數(shù)據(jù)庫的速度對比:

三.配置
// In your root build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
}
allprojects {
repositories {
jcenter()
//使用數(shù)據(jù)庫升級輔助GreenDaoUpgradeHelper時添加
maven { url "https://jitpack.io" }
}
}
// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v1.4.0'//數(shù)據(jù)庫升級輔助
}
設置schema
在app的build.gradle 的android路徑下配置
greendao {
schemaVersion 1//<--數(shù)據(jù)庫的版本,用于升級時候進行更改
daoPackage 'com.fsp.greendao.gen'//這個是生成DAOs、DaoMaster、DaoSession代碼保存的包名,默認為entities所在包名
targetGenDir 'src/main/java'//生成DAOs、DaoMaster、DaoSession的目錄。默認為build/generated/source/greendao
}
混淆
### greenDAO 3
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties
# If you do not use SQLCipher:
-dontwarn org.greenrobot.greendao.database.**
# If you do not use RxJava:
-dontwarn rx.**
四.實現(xiàn)
好了我們來看看怎么實現(xiàn)

- 創(chuàng)建bean類
@Entity
public class UserInfo {
@Id(autoincrement =true)
private Long id;
private String name;
private int age;
private int sex;
//以下內(nèi)容是自動產(chǎn)生的
@Generated(hash = 1968140991)
public UserInfo(Long id, String name, int age, int sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
@Generated(hash = 1279772520)
public UserInfo() {
}
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 int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return this.sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
編寫完變量之后,編譯項目,(1)會自動構(gòu)造方法,get,set方法。(2)會生成 DaoMaster、DaoSession、DAOS類,類的位置位于你在app的build.gradle的schema配置
@Entity:告訴GreenDao該對象為實體,只有被@Entity注釋的Bean類才能被dao類操作
@Id:對象的Id,使用Long類型作為EntityId,否則會報錯。(autoincrement = true)表示主鍵會自增,如果false就會使用舊值
@Property:可以自定義字段名,注意外鍵不能使用該屬性
@NotNull:屬性不能為空
@Unique:該屬性值必須在數(shù)據(jù)庫中是唯一值
@Generated:greenDao生產(chǎn)代碼注解,手動修改報錯
- 數(shù)據(jù)庫的創(chuàng)建
在MyApplication的onCreate()方法中初始化
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
//初始化greendao
GreenDaoManager.getInstance();
}
public static Context getContext(){
return context;
}
}
GreenDaoManager中創(chuàng)建數(shù)據(jù)庫,并對其進行管理
public class GreenDaoManager {
private static final String DB_NAME="greendao";
private static GreenDaoManager mInstance;
private DaoMaster daoMaster;
private DaoSession daoSession;
public static GreenDaoManager getInstance(){
if(mInstance==null){
synchronized (GreenDaoManager.class){
if(mInstance==null){
mInstance =new GreenDaoManager();
}
}
}
return mInstance;
}
private GreenDaoManager(){
if(mInstance==null){
MySQLiteOpenHelper helper =new MySQLiteOpenHelper(MyApplication.getContext(),DB_NAME,null);
Database db = helper.getWritableDb();
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
}
}
public DaoSession getDaoSession(){
return daoSession;
}
public DaoMaster getDaoMaster(){
return daoMaster;
}
}
MySQLiteOpenHelper類繼承DaoMaster.OpenHelper,并重載onUpgrade方法,里面處理數(shù)據(jù)庫升級的邏輯
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
public MySQLiteOpenHelper(Context context, String name) {
super(context, name);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
//----------------------------使用sql實現(xiàn)升級邏輯
if (oldVersion == newVersion) {
Log.e("onUpgrade", "數(shù)據(jù)庫是最新版本,無需升級" );
return;
}
Log.e("onUpgrade", "數(shù)據(jù)庫從版本" + oldVersion + "升級到版本" + newVersion);
switch (oldVersion) {
case 1:
String sql = "";
db.execSQL(sql);
case 2:
default:
break;
}
//-----------------------------------
//--------------------------或者使用GreenDaoUpgradeHelper輔助庫實現(xiàn)邏輯
// MigrationHelper.migrate(db,UserDao.class);
//----------------------------
}
這里建議使用DaoMaster.OpenHelper ,不要使用DaoMaster.DevOpenHelper,因為使用DaoMaster.DevOpenHelper每次升級數(shù)據(jù)庫都會把表刪除重建,推薦開發(fā)時用。正式使用時還是用DaoMaster.OpenHelper。
通過 MigrationHelper 在刪表重建的過程中,使用臨時表保存數(shù)據(jù)并還原。
- DaoMaster.OpenHelper :創(chuàng)建SQLite數(shù)據(jù)庫的SQLiteOpenHelper的具體實現(xiàn)
- DaoMaster : GreenDao的頂級對象,用于創(chuàng)建和刪除表
- DaoSession : 管理所有的Dao對象,Dao對象可以通過 daoSession.getUserInfoDao()獲得
3.增刪改查
創(chuàng)建一個Dao類,把增刪改查的方法封裝起來,提高代碼的可復用性,簡潔性
public class UserDao {
private final GreenDaoManager daoManager;
private static UserDao mUserDao;
public UserDao(){
daoManager = GreenDaoManager.getInstance();
}
public static UserDao getInstance(){
if(mUserDao==null){
mUserDao =new UserDao();
}
return mUserDao;
}
/**
* 插入數(shù)據(jù) 若未建表則先建表
* @param userInfo
* @return
*/
public boolean insertUserData(UserInfo userInfo){
boolean flag =false;
flag =getUserInfoDao().insert(userInfo) ==-1?false :true;
return flag;
}
/**
* 插入或替換數(shù)據(jù)
* @param userInfo
* @return
*/
public boolean insertOrReplaceData(UserInfo userInfo){
boolean flag =false;
try{
flag = getUserInfoDao().insertOrReplace(userInfo)==-1?false:true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 插入多條數(shù)據(jù) 子線程完成
* @param list
* @return
*/
public boolean insertOrReplaceMultiData(final List<UserInfo> list){
boolean flag =false;
try{
getUserInfoDao().getSession().runInTx(new Runnable() {
@Override
public void run() {
for(UserInfo userInfo:list){
daoManager.getDaoSession().insertOrReplace(userInfo);
}
}
});
flag =true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 更新數(shù)據(jù)
* @param userInfo
* @return
*/
public boolean updateUserData(UserInfo userInfo){
boolean flag =false;
try{
getUserInfoDao().update(userInfo);
flag =true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 根據(jù)id刪除數(shù)據(jù)
* @param userInfo
* @return
*/
public boolean deleteUserData(UserInfo userInfo){
boolean flag =false;
try{
getUserInfoDao().delete(userInfo);
flag =true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 刪除所有數(shù)據(jù)
* @return
*/
public boolean deleteAllData(){
boolean flag =false;
try{
getUserInfoDao().deleteAll();
flag =true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 根據(jù)主鍵查詢
* @param key
* @return
*/
public UserInfo queryUserDataById(long key){
return getUserInfoDao().load(key);
}
/**
* 查詢所有數(shù)據(jù)
* @return
*/
public List<UserInfo> queryAllData(){
return getUserInfoDao().loadAll();
}
/**
* 根據(jù)名稱查詢 以年齡降序排列
* @param name
* @return
*/
public List<UserInfo> queryUserByName(String name){
Query<UserInfo> build = null;
try{
build =getUserInfoDao().queryBuilder()
.where(UserInfoDao.Properties.Name.eq(name))
.orderDesc(UserInfoDao.Properties.Age)
.build();
}catch (Exception e){
e.printStackTrace();
}
return build.list();
}
/**
* 根據(jù)參數(shù)查詢
* @param where
* @param param
* @return
*/
public List<UserInfo> queryUserByParams(String where,String... param){
return getUserInfoDao().queryRaw(where,param);
}
public UserInfoDao getUserInfoDao(){
return daoManager.getDaoSession().getUserInfoDao();
}
}
4.調(diào)用
在需要用到的地方調(diào)用方法,我這里是建了一個RecyclerView,更直觀的顯示數(shù)據(jù)的操作。你可以根據(jù)需要在適當?shù)牡胤秸{(diào)用增刪改查方法就行。
private void updateData() {
if (!lists.isEmpty()) {
UserInfo userInfo = lists.get(0);
userInfo.setName("李四");
UserDao.getInstance().updateUserData(userInfo);
queryListData();
}
}
private void deleteData() {
if (!lists.isEmpty()) {
UserDao.getInstance().deleteUserData(lists.get(0));
queryListData();
}
}
private void addData() {
UserInfo userInfo = new UserInfo();
userInfo.setName("張三");
userInfo.setAge(18);
userInfo.setSex(1);
UserDao.getInstance().insertUserData(userInfo);
queryListData();
}
private void queryListData() {
lists = UserDao.getInstance().queryAllData();
adapter.setData(lists);
Toast.makeText(this, "查詢到" + lists.size() + "條數(shù)據(jù)", Toast.LENGTH_SHORT).show();
}
5.其他方法
添加
單條數(shù)據(jù)
getUserInfoDao().insert(userInfo)
getUserInfoDao().insertOrReplace(userInfo);
多條數(shù)據(jù)
getUserInfoDao().insertInTx(userInfoList);
getUserInfoDao().insertOrReplaceInTx(userInfoList);
查詢
單個條件
where()
whereOr()
多個條件
where(,,)
whereOr(,,)
降序 orderDesc()
升序 orderAsc()
當頁限制個數(shù) limit()
根據(jù)key查詢 .load(key)
全部 .loadAll() 或者.queryBuilder().list()
修改
單條 .update(userInfo)
多條 .updateInTx(userInfoList)
刪除
單條 .delete(userInfo)
多條 .deleteInTx(userInfoList)
全部 .deleteAll()
6.演示

7.demo下載
http://download.csdn.net/detail/feibendexiaoma/9884019
總結(jié)
這里只介紹了GreenDao的基礎使用方法,比較高深的知識點如加密,多表關聯(lián)等需繼續(xù)深究,一步一步慢慢積累。