Android SQLite, KopDB 架構學習1——使用

來源:互聯網
上載者:User

標籤:android   sqlite   database   

前言

我的部落格:http://mrfufufu.github.io/
最近項目中要用到資料庫,因為之前需要本機存放區的資料量並不是非常大,SharedPreferences 足以解決大部分的資料存放區問題,所以,我們一直沒有用到 SQLite。現在產品需要最佳化私信模組體驗,所以增加私信本機存放區是非常必要的。這時候用上 SQLite 就非常必要了。好在我們的老大之前就已經封裝好了一份非常完善的資料庫架構了,拿來就能用。看了源碼研究了一天,大概有了寫心得體會,整理出來,學習使用。

就給他起名叫 KopDB 吧(Kop 是我們老大打 log 的時候用的 tag),KopDB 採用的是對象關係映射(ORM)的模式,並將我們平時開發時最常用到的一些資料庫功能進行了封裝,使得不用編寫一行SQL語句就可以完成各種建表、増刪改查的操作。

這篇文章主要講的只是 KopDB 的使用,具體分析我會在下篇文章中。

Github 項目地址,裡麵包含了 lib 和對應的 demo,歡迎 Star

https://github.com/MrFuFuFu/KopDB.git

主要的使用方式非常簡單:

先給出 demo 中的資料 model 模型方便後面閱讀理解:

public class PersonModel extends BaseModel {    private static final long serialVersionUID = 3462436436344054489L;    public static final String PERSON_ID = "person_id";    public static final String PERSON_NAME = "person_name";    public static final String PERSON_AGE = "person_age";    public static final String PERSON_ADDRESS = "person_address";    public static final String PERSON_PHONE = "person_phone";    @DatabaseField(columnName = PERSON_ID, index = true, unique = true, canBeNull = false)    public int id;    @DatabaseField(columnName = PERSON_NAME)    public String name;    @DatabaseField(columnName = PERSON_AGE)    public String age;    @DatabaseField(columnName = PERSON_ADDRESS)    public String address;    @DatabaseField(columnName = PERSON_PHONE)    public String phone;    @Override    public String toString() {        return "id=" + id + "\r name=" + name + "\r age=" + age + "\r address=" + address + "\r phone=" + phone;    }}

其中 id 的寫法就表示它是主鍵啦,注意:必須繼承 BaseModel 。

1、初始化:
public void initDB() {    if (DatabaseManager.getInstance().isInited())        return;    String dbName = "person.db";    int version = 0;    try {        version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;    } catch (NameNotFoundException e) {        e.printStackTrace();    }    List<Class<?>> list = new ArrayList<Class<?>>();    list.add(PersonModel.class);    DatabaseManager.getInstance().initDataBase(getApplicationContext(), dbName, version, list);}

其中 dbName 就是資料庫名字;version 版本這裡使用的是 versionCode,這樣每次升級版本號碼以後資料庫都會升級一次。當然你也可以自己定義;list 就是需要存到資料庫的映射模型列表,它必須繼承自 BaseModel。初始化完成以後,資料庫和表就都已經給我們建立好了。

根據對象關係映射模式的理念就是每一張表都應該對應一個模型(Model),也就是說,如果我們想要建一張 person 表,就應該有一個對應的 Person 模型類。

2、insert 資料

一行代碼就能搞定:

DatabaseManager.getInstance().insert(PersonModel.class, model);

如果想要監聽插入是否失敗,則可以調用如下 insert 方法

DatabaseManager.getInstance().insert(PersonModel.class, model, new DatabaseManager.getInstance().insert(PersonModel.class, model, new DBOperateAsyncListener() {    @Override    public <T extends BaseModel> void onPostExecute(DatabaseOptionType optionType, Class<T> claz, List<T> successModels, List<T> failModels) {        if (successModels != null) {            Log.i("MrFu", "Success = " + ((PersonModel)(successModels.get(0))).toString());        }else if (failModels != null) {            Log.i("MrFu", "Fail = " + ((PersonModel)(failModels.get(0))).toString());        }    }});

當然,如果我的資料是一個 list 的形式的,也可也直接插入,而不需要寫 for 迴圈一條一條插入,

DatabaseManager.getInstance().insert(PersonModel.class, models);
3、update 資料

同樣也是一行代碼的事情:

DatabaseManager.getInstance().update(PersonModel.class, model1);

他同樣支援4個重載方法,insert 沒有實際給出,這裡給出他的四個重載方法,insert 類似

DatabaseManager.getInstance().update(Class<T> claz, T t);DatabaseManager.getInstance().update(Class<T> claz, List<T> models);DatabaseManager.getInstance().update(Class<T> claz, T t, DBOperateAsyncListener listener);DatabaseManager.getInstance().update(Class<T> claz, List<T> models, DBOperateAsyncListener listener);
4、replace 資料

同樣也是一行代碼就能搞定啦,同樣支援4個重載方法:

DatabaseManager.getInstance().replace(Class<T> claz, T t);DatabaseManager.getInstance().replace(Class<T> claz, List<T> models);DatabaseManager.getInstance().replace(Class<T> claz, T t, DBOperateAsyncListener listener);DatabaseManager.getInstance().replace(Class<T> claz, List<T> models, DBOperateAsyncListener listener);
5、delete 資料

同樣也是喔,其中 whereClause 是 delete 的條件,whereArgs就是 whereClause 的預留位置啦:

DatabaseManager.getInstance().delete(Class<T> claz, String whereClause, String[] whereArgs);DatabaseManager.getInstance().delete(Class<T> claz, String whereClause, String[] whereArgs, DBOperateDeleteListener listener);

舉個例子,刪除 id 為 1 的資料

DatabaseManager.getInstance().delete(PersonModel.class, PersonModel.PERSON_ID + " = ?", new String[] {"1"});

這就表示刪除 PersonModel 表中的 person_id 為 1 的資料。

6、select 資料

如果需要查詢整張表的資料,只需要按照下面的寫法就可以咯:

DatabaseManager.getInstance().select(PersonModel.class, null, null, null, null, null, null, null);

其實這麼寫還是多餘了。所以,我覺得我應該添加這麼個方法:

List<PersonModel> list = DatabaseManager.getInstance().select(PersonModel.class);

這麼來看,就方便多了,如果我需要查詢整張表的資料,直接調用這個方法就可以了,當然如果你想對 select 方法進行擴充的話,完全可以重載更多的 select 方法來進行實現。

其中 SQLiteDateBase 的 query 方法如下,可以根據這個方法的參數對應這來重載 select 方法,參數都是相同的:

/*** Query the given table, returning a {@link Cursor} over the result set.** @param table The table name to compile the query against.* @param columns A list of which columns to return. Passing null will*            return all columns, which is discouraged to prevent reading*            data from storage that isn‘t going to be used.* @param selection A filter declaring which rows to return, formatted as an*            SQL WHERE clause (excluding the WHERE itself). Passing null*            will return all rows for the given table.* @param selectionArgs You may include ?s in selection, which will be*         replaced by the values from selectionArgs, in order that they*         appear in the selection. The values will be bound as Strings.* @param groupBy A filter declaring how to group rows, formatted as an SQL*            GROUP BY clause (excluding the GROUP BY itself). Passing null*            will cause the rows to not be grouped.* @param having A filter declare which row groups to include in the cursor,*            if row grouping is being used, formatted as an SQL HAVING*            clause (excluding the HAVING itself). Passing null will cause*            all row groups to be included, and is required when row*            grouping is not being used.* @param orderBy How to order the rows, formatted as an SQL ORDER BY clause*            (excluding the ORDER BY itself). Passing null will use the*            default sort order, which may be unordered.* @param limit Limits the number of rows returned by the query,*            formatted as LIMIT clause. Passing null denotes no LIMIT clause.* @return A {@link Cursor} object, which is positioned before the first entry. Note that* {@link Cursor}s are not synchronized, see the documentation for more details.* @see Cursor*/public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) {...}

怎麼樣,是不是非常簡單呢,我們不需要考慮如何? SQLiteOpenHelper 也不需要考慮那些複雜的 SQL 情況。

這篇部落客要講述的是如何使用 KopDB 架構,下一篇部落格,我會對這個架構的實現進行具體的分析,以加深印象,方便以後的擴充和學習。

本篇文章對 SQLite 的講解不是非常的細緻,有關 SQLite 的詳細說明可以參照這兩篇博文,非常非常詳細:

郭霖: Android資料庫高手秘籍

scott: Android中SQLite應用詳解

Android SQLite, KopDB 架構學習1——使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.