1. 程式人生 > >Android複習之旅--SQLite

Android複習之旅--SQLite

SQLite的知識點實在是太多了,將其一一整理出來可能會耗費太多時間,實在抱歉,或許以後會推出關於SQLite的其它知識點。在此只整理出SQLite的增刪改查還有事務處理,並將它們封裝到方法中,便於閱讀。

SQLite簡介
SQLite是一個輕量級資料庫,支援SQL語言、事務處理等功能。SQLite沒有伺服器程序,它通過檔案儲存資料,該檔案是跨平臺的,可以放在其他平臺中使用。

SQLite支援NULL、INTEGER、REAL(浮點數)、TEXT(字串)和BLOB(二進位制物件,1為true,0為false)5種資料型別。

但實際上SQLite也接收varchar(n)、char(n)、decimal(p,s)等資料型別,只不過在運算或儲存時會轉換成對應的5種資料型別。因此可以將各種型別的資料儲存到任何欄位中,而不用關心欄位宣告的資料型別。這也是SQLite資料庫的最大特點。

資料庫檔案儲存的位置

/data/data//databases/xxx.db
資料庫在建立的時候預設會建立一張表(metadata.db)來儲存系統語言環境

資料庫增刪改查的SQL語句

  • 增加:insert into 表名(欄位名,…) values(值,…)
  • 刪除:delete from 表名 where 條件
  • 更新:update 表名 set 欄位名=值,… where 條件
  • 查詢:select 欄位名 from 表名 where 條件

新增約束

在資料庫表中,往往會給某些欄位新增約束來滿足特定的需求

  • 主鍵:primary key (欄位 … primary key)
  • 外來鍵:references (欄位 … references data2 (主鍵))
  • 非空:not null(欄位 … not null)
  • 唯一:unique (欄位 … unique)
  • 預設值:default (欄位 … default 預設值)

SQLiteOpenHelper類的常用方法

這是一個抽象類,該類用於建立資料庫和資料庫版本更新。需要建立新的類來繼承

void onCreate(SQLiteDatabase db);  //建立資料庫時呼叫,子類必須過載此方法
void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);  //資料庫版本更新時呼叫,子類必須過載此方法
SQLiteDatabase getReadableDatabase();  //建立或開啟一個只讀的資料庫
SQLiteDatabase getWritableDatabase();  //建立或開啟一個讀寫的資料庫

SQLiteDatabase類的常用方法

  • 執行帶佔位符的SQL語句實現增刪改查

    /** 帶佔位符的SQL語句;條件值  */
    void execSQL(String sql, Object[] bindArgs); 
    
    /** 帶佔位符的SQL語句;條件值  */
    Curosr rawQuery(String sql, String[] selectionArgs); 
    
  • 或呼叫API中的方法實現增刪改查

    /** 表名;一般為null即可;新增的內容*/
    long insert(String table, String nullColumnHack, ContentValues values); // -1為新增失敗
    
    /** 表名;條件;條件值*/
    int delete(String table, String whereClause, String[] whereArgs); // 返回受影響的行數
    
    /** 表名;修改的內容;條件;條件值*/
    int update(String table, ContentValues values, String whereClause, String[] whereArgs); // 返回受影響的行數
    
    /** 表名;返回的列;條件;條件值;group by;having;order by */
    Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy); //返回結果集
    
    void close();  //關閉資料庫
    

兩種增刪改查的優缺點

  • 自己寫sql語句
    • 靈活
    • 資源佔用小
    • 可以實現表的級聯查詢
  • google的現成API
    • 方便
    • 資源開銷比較大
    • 有返回值

Cursor介面的常用方法

Cursor是一個遊標介面,在資料庫操作中返回值,相當於結果集ResultSet

boolean moveToNext(); //移動游標到下一行
boolean moveToFirst(); //移動游標到第一行
boolean moveToPosition(int position); //移動游標到指定位置
int getCount();  //返回Cursor中的行數
int getPosition();  //返回當前Cursor的位置

int getColumnIndex(String columnName);  //返回指定列的索引值,如不存在則返回-1
int getInt(int columnIndex);  //返回指定列的整數值
String getString(int columnIndex);  //返回指定列的字串

資料庫的常用操作

建立一個類繼承自SQLiteOpenHelper,複寫父類的方法

public class PersonDBOpenHelper extends SQLiteOpenHelper {

    public PersonDBOpenHelper(Context context) {
        //上下文,資料庫名稱,遊標工廠(預設為null即可),版本號
        super(context, "rixin", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // 建立SQLite資料表(資料庫第一次建立時呼叫)
        db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20),age integer)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 資料庫的版本升級時呼叫
        Log.w("info", "資料庫升級了");
    }
}

例項化資料庫類

PersonDBOpenHelper helper = new PersonDBOpenHelper(this);

新增記錄

/**
 * 新增記錄
 * name:要新增記錄中的某個欄位名
 * age:要新增記錄中的某個欄位名
 */
public void insertRecord(String name, int age) {
    SQLiteDataBase db = helper.getWritableDatabase(); // 開啟一個讀寫的資料庫
    // db.execSQL("insert into info(name,age) values(?,?)", new String[]{name, age});

    ContentValues values = new ContentValues();
    values.put("name", name);
    values.put("age", age);
    long i = db.insert("info", null, values);
    if (i == -1) {
        Toast.makeText(this, "新增記錄失敗", 0).show();
    } esle {
        Toast.makeText(this, "新增記錄成功", 0).show();
    }
    db.close();
}

刪除記錄

/**
 * 刪除記錄
 * name:要刪除的記錄中的某個欄位名
 */
public void deleteRecord(String name) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 開啟一個只讀的資料庫
    // db.execSQL("delete from info where name=?", new String[]{name});

    int i = db.delete("info", "name=?", new String[]{name});
    if (i == 0) {
        Toast.makeText(this, "刪除記錄失敗", 0).show();
    } else {
        Toast.makeText(this, "刪除記錄成功", 0).show();
    }
    db.close();
}

更新記錄

/** 
 * 更新記錄
 * name:以name欄位查詢記錄
 * age:要修改的欄位
 */
public void updateRecord(String name, int age) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 開啟一個只讀的資料庫
    // db.execSQL("update info set age=? where name=?", new String[]{age, name});

    ContentValues values = new ContentValues();
    values.put("age", age);
    int i = db.update("info", values, "name=?", new String[]{name});
    if (i == 0) {
        Toast.makeText(this, "更新記錄失敗", 0).show();
    } else {
        Toast.makeText(this, "更新記錄成功", 0).show();
    }
    db.close();
}

查詢記錄

/**
 * 查詢記錄
 * name:以name欄位值查詢記錄
 */
public void queryRecord(String name) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 開啟一個只讀的資料庫
    //得到資料庫查詢的結果集的遊標(指標)

    // Cursor cursor = db.rawQuery("select * from info", null); //查詢全部記錄
    // Cursor cursor = db.rawQuery("select age from info where name=?", new String[]{name});

    // Cursor cursor = db.query("info", null, null, null, null, null, null);
    Cursor cursor = db.query("info", new String[]{"age"}, "name=?", new String[]{name}, null, null, null);
    List<HashMap<String,int>> list = new ArrayList<HashMap<String,int>>();
    while (cursor.moveToNext()) {
        HashMap<String,int> hm = new HashMap<String,int>();
        hm.put("name", cursor.getString(cursor.getColumnIndex("name")));
        hm.put("age", cursor.getInt(cursor.getColumnIndex("age")));
        list.add(hm);
        hm = null;
    }
    cursor.close();
    db.close();
}

事務操作(銀行轉賬等相關需要同步操作資料庫的事務)

public void execTransaction(String name1, String name2) {
    SQLiteDatabase db = helper.getWritableDatabase();
    db.beginTransaction();
    try {
        // 轉賬
        db.execSQL("update info set money=money-100 where name =?", new String[]{name1});
        // 收到轉賬
        db.execSQL("update info set money=money+100 where name =?", new String[]{name2});
        // 標識事務執行成功,如果沒有執行下面的程式碼,資料會回滾
        db.setTransactionSuccessful();
    } catch(Exception ex) {
        ex.printStackTrace();
        Log.i("rixin", "事務處理失敗");
    } finally {
        db.endTransaction(); //關閉事務
        db.close();  //關閉資料庫
    }
}

值得注意的是:操作完資料庫後要記得關閉資料庫,使用完Cursor物件後,也應及時關閉,否則會造成記憶體洩漏

利用sqlite3工具檢視資料庫的內容

sqlite3 xxx.db (進去後輸入sql語句查詢即可)

如果出現中文亂碼 需要修改cmd的編碼集,預設是gb2312

chcp 65001 (更改cmd視窗的編碼的DOS命令,65001是utf-8)

adb shell   (掛載到Linux的空間)
cd data/data/<packagename>/databases  (進入應用的databases目錄下)
ls -l  (列出當前目錄下的所有檔案的詳細資訊)
sqlite3 xxx.db  
select * from info;  (SQL語句查詢,記得加上分號" ; "結束)

如果覺得使用命令來檢視資料庫表麻煩,也可以google搜尋下載可以檢視SQLite資料庫的軟體。匯出資料庫檔案到電腦後即可使用軟體來檢視資料庫裡面的資訊。

希望以上的內容對你們有所幫助吧