Android SQLite詳解

在項(xiàng)目開發(fā)中,我們或多或少都會用到數(shù)據(jù)庫。在Android中,我們一般使用SQLite,因?yàn)锳ndroid在android.database.sqlite包封裝了很多SQLite操作的API。我自己寫了一個(gè)Demo來總結(jié)SQLite的使用,托管在Github上,大家可以點(diǎn)擊下載APK,也可以點(diǎn)擊下載源碼。Demo截圖如下:

在使用SQLite時(shí),我建議先下載一個(gè)本地SQLite客戶端來驗(yàn)證操作,在本地寫的SQL語句運(yùn)行正確后,再轉(zhuǎn)移到Android中。我用的是SQLite Expert Personal。
首先創(chuàng)建一個(gè)繼承在SQLiteOpenHelper的類,并重寫onCreate()onUpgrade()方法。

public class OrderDBHelper extends SQLiteOpenHelper{
    private static final int DB_VERSION = 1;
    private static final String DB_NAME = "myTest.db";
    public static final String TABLE_NAME = "Orders";

    public OrderDBHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        // create table Orders(Id integer primary key, CustomName text, OrderPrice integer, Country text);
        String sql = "create table if not exists " + TABLE_NAME + " (Id integer primary key, CustomName text, OrderPrice integer, Country text)";
        sqLiteDatabase.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;
        sqLiteDatabase.execSQL(sql);
        onCreate(sqLiteDatabase);
    }
}

這個(gè)類主要用于建數(shù)據(jù)庫和建表用,我們再創(chuàng)建一個(gè)OrderDao用于處理所有的數(shù)據(jù)操作方法。在OrderDao鐘實(shí)例化OrderDBHelper:

public OrderDao(Context context) {
    this.context = context;
    ordersDBHelper = new OrderDBHelper(context);
}

數(shù)據(jù)庫操作無外乎:“增刪查改”。對于“增刪改”這類對表內(nèi)容變換的操作,我們需先調(diào)用getWritableDatabase(),在執(zhí)行的時(shí)候可以調(diào)用通用的execSQL(String sql)方法或?qū)?yīng)的操作API:insert()、delete()、update()。而對“查”,需要調(diào)用getReadableDatabase(),這時(shí)就不能使用execSQL方法了,得使用query()rawQuery()方法。下面開始一一介紹。

增加數(shù)據(jù)

在我的Demo中,有兩種增加數(shù)據(jù)操作:
初始化數(shù)據(jù)
在進(jìn)入Demo程序時(shí),先判斷表中是否有數(shù)據(jù),如果表中沒有數(shù)據(jù),我將先添加一些數(shù)據(jù)。在初始化數(shù)據(jù)時(shí),因?yàn)橐淮涡砸砑拥臄?shù)據(jù)比較多,所以我直接采用的是execSQL方法:

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();

db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (1, 'Arc', 100, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (2, 'Bor', 200, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (3, 'Cut', 500, 'Japan')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (4, 'Bor', 300, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (5, 'Arc', 600, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (6, 'Doom', 200, 'China')");

db.setTransactionSuccessful();

插入一條新數(shù)據(jù)
我們還可以使用insert(String table,String nullColumnHack,ContentValues values)方法來插入,ContentValues內(nèi)部實(shí)現(xiàn)就是HashMap,但是兩者還是有差別的,ContenValues Key只能是String類型,Value只能存儲基本類型的數(shù)據(jù),像string,int之類的,不能存儲對象這種東西:

public ContentValues() {
    // Choosing a default size of 8 based on analysis of typical
    // consumption by applications.
    mValues = new HashMap<String, Object>(8);
}

使用insert()方法我們插入一條新數(shù)據(jù)(7, "Jne", 700, "China"),對于修改數(shù)據(jù)的操作我們一般當(dāng)作事務(wù)(Transaction)處理:

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();

// insert into Orders(Id, CustomName, OrderPrice, Country) values (7, "Jne", 700, "China");
ContentValues contentValues = new ContentValues();
contentValues.put("Id", 7);
contentValues.put("CustomName", "Jne");
contentValues.put("OrderPrice", 700);
contentValues.put("Country", "China");
db.insertOrThrow(OrderDBHelper.TABLE_NAME, null, contentValues);

db.setTransactionSuccessful();

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

刪除數(shù)據(jù)的方法除了execSQL還有delete(String table,String whereClause,String[] whereArgs),whereClause是刪除條件,whereArgs是刪除條件值數(shù)組。

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();

// delete from Orders where Id = 7
db.delete(OrderDBHelper.TABLE_NAME, "Id = ?", new String[]{String.valueOf(7)});
db.setTransactionSuccessful();

再看刪除的源碼,里面會拼裝刪除條件和刪除條件值數(shù)組:

public int delete(String table, String whereClause, String[] whereArgs) {
    acquireReference();
    try {
        SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
                (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
        try {
            return statement.executeUpdateDelete();
        } finally {
            statement.close();
        }
    } finally {
        releaseReference();
    }
}

修改數(shù)據(jù)

修改數(shù)據(jù)和插入數(shù)據(jù)很相似,調(diào)用的方法除了execSQL還可以是update(String table,ContentValues values,String whereClause, String[] whereArgs)

db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();

// update Orders set OrderPrice = 800 where Id = 6
ContentValues cv = new ContentValues();
cv.put("OrderPrice", 800);
db.update(OrderDBHelper.TABLE_NAME,
        cv,
        "Id = ?",
        new String[]{String.valueOf(6)});
db.setTransactionSuccessful();

查找數(shù)據(jù)

查找數(shù)據(jù)有兩個(gè)方法,一是public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);,另外一個(gè)是public Cursor rawQuery(String sql, String[] selectionArgs)rawQuery的寫法類似上面的execSQL,在此不做介紹,query方法中的參數(shù)如下:

  • table:表名稱
  • columns:列名稱數(shù)組
  • selection:條件字句,相當(dāng)于where
  • selectionArgs:條件字句,參數(shù)數(shù)組
  • groupBy:分組列
  • having:分組條件
  • orderBy:排序列
  • limit:分頁查詢限制
  • Cursor:返回值,相當(dāng)于結(jié)果集ResultSet

我們可以看到返回的類型都是Cursor,Cursor是一個(gè)游標(biāo)接口,提供了遍歷查詢結(jié)果的方法,如移動指針方法move(),獲得列值方法。Cursor游標(biāo)常用方法如下:

我們先來查一查用戶名為"Bor"的信息:

db = ordersDBHelper.getReadableDatabase();

// select * from Orders where CustomName = 'Bor'
cursor = db.query(OrderDBHelper.TABLE_NAME,
        ORDER_COLUMNS,
        "CustomName = ?",
        new String[] {"Bor"},
        null, null, null);

if (cursor.getCount() > 0) {
    List<Order> orderList = new ArrayList<Order>(cursor.getCount());
    while (cursor.moveToNext()) {
        Order order = parseOrder(cursor);
        orderList.add(order);
    }
    return orderList;
}

當(dāng)然我們也可以查詢總數(shù)、最大值最小值之類的,以查詢Country為China的用戶總數(shù)為例:

db = ordersDBHelper.getReadableDatabase();
// select count(Id) from Orders where Country = 'China'
cursor = db.query(OrderDBHelper.TABLE_NAME,
        new String[]{"COUNT(Id)"},
        "Country = ?",
        new String[] {"China"},
        null, null, null);

if (cursor.moveToFirst()) {
    count = cursor.getInt(0);
}

至此SQLite就介紹完了,大家可以下載Demo詳細(xì)查看。Demo中還有一些其他比較干貨的東西,大家可以挖掘挖掘。當(dāng)然Demo中也有些不足,我還會更新,盡量做到讓用戶通過Demo就能學(xué)會如何使用SQLite。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • LZ-Says:給大家推薦一個(gè)網(wǎng)站,有興趣可以查閱,想為大家貢獻(xiàn)一點(diǎn)自己的力量也可以投稿,老大審核通過會發(fā)表,更好...
    靜心Study閱讀 1,070評論 0 3
  • 2017年5月17日 Kylin_Wu 標(biāo)注(★☆)為考綱明確給出考點(diǎn)(必考) 常見手機(jī)系統(tǒng)(★☆) And...
    Azur_wxj閱讀 1,959評論 0 10
  • 讀經(jīng)日記第16篇 2016年8月8日 星期一陣雨 系統(tǒng)讀經(jīng)第三周第6天 讀經(jīng)內(nèi)容: 《易經(jīng) 上經(jīng)》需卦第五,訟卦...
    May137閱讀 212評論 0 0
  • “姥姥說的話就是你小時(shí)候不愿意聽,長大了想聽,卻再也聽不到的,那些話?!? “姥姥的話,嘮叨,但那是...
    李小佳閱讀 1,217評論 2 3
  • “謙虛吧,你就。有才能的人總是不承認(rèn)他有才,就好比美女都不說她是美女。我就不是美女。嘿嘿……” 那丫頭竟然反將一軍...
    東南萌閱讀 419評論 12 2

友情鏈接更多精彩內(nèi)容