Android 讓你的數(shù)據(jù)庫(kù)操作更便捷 --- GreenDao之初體驗(yàn)

你還在為數(shù)據(jù)庫(kù)建表時(shí)那復(fù)雜而冗長(zhǎng)的SQL語(yǔ)句煩惱么?

你還在為數(shù)據(jù)庫(kù)存儲(chǔ)時(shí)那頻繁的put content values而感到焦躁么照激?

你還在為在數(shù)據(jù)庫(kù)操作中只因?yàn)镾QL語(yǔ)句中寫錯(cuò)了一個(gè)字母而找了半天bug
而感到沮喪么霎冯?

快用GreenDao吧铃拇,解決以上各種疑難雜癥,從此告別SQL語(yǔ)句沈撞。

回顧SQLiteDatabaseHelper

1.表的創(chuàng)建

如果你的數(shù)據(jù)庫(kù)當(dāng)中有20個(gè)數(shù)據(jù)模型慷荔,你要將以下面這段東西寫20遍,還不帶重樣的- -缠俺。
If you type a wrong letter显晶,loses the whole game

@Override 
 public void onCreate(SQLiteDatabase db) {      
          StringBuilder sb2 = new StringBuilder();
          sb2.append("CREATE TABLE "+ TABLE_NAME+ "(")
         .append("_id INTEGER PRIMARY KEY AUTOINCREMENT,")
         .append("it TEXT,")
         .append("is TEXT,")
         .append("too TEXT,")
         .append("painful TEXT,")
         .append("do INTEGER,")
         .append("you TEXT,")
         .append("think BIGINT,")
         .append("so INTEGER")
         .append(");");
         db.execSQL(sb2.toString());
  }
2.數(shù)據(jù)庫(kù)的存儲(chǔ)操作
//以寫入模式獲取數(shù)據(jù)存儲(chǔ)庫(kù)
SQLiteDatabase db = mDbHelper.getWritableDatabase();
//創(chuàng)建一個(gè)新的值映射,其中列名稱是鍵
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);
//插入新行壹士,返回新行的主鍵值
long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);
3.數(shù)據(jù)庫(kù)的查詢
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 指定數(shù)據(jù)庫(kù)中的哪些列
String[] projection = {FeedEntry._ID,    FeedEntry.COLUMN_NAME_TITLE,    FeedEntry.COLUMN_NAME_SUBTITLE    };
// 過濾title值為 'My Title'的數(shù)據(jù)
String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = { "My Title" };
// 制定返回結(jié)果的排列順序
String sortOrder =  FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";
Cursor c = db.query(FeedEntry.TABLE_NAME,                     // 你要查詢的表
        projection,                               // 要返回的列
        selection,                                //定義的數(shù)據(jù)過濾規(guī)則
        selectionArgs,                            // 過濾后返回的參數(shù)
        null,                                     // 不對(duì)行進(jìn)行分組  
        null,                                     //不按照行分的組過濾數(shù)據(jù)  
        sortOrder                                 // 定義的排序規(guī)則    );
cursor.moveToFirst();
long itemId = cursor.getLong(cursor.getColumnIndexOrThrow(FeedEntry._ID));
4.數(shù)據(jù)庫(kù)的刪除
// 定義查詢位置
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
// 制定要?jiǎng)h除的參數(shù)(既title = 'MyTitle')
String[] selectionArgs = { "MyTitle" };
// 對(duì)應(yīng)的刪除操作
db.delete(FeedEntry.TABLE_NAME, selection, selectionArgs)
5.數(shù)據(jù)庫(kù)的更新
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 定義要更新的值
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
//根據(jù)過濾調(diào)制定制要更新的列
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = { "MyTitle" };
int count = db.update(FeedReaderDbHelper.FeedEntry.TABLE_NAME,values, selection,selectionArgs);

當(dāng)然你也可以直接通過SQL語(yǔ)句進(jìn)行相關(guān)操作

SQLiteDatabase db = mDbHelper.getReadableDatabase();
db.getReadableDatabase().execSQL(your sql?);  //執(zhí)行增刪改查的SQL語(yǔ)句

GreenDao是什么磷雇?

一言以蔽之,greenDAO就是一個(gè)開源的Android ORM(對(duì)象關(guān)系映射)框架躏救,使SQLite數(shù)據(jù)庫(kù)的開發(fā)變得簡(jiǎn)單唯笙,便捷。而且在性能上greenDao也做了很大的優(yōu)化落剪。該文章主要是介紹如何使用greenDao睁本。(畢竟該發(fā)揮拿來主義的時(shí)候就要發(fā)揮- -)

GreenDao的使用

1.Android Studio中的配置

① app目錄下build.grandle的配置

dependencies依賴:

dependencies {  
       compile 'org.greenrobot:greendao:3.1.0'  
 }

在android的根下添加:

android {  
    greendao{     
         schemaVersion 1     //控制數(shù)據(jù)庫(kù)版本尿庐,若數(shù)據(jù)庫(kù)結(jié)構(gòu)發(fā)生改變忠怖,更改此處版本號(hào)
         targetGenDir 'src/main/java' 
   }
}

并在最上方添加對(duì)應(yīng)的plugin
apply plugin: 'org.greenrobot.greendao'

② 工程根目錄下目錄下build.grandle的配置

buildscript {   
     repositories {     
         jcenter()  
      }  
      dependencies {  
          classpath 'com.android.tools.build:gradle:2.2.0'     
           classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'      
     }
}

2.創(chuàng)建一張新的表
1.首先你要先創(chuàng)建一個(gè)新的類。并未類的屬性標(biāo)上對(duì)應(yīng)的注解
@Entity代表你所要?jiǎng)?chuàng)建表的實(shí)體
@Id表示數(shù)據(jù)庫(kù)的主鍵
@Property表示該實(shí)體里對(duì)應(yīng)的屬性(也就是字段)

@Entity
public class Singer {   
       @Id    
       private Long id;         //主鍵
       @Property         
       private String name;  
       @Property   
       private String sex;   
       @Property   
       private String country;
}

2.自動(dòng)生成對(duì)應(yīng)的DaoSession和DaoMater文件

之后雙擊 Build 一欄下的 Make Moudle app


編譯完成后你會(huì)發(fā)現(xiàn)你的項(xiàng)目結(jié)構(gòu)發(fā)生了如下變化:

我們回發(fā)現(xiàn)Studio自動(dòng)幫我們生成了DaoMaster抄瑟,DaoSessionSinger的實(shí)體操作類SingerDao凡泣。

3.GreenDao是如何工作的?
(此處只是簡(jiǎn)單的介紹一下GreenDao的工作原理皮假,以及粗略的剖析一下源碼鞋拟,沒興趣的哥(姐)們兒直接可直接忽略此小節(jié))

這里先簡(jiǎn)單的介紹一下這三個(gè)東西。

*** - DaoMaster***
greenDAO的入口點(diǎn)惹资。 DaoMaster保存數(shù)據(jù)庫(kù)對(duì)象(SQLiteDatabase)并管理特定模式的DAO類(而不是對(duì)象)贺纲。它有靜態(tài)方法來創(chuàng)建表或刪除它們。它的內(nèi)部類OpenHelper和DevOpenHelper的底層依舊由SQLiteOpenHelper實(shí)現(xiàn)褪测,在SQLite數(shù)據(jù)庫(kù)中創(chuàng)建數(shù)據(jù)庫(kù)猴誊,具體可以查看DaoMaster的源碼潦刃。以下貼出部分源碼

/**DaoMaster源碼**********************************/
public class DaoMaster extends AbstractDaoMaster {
      //此處為數(shù)據(jù)庫(kù)版本號(hào)
       public static final int SCHEMA_VERSION = 1;
      //此處也可自己定義一個(gè)類去繼承OpenHelper
      public static class DevOpenHelper extends OpenHelper {
               public DevOpenHelper(Context context, String name, CursorFactory factory) {
                      super(context, name, factory);
               }
        }

        public static abstract class OpenHelper extends DatabaseOpenHelper {
                  public OpenHelper(Context context, String name, CursorFactory factory) {
                  super(context, name, factory, SCHEMA_VERSION);
        }
      }
}

/*DatabaseOpenHelper 源碼***********************************/

public abstract class DatabaseOpenHelper extends SQLiteOpenHelper{
         public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version) {
                  super(context, name, factory, version);
                  this.context = context;
                  this.name = name;
                  this.version = version;
    }
}

-DaoSession
管理特定模式的所有可用DAO對(duì)象懈叹,您可以使用其中一個(gè)getter方法獲取它們乖杠。 DaoSession還為實(shí)體提供了一些通用的持久性方法,如插入澄成,加載胧洒,更新,刷新和刪除墨状。以下為DaoSession源碼

public class DaoSession extends AbstractDaoSession {

    private final DaoConfig singerDaoConfig;

    private final SingerDao singerDao;

    public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
            daoConfigMap) {
        super(db);

        singerDaoConfig = daoConfigMap.get(SingerDao.class).clone();
        singerDaoConfig.initIdentityScope(type);
        //創(chuàng)建對(duì)應(yīng)的DAO對(duì)象
        singerDao = new SingerDao(singerDaoConfig, this);
        //將DAO對(duì)象與Singer綁定起來
        registerDao(Singer.class, singerDao);
    }

    /**獲取對(duì)應(yīng)的DAO對(duì)象*/  
    public SingerDao getSingerDao() {
        return singerDao;
    }

}

-SingerDao
這個(gè)我想不必過多介紹卫漫,相信接觸過數(shù)據(jù)庫(kù)操作的各位親們都不會(huì)對(duì)它陌生,接下來讓我們簡(jiǎn)單的看以它的部分代碼肾砂。

public class SingerDao extends AbstractDao<Singer, Long> {

    public static void createTable(Database db, boolean ifNotExists) {
        String constraint = ifNotExists? "IF NOT EXISTS ": "";
        db.execSQL("CREATE TABLE " + constraint + "\"SINGER\" (" + //
                "\"_id\" INTEGER PRIMARY KEY ," + // 0: id
                "\"NAME\" TEXT," + // 1: name
                "\"SEX\" TEXT," + // 2: sex
                "\"COUNTRY\" TEXT);"); // 3: country
    }
}

我們會(huì)發(fā)現(xiàn)在這個(gè)類已經(jīng)幫我們把表創(chuàng)建好了汛兜,關(guān)鍵是不需要你寫一句SQL語(yǔ)句,你要想創(chuàng)建20張表的話只要寫上20個(gè)數(shù)據(jù)模型并標(biāo)上對(duì)應(yīng)的屬性值就可以了通今。這里會(huì)被DaoMaster調(diào)用粥谬。

public class DaoMaster extends AbstractDaoMaster {
    public static void createAllTables(Database db, boolean ifNotExists) {
        //此處調(diào)用
        SingerDao.createTable(db, ifNotExists);
    }
}

那他又是如何實(shí)現(xiàn)增刪改查的呢?我們這里已增加數(shù)據(jù)為例,其余同理辫塌,可查看源碼:
從SingerDao的源碼我們可以看到它是繼承自AbstractDao漏策。我們來粗略的看一下內(nèi)部進(jìn)行了怎樣實(shí)現(xiàn)的。

public abstract class AbstractDao<T, K> {
    public long insert(T entity) {
        return executeInsert(entity, statements.getInsertStatement(), true);
    }
}

public class TableStatements {
    public DatabaseStatement getInsertStatement() {
        if (insertStatement == null) {
            //sql語(yǔ)句的拼接
            String sql = SqlUtils.createSqlInsert("INSERT INTO ", tablename, allColumns);
            DatabaseStatement newInsertStatement = db.compileStatement(sql);
            synchronized (this) {
                if (insertStatement == null) {
                    insertStatement = newInsertStatement;
                }
            }
            if (insertStatement != newInsertStatement) {
                newInsertStatement.close();
            }
        }
        return insertStatement;
    }
}

public class SqlUtils {
    public static String createSqlInsert(String insertInto, String tablename, String[] columns) {
        StringBuilder builder = new StringBuilder(insertInto);
        builder.append('"').append(tablename).append('"').append(" (");
        appendColumns(builder, columns);
        builder.append(") VALUES (");
        appendPlaceholders(builder, columns.length);
        builder.append(')');
        return builder.toString();
    }
}

我們會(huì)發(fā)現(xiàn)臼氨,到最后掺喻,他還是將所有的參數(shù)拼成了一句添加的sql。GreenDao的內(nèi)部都已經(jīng)幫你實(shí)現(xiàn)好了储矩。而我們?cè)谕獠恐恍枰?jiǎn)單的調(diào)用一句即可感耙。
singerDao.insert(new Singer(null, "周杰倫", "男", "中國(guó)"));

4.GreenDao的簡(jiǎn)單操作

①在Application中的配置

public class MyApplication extends Application {

    public static final String TAG = MyApplication.class.getSimpleName();
    private static Context mContext;
    public SQLiteDatabase db;
    public DaoSession daoSession;
    public DaoMaster.DevOpenHelper helper;
    public DaoMaster daoMaster;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        setupDatabase();
    }

    /**數(shù)據(jù)庫(kù)的配置*/
    private void setupDatabase() {
        //此處的Helper可自定義
        helper = new DaoMaster.DevOpenHelper(this, "green_dao_demo.db", null);
        db = helper.getWritableDatabase();
        // 注意:該數(shù)據(jù)庫(kù)連接屬于 DaoMaster,所以多個(gè) Session 指的是相同的數(shù)據(jù)庫(kù)連接持隧。
        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }

    public static Context getContext() {
        return mContext;
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }
}

②獲取Dao對(duì)象

    SingerDao singerDao = ((MyApplication) getActivity()
                    .getApplicationContext())
                    .getDaoSession()
                    .getSingerDao();

-添加數(shù)據(jù)

           Singer singer = new Singer(null, name, age, country);
            singerDao.insert(singer);

-查詢數(shù)據(jù)

    public List<Singer> getSingerList(String country) {
        if (!TextUtils.isEmpty(country)) {
            List<Singer> singers = getSingerDao()       
                    .queryBuilder()
                    .where(SingerDao.Properties.Country.eq(country))  //判斷條件
                    .orderDesc()                                     //排序順序
                    .build()
                    .list();                                     //生成對(duì)應(yīng)的list
            return singers;
        }
        return null即硼;
      }

-更新數(shù)據(jù)

        //通過主鍵更新數(shù)據(jù)
        singerDao.update(new Singer(Loing.valueOf(id),name, sex, country));
        //常規(guī)更新
        singer.setName(name);
        singer.setSex(sex);
        singer.setCountry(country);
        singerDao.update(singer);

-刪除數(shù)據(jù)

   //通過主鍵刪除
  singerDao.deleteByKey(Long.valueOf(singer.getId()));
   //常規(guī)刪除
  singerDao.delete(singer);

-批量操作

  singerDao.insertInTx(singers); // 批量添加
 singerDao.updateInTx(singers); // 批量更新
singerDao.deleteInTx(singers); //批量刪除

項(xiàng)目示例地址

https://github.com/HandGrab/GreenDaoDemo

參考:
GreenDao官網(wǎng):http://greenrobot.org/greendao/
GreenDao部分源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市屡拨,隨后出現(xiàn)的幾起案子只酥,更是在濱河造成了極大的恐慌,老刑警劉巖呀狼,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裂允,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡哥艇,警方通過查閱死者的電腦和手機(jī)绝编,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人十饥,你說我怎么就攤上這事怎棱。” “怎么了绷跑?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵拳恋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我砸捏,道長(zhǎng)谬运,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任垦藏,我火速辦了婚禮梆暖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掂骏。我一直安慰自己轰驳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布弟灼。 她就那樣靜靜地躺著级解,像睡著了一般。 火紅的嫁衣襯著肌膚如雪田绑。 梳的紋絲不亂的頭發(fā)上勤哗,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音掩驱,去河邊找鬼芒划。 笑死,一個(gè)胖子當(dāng)著我的面吹牛欧穴,可吹牛的內(nèi)容都是我干的民逼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涮帘,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拼苍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起焚辅,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤映屋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后同蜻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡早处,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年湾蔓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砌梆。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡默责,死狀恐怖贬循,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桃序,我是刑警寧澤杖虾,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站媒熊,受9級(jí)特大地震影響奇适,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芦鳍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一嚷往、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柠衅,春花似錦皮仁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至喝峦,卻和暖如春付燥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愈犹。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工键科, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人漩怎。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓勋颖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親勋锤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饭玲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一、關(guān)于greenDAO greenDAO應(yīng)該算是當(dāng)前最火的數(shù)據(jù)庫(kù)開源框架了叁执,它是一個(gè)將對(duì)象映射到SQLite數(shù)據(jù)...
    當(dāng)幸福來敲門58閱讀 13,870評(píng)論 3 19
  • (一)GreenDao簡(jiǎn)介 GreenDao是一個(gè)對(duì)象關(guān)系映射(ORM)的開源框架茄厘,目前最主流的安卓數(shù)據(jù)庫(kù)操作框架...
    miss2008閱讀 5,243評(píng)論 4 18
  • GreenDao 介紹:greenDAO是一個(gè)對(duì)象關(guān)系映射(ORM)的框架,能夠提供一個(gè)接口通過操作對(duì)象的方式去操...
    小董666閱讀 732評(píng)論 0 1
  • 前言 最近的項(xiàng)目需要使用到數(shù)據(jù)庫(kù)谈宛,本來想用Sqlite數(shù)據(jù)來做的次哈,但是聽同事說使用Greendao數(shù)據(jù)庫(kù)是真的好用...
    Smile__EveryDay閱讀 3,616評(píng)論 2 7
  • iOS開發(fā)中應(yīng)用的橫豎屏在項(xiàng)目中就可以設(shè)置App支持的旋轉(zhuǎn)方向,這是全局控制的一種方法,代碼的實(shí)現(xiàn)是以下三個(gè)方法:...
    輕云_閱讀 3,439評(píng)論 1 4