Android SQLite使用

1袱蚓、SQLite的使用要緊抓SQLiteOpenHelper

SQLiteOpenHelper是一個輔助類蚓曼,管理數(shù)據(jù)庫(創(chuàng)建、增嗽桩、修兔乞、刪) & 版本的控制汇鞭。
在實際開發(fā)中,為了能夠更好的管理和維護數(shù)據(jù)庫报嵌,我們會封裝一個繼承自SQLiteOpenHelper類的數(shù)據(jù)庫操作類虱咧,然后以這個類為基礎(chǔ),再封裝我們的業(yè)務(wù)邏輯方法锚国。

方法名 作用
onCreate() 創(chuàng)建數(shù)據(jù)庫
onUpgrade() 升級數(shù)據(jù)庫
close() 關(guān)閉所有打開的數(shù)據(jù)庫對象
execSQL() 可進行增刪改操作, 不能進行查詢操作
query()腕巡、rawQuery() 查詢數(shù)據(jù)庫
insert() 插入數(shù)據(jù)
delete() 刪除數(shù)據(jù)
getWritableDatabase() 創(chuàng)建或打開可以讀/寫的數(shù)據(jù)庫
getReadableDatabase() 創(chuàng)建或打開可讀的數(shù)據(jù)庫

2、SQLite使用

2.1血筑、特別注意

2.1.1绘沉、對于“增、刪豺总、改”這類操作车伞,首先調(diào)用getWritableDatabase()獲得一個可讀寫數(shù)據(jù)庫的對象,然后在調(diào)用通用的execSQL(String sql) 或?qū)?yīng)的操作API方法:insert()喻喳、delete()另玖、update()
2.1.2、對“查”表伦,首先調(diào)用getReadableDatabase()獲得一個可讀的數(shù)據(jù)庫對象谦去,然后使用query()或rawQuery()方法查詢數(shù)據(jù)庫不能使用execSQL方法

2.2、創(chuàng)建數(shù)據(jù)庫

MySQLiteHelper .java

public class MySQLiteHelper extends SQLiteOpenHelper {

   public MySQLiteHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
      super(context, name, factory, version);
   }

  /**
   * 第一次創(chuàng)建數(shù)據(jù)庫的時候回調(diào)該方法
   * 當使用getReadableDatabase()方法獲取數(shù)據(jù)庫實例的時候, 如果數(shù)據(jù)庫不存在, 就會調(diào)用這個方法;
   * @param db
   */
   @Override
   public void onCreate(SQLiteDatabase db) {
      String sql = "create table user(name varchar(10))";
      //execSQL用于執(zhí)行SQL語句完成數(shù)據(jù)庫的創(chuàng)建
      db.execSQL(sql);
      //數(shù)據(jù)庫實際上是沒有被創(chuàng)建或者打開蹦哼,
      //直到getWritableDatabase() 或者 getReadableDatabase() 方法中的一個被調(diào)用時才會進行創(chuàng)建或者打開
   }

   @Override
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      //這里是更新數(shù)據(jù)庫的
   }
}

因為我的操作比較多鳄哭,我特意創(chuàng)建了一個控制類,如果嫌麻煩可以直接在Activity中操作
DataBaseControl.java

public class DataBaseControl {
    private String DbName = "bd.db";

    public DataBaseControl(Context context) {
        MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
        //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
        SQLiteDatabase database = mySqliteHelper.getWritableDatabase();
        //SQLiteDatabase database = mySqliteHelper.getReadableDatabase();
    }
}
2.3纲熏、插入數(shù)據(jù)

因為要寫入數(shù)據(jù)所以需要使用讀寫功能的getWritableDatabase()
插入數(shù)據(jù)可以使用insert()也可以使用excelSQL()
DataBaseControl.java

public DataBaseControl(Context context) {
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();

    //創(chuàng)建ContentValues對象
    //注:ContentValues內(nèi)部實現(xiàn)就是HashMap妆丘,但是兩者還是有差別的
    //ContentValues Key只能是String類型,Value只能存儲基本類型數(shù)據(jù)局劲,不能存儲對象
    ContentValues values = new ContentValues();
    // 向該對象中插入鍵值對
    values.put("name", "張三");

    // 調(diào)用insert()方法將數(shù)據(jù)插入到數(shù)據(jù)庫
    // 第一個參數(shù):要操作的表名稱
    // 第二個參數(shù):SQl不允許一個空列勺拣,如果ContentValues是空的,那么這一列被明確的指明為NULL值
    // 第三個參數(shù):ContentValues對象
    database.insert("user", null, values);

    //也可以直接使用下面方法
    //database.execSQL("insert into user (name) values ('張三')");
}
2.4鱼填、刪除數(shù)據(jù)

刪除數(shù)據(jù)也需要使用getWritableDatabase()
刪除可使用delete()也可以使用excelSQL()
DataBaseControl.java

 public DataBaseControl(Context context) {
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();

    //調(diào)用delete方法進行刪除操作
    //第一個參數(shù)String:需要操作的表名
    //第二個參數(shù)String:where選擇語句, 選擇哪些行要被刪除, 如果為null, 就刪除所有行;
    //第三個參數(shù)String[]: where語句的參數(shù), 逐個替換where語句中的 "?" 占位符;
    database.delete("user", "id=?", new String[]{"1"});

    //也可以直接使用下面方法
    //database.execSQL("DELETE FROM user WHERE name = '張三'");
}
2.5宣脉、修改數(shù)據(jù)

修改數(shù)據(jù)需要使用getWritableDatabase()
修改數(shù)據(jù)可用update()也可以使用execSQL()
DataBaseControl.java

public DataBaseControl(Context context) {
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();
    
    // 創(chuàng)建一個ContentValues對象
    ContentValues values = new ContentValues();
    values.put("name", "李四");

    // 調(diào)用update方法修改數(shù)據(jù)庫
    // 第一個參數(shù)String:表名
    // 第二個參數(shù)ContentValues:ContentValues對象(需要修改的)
    // 第三個參數(shù)String:WHERE表達式,where選擇語句, 選擇那些行進行數(shù)據(jù)的更新, 如果該參數(shù)為 null, 就會修改所有行;剔氏?號是占位符
    // 第四個參數(shù)String[]:where選擇語句的參數(shù), 逐個替換 whereClause 中的占位符;
    database.update("user", values, "id=?", new String[]{"1"});

    //也可以直接使用下面方法
    //database.execSQL("UPDATE user SET name = '李四' WHERE id=1");
}
2.6塑猖、查詢數(shù)據(jù)

查詢數(shù)據(jù)只需要可讀就行所以使用getReadableDatabase()竹祷,當然如果你的操作不僅僅是查詢的話還是建議使用getWritableDatabase()
然后使用query() 或 rawQuery()
DataBaseControl.java

    //distinct可以指定“true”或“false”表示要不要過濾重復(fù)值
    //table:要操作的表明
    //columns:查詢的列所有名稱集
    //selection:WHERE之后的條件語句,可以使用占位符
    //groupBy:指定分組的列名
    //having指定分組條件羊苟,配合groupBy使用
    //orderBy指定排序的列名
    //limit指定分頁參數(shù)
    database.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

    //這種最簡單 直接使用SQL語句  selectionArgs(占位符代替實際參數(shù))可以直接填null
    database.rawQuery(String sql, String[] selectionArgs);

    //所有查詢都會返回一個Cursor對象
    //Cursor對象常用方法如下:
    cursor.move(int offset); //以當前位置為參考,移動到指定行
    cursor.moveToFirst();    //移動到第一行
    cursor.moveToLast();     //移動到最后一行
    cursor.moveToPosition(int position); //移動到指定行
    cursor.moveToPrevious(); //移動到前一行
    cursor.moveToNext();     //移動到下一行
    cursor.isFirst();        //是否指向第一條
    cursor.isLast();     //是否指向最后一條
    cursor.isBeforeFirst();  //是否指向第一條之前
    cursor.isAfterLast();    //是否指向最后一條之后
    cursor.isNull(int columnIndex);  //指定列是否為空(列基數(shù)為0)
    cursor.isClosed();       //游標是否已關(guān)閉
    cursor.getCount();       //總數(shù)據(jù)項數(shù)
    cursor.getPosition();    //返回當前游標所指向的行數(shù)
    cursor.getColumnIndex(String columnName);//返回某列名對應(yīng)的列索引值
    cursor.getString(int columnIndex);   //返回當前行指定列的值

具體的使用如下:
DataBaseControl.java

public DataBaseControl(Context context) {
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();

    // 第一個參數(shù)String:表名
    // 第二個參數(shù)String[]:要查詢的列名
    // 第三個參數(shù)String:查詢條件
    // 第四個參數(shù)String[]:查詢條件的參數(shù)
    // 第五個參數(shù)String:對查詢的結(jié)果進行分組
    // 第六個參數(shù)String:對分組的結(jié)果進行限制
    // 第七個參數(shù)String:對查詢的結(jié)果進行排序
    Cursor cursor = database.query("user", new String[] {"name" }, "id=?",
            new String[] { "1" }, null, null, null);
    //利用光標移動塑陵,判斷結(jié)果集是否還有下一條數(shù)據(jù)
    while (cursor.moveToNext()) {
        name = cursor.getString(cursor.getColumnIndex("name"));
    }
    cursor.close();//記得一定關(guān)閉它哦

    //---------------------------------------------------------------------------        

    //rawQuery直接傳入SQL就好
    Cursor cursor = database.rawQuery(sql, null);
    for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
        list.add(new user(cursor.getInt(0), cursor.getString(1)));
    }
    cursor.close();//記得一定關(guān)閉它哦

    //在此說明上下兩種遍歷方式都可以使用,當然也有其他方式蜡励,具體用什么方式看個人習(xí)慣
}
2.7令花、數(shù)據(jù)庫更新

MySQLiteHelper.java

//數(shù)據(jù)庫版本號
private static final int DATABASE_VERSION = 1;

//oldVersion : 舊版本數(shù)據(jù)庫
//newVersion : 新版本數(shù)據(jù)庫
//注意:這里的刪除等操作必須要保證新的版本必須要比舊版本的版本號要大才行。
//[即 Version 2.0 > Version 1.0 ] 所以這邊我們不需要對其進行操作凉倚。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //這里是更新數(shù)據(jù)庫的
}

DataBaseControl.java

public DataBaseControl(Context context) {
    //創(chuàng)建SQLiteOpenHelper子類對象的時候,必須傳入一個version參數(shù)
    //該參數(shù)就是當前數(shù)據(jù)庫版本, 只要這個版本高于之前的版本, 就會觸發(fā)這個onUpgrade()方法兼都,如下面代碼
    //注意,一定要傳入最新的數(shù)據(jù)庫版本號
    //傳入版本號為2稽寒,大于舊版本(1)扮碧,所以會調(diào)用onUpgrade()升級數(shù)據(jù)庫
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 2);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();
}
2.8、關(guān)閉數(shù)據(jù)庫

DataBaseControl.java

public DataBaseControl(Context context) {
    MySQLiteHelper mySqliteHelper = new MySQLiteHelper(context, DbName, null, 1);
    //調(diào)用getReadableDatabase()或getWritableDatabase()才算真正創(chuàng)建或打開數(shù)據(jù)庫
    SQLiteDatabase database = mySqliteHelper.getWritableDatabase();

    //關(guān)閉當前數(shù)據(jù)庫
    database.close();
}

3杏糙、個人建議

個人建議都是用SQL語句慎王,SQL語句比較通用,insert()宏侍、delete()赖淤、query()方法參數(shù)多,使用復(fù)雜

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谅河,一起剝皮案震驚了整個濱河市咱旱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绷耍,老刑警劉巖莽龟,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锨天,居然都是意外死亡,警方通過查閱死者的電腦和手機剃毒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門病袄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赘阀,你說我怎么就攤上這事益缠。” “怎么了基公?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵幅慌,是天一觀的道長。 經(jīng)常有香客問我轰豆,道長胰伍,這世上最難降的妖魔是什么齿诞? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮骂租,結(jié)果婚禮上祷杈,老公的妹妹穿的比我還像新娘。我一直安慰自己渗饮,他們只是感情好但汞,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著互站,像睡著了一般私蕾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胡桃,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天踩叭,我揣著相機與錄音,去河邊找鬼标捺。 笑死懊纳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的亡容。 我是一名探鬼主播嗤疯,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闺兢!你這毒婦竟也來了茂缚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤屋谭,失蹤者是張志新(化名)和其女友劉穎脚囊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桐磁,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡悔耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了我擂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衬以。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖校摩,靈堂內(nèi)的尸體忽然破棺而出看峻,到底是詐尸還是另有隱情,我是刑警寧澤衙吩,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布互妓,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冯勉。R本人自食惡果不足惜澈蚌,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望珠闰。 院中可真熱鬧惜浅,春花似錦、人聲如沸伏嗜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽承绸。三九已至裸影,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間军熏,已是汗流浹背轩猩。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留荡澎,地道東北人均践。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像摩幔,于是被迫代替她去往敵國和親彤委。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

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