編輯:關於Android編程
除非迫不得已,要不然不要在你的APP裡面使用數據庫,記不得是哪個書的話了!
現在Android平台下的ORM框架very多,比如GreenDao,曾經寫過一篇關於GreenDao的傻瓜式入門,喜歡的朋友可以去看下,GreenDao傻瓜式入門
他用起來需要自己建立一個Java工程,然後把數據模型建立,在執行java主函數的時候就把模型映射的表和結構全部創建完畢,
然後增刪改查需要用greendao的api來操作,各有利弊.
隨著今年RXjava Rxandroid的越來越火爆,一個響應式的數據庫SqlBrite也被我們傳說中的巨人,傑克大神放出,他基於RX觀察者模式,來對我們原聲的數據庫進行操作,沒有隱藏API,對於喜歡寫sql語句的同學無非是比較不錯的,
本文介紹下,在原生的sqllite中引入sqlbrite 操作數據庫,先看下demo預覽,
一個簡單的界面,我們用數據庫初始化了幾個person,是不是看出來點什麼端倪,
好吧,我們繼續,
我們在app初始化的時候,用sqlite建立了數據庫,以及我們的person表
這裡的操作全部是原始的api操作大家都非常熟悉的
public class ATDbOpenHelper extends SQLiteOpenHelper { public ATDbOpenHelper(Context context) { super(context, ATDbConstant.AT_DB_NAME, null, ATDbConstant.AT_DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(ATDb.PersonTable.CREATE); addSamePerson(db); } private void addSamePerson(SQLiteDatabase db) { Person person = new Person(); person.setAge(35); person.setName("陳冠希"); db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person)); person = new Person(); person.setAge(28); person.setName("張柏芝"); db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person)); person = new Person(); person.setAge(23); person.setName("蔡依林"); db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person)); person = new Person(); person.setAge(26); person.setName("小S"); db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person)); person = new Person(); person.setAge(27); person.setName("洪文安"); db.insert(ATDb.PersonTable.TABLE_NAME, null, ATDb.PersonTable.toContentValues(person)); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
接下來看下我們的DB對象
public class ATDb { public ATDb() { } public static abstract class PersonTable { // 表名 public static final String TABLE_NAME = "person"; // 表字段 public static final String ID = "_id"; public static final String COLUMN_NAME = "name"; public static final String COLUME_AGE = "age"; // 建表語句 public static final String CREATE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_NAME + " TEXT NOT NULL," + COLUME_AGE + " INT," + "UNIQUE (" + COLUMN_NAME + ") ON CONFLICT REPLACE" + " ); "; // 對象轉字段,放入表中 public static ContentValues toContentValues(Person person) { ContentValues values = new ContentValues(); values.put(COLUMN_NAME, person.getName()); values.put(COLUME_AGE, person.getAge()); return values; } // 響應式的查詢,根據表中的row生成一個對象 static Func1PERSON_MAPPER = new Func1 () { @Override public Person call(Cursor cursor) { Person person = new Person(); String name = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)); person.setName(name); int age = cursor.getInt(cursor.getColumnIndexOrThrow(COLUME_AGE)); person.setAge(age); return person; } }; } }
這裡依然沒有什麼變化,就是根據官方的demo,我們多了一個響應式的查詢,mapper,這個mapper參數一會需要放到sqlbrite給我們提供的數據庫對象中,
下面是數據庫的DbManager,裡面包含了sqlbrite給我們提供的上帝數據庫,britedatebase
public class ATDbManager { private static final String TAG = "ATDbManager"; // rx響應式數據庫, private BriteDatabase briteDatabase; public ATDbManager(Context context) { ATDbOpenHelper dbOpenHelper; // sqlbrite 初始化,構造出響應式數據庫,添加log SqlBrite sqlBrite; sqlBrite = SqlBrite.create(new SqlBrite.Logger() { @Override public void log(String message) { Logger.wtf(TAG, "log: >>>>" + message); } }); // 原生的sqllitehelper 用來建立數據庫和數據表,以及構造,rx響應式數據庫 dbOpenHelper = new ATDbOpenHelper(context); // 執行slqbirte 構造數據庫的語句 briteDatabase = sqlBrite.wrapDatabaseHelper(dbOpenHelper, Schedulers.io()); briteDatabase.setLoggingEnabled(true); } public Observable> queryPerson() { return briteDatabase .createQuery(ATDb.PersonTable.TABLE_NAME, "SELECT * FROM " + ATDb.PersonTable.TABLE_NAME) .mapToList(ATDb.PersonTable.PERSON_MAPPER); } public Observable
> queryPersonByName(String name) { return briteDatabase.createQuery(ATDb.PersonTable.TABLE_NAME, "SELECT * FROM " + ATDb.PersonTable.TABLE_NAME + " WHERE " + ATDb.PersonTable.COLUMN_NAME + " = ?" , name) .mapToList(ATDb.PersonTable.PERSON_MAPPER) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public long addPerson(Person person) { return briteDatabase.insert(ATDb.PersonTable.TABLE_NAME, ATDb.PersonTable.toContentValues(person)); } public int deletePersonByName(final String name) { return briteDatabase.delete(ATDb.PersonTable.TABLE_NAME, ATDb.PersonTable.COLUMN_NAME + "=?", name); } }
到這裡,所有的數據庫相關類全部介紹完畢,你會發現,sqlbrite不是一個數據庫框架,他依然需要讓你自己寫sql語句來創建數據庫查詢,就是查詢的等操作,采用了RX的方式來完成,這樣的好處,就是我們在展示列表的時候,增刪改查後,Sqlbrite都會自動的調用查詢,來改變你傳入列表的數據,不像我們以前的那種,比刪除了一個人,你要更新列表,你需要重新queery person表然後 adapter notity,用sqlbrite可以不用這樣做,
我們看下我們的activity中如何做,
//查詢的時候,rx直接返回了當前數據的所有數據 private void queryPerson() { Observable> listObservable = dbManager.queryPerson(); listObservable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber
>() { @Override public void onCompleted() { this.unsubscribe(); } @Override public void onError(Throwable e) { } @Override public void onNext(List
persons) { Logger.e(TAG, "onNext: >>>>>" + persons.size() + persons.toString()); dataForRecylerView.clear(); dataForRecylerView.addAll(persons); personAdapter.notifyDataSetChanged(); } }); }
刪除,操作,修改操作 在操作完畢後都會觸發,查詢,
以刪除為例;
@OnClick(R.id.tv_add) void addPerson() { String personName = nameInput.getText().toString(); String personAge = ageInput.getText().toString(); if (TextUtils.isEmpty(personAge)) { Snackbar.make(fab, "請輸入年齡!", Snackbar.LENGTH_SHORT).show(); } else if (TextUtils.isEmpty(personName)) { Snackbar.make(fab, "請輸入姓名!", Snackbar.LENGTH_SHORT).show(); } else { // 調用add person Person addPerson = new Person(); addPerson.setAge(Integer.valueOf(personAge)); addPerson.setName(personName); long state = dbManager.addPerson(addPerson); if (state > 0) { Snackbar.make(fab, "添加" + personName + "成功", Snackbar.LENGTH_SHORT).show(); } // tips 沒有調用查詢語句,rxjava根據表數據的變化,會輸出新的數據 } }
執行完畢刪除後,我們看下log日志,
所以我們剛才的刪除代碼,執行了db的delete語句並沒有執行重新查詢,列表會自動刷新.<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPs/rv7TUtMLrt9bO9rrNcnjUtMLrtcTNrNGnLMfrt/C/qWdpdGh1YrXEvdy/y7TzyfEsU3FsQmlyaXRl1LTC68G0vdM8YnIgLz4NCjxhIGhyZWY9"https://github.com/square/sqlbrite?utm_source=tuicool&utm_medium=referral" target="_blank">SqlBrite源碼
ListView是Android中經常會使用的東西,綁定數據對於初學者來說,尤其是剛接觸編程的人來說,往往會覺得很難理解,我上大二的時候學的java,但是基本上相當於沒有
簡介類別:項目文檔生成器,生成靜態站點,管理MarkDown文檔。官方網址:http://www.mkdocs.org/中文文檔:http://markdown-docs
Android通訊錄的制作有很多種方式,網上大部分也都有了,但是用數據庫制作通訊錄的卻少之又少,這裡我就制作一個簡單的app供大家學習先看一下效果圖,在下面有提供項目源碼
裡面評論有很多人提到了這個問題,我也是其中一員,但是問遍了所有人,自己也發帖(http://bbs.csdn.net/topics/390769358) 尋