如果不使用Room、LiveData、ViewModel只使用SqliteOpenHelper會怎樣? 上篇 "查詢"
關於學習Android的資料庫運作,
現在很少直接操作SQLiteOpenHelper,
通常會直接學習使用Room和ContentProvider來操作資料,
並配合MMVM架構去撰寫程式碼。
但直接讓新手學這種較多抽象的東西,
如果沒實作過糟糕的方式...恐怕無法真正理解這些做法好在哪?
以及重點差異。
基於上述理由我想用SQLiteOpenHelper實作一個沒有清楚分割UI和Model的案例。
最棒的學習方式是從問題中學習並解決它,
所以我們來假設一個需求「能查看&修改產品清單的App」
(當然只限於Android端)。
產品可視為一個資料表Products,
每一個產品需要有產品名稱、價格、庫存量,最後還需要一個唯一值的ID,總共4個Column要定義。
規劃的架構如下:
將條目定義成常量的好處在於IDE會提供自動補全,
可以避免打錯字這類低階錯誤,
將每一筆資料都轉成Product物件處理,方便RecyclerView的Adapter處理。
原本就有的activity_main還會需要再兩個XML ,
一個RecyclerView和一個itemView。
建構元參數List<Product> products是填充每個item的資料來源。
需要定義好ProductViewHolder和實作三個方法。
onCreateViewHolder()中指定item要填充的layout(此為content_main_item.xml)
getItemCount() 回傳 products的大小。
onBindViewHolder將當前position位置的item資料填入holder中對應的View(此為nameTextView和summaryTextView)中
沒設定也不報錯算是初學蠻常忘的東西。
adapter的productList是從Sqlite查詢得到的,
當onCreate時賦值給它一個ProductSqlOpenHelper。
當onDestroy時進行關閉的動作myHelper
結果
現在很少直接操作SQLiteOpenHelper,
通常會直接學習使用Room和ContentProvider來操作資料,
並配合MMVM架構去撰寫程式碼。
但直接讓新手學這種較多抽象的東西,
如果沒實作過糟糕的方式...恐怕無法真正理解這些做法好在哪?
以及重點差異。
基於上述理由我想用SQLiteOpenHelper實作一個沒有清楚分割UI和Model的案例。
最棒的學習方式是從問題中學習並解決它,
所以我們來假設一個需求「能查看&修改產品清單的App」
(當然只限於Android端)。
產品可視為一個資料表Products,
每一個產品需要有產品名稱、價格、庫存量,最後還需要一個唯一值的ID,總共4個Column要定義。
規劃的架構如下:
Step1 建立一個Contract來管理資料庫、資料表會用到的常量。
將條目定義成常量的好處在於IDE會提供自動補全,
可以避免打錯字這類低階錯誤,
Step2 建立資料類別Product
將每一筆資料都轉成Product物件處理,方便RecyclerView的Adapter處理。
Step3 建立ProductSqlOpenHelper
繼承父類SqliteOpenHelper,並實現類的onCreate和onUpgrade。
通常onCreate做的就是建立資料表,onUpgrade則是當資料表結構有變動之類的進行更新的函數(當VERSION_NUMBER改變)。
另外我又定義了兩個方法,
查詢資料用的方法getAllProducts
回傳的結果型態是List<Product>,之後將會提供給Adapter使用。
參數只需要SqliteDatabase,
回傳的結果就是一個Product的List(List<Product>),
之後會提供給Adapter使用。
參數只需要SqliteDatabase,
回傳的結果就是一個Product的List(List<Product>),
之後會提供給Adapter使用。
插入Product用的方法insertProduct
參數包掛db、Product代表要插入Products資料表的資料,
回傳新增item的id,如果新增失敗回傳-1,
因為db.insert會回傳插入item的id,當錯誤發生會回傳-1。
方法內部使用ContentValues以Key-Value的形式將Product插入資料表。
註: 你應該在Cursor用完後關閉,但千萬不要隨便關閉db.close()
最好是在onDestroy呼叫時再進行關閉,
且關閉也最好用Helper的close()而不是database的close()。
回傳新增item的id,如果新增失敗回傳-1,
因為db.insert會回傳插入item的id,當錯誤發生會回傳-1。
方法內部使用ContentValues以Key-Value的形式將Product插入資料表。
註: 你應該在Cursor用完後關閉,但千萬不要隨便關閉db.close()
最好是在onDestroy呼叫時再進行關閉,
且關閉也最好用Helper的close()而不是database的close()。
Step4 "產品列表"畫面RecyclerView
原本就有的activity_main還會需要再兩個XML ,
一個RecyclerView和一個itemView。
Step5 建立Adapter
Adapter的功用主要是將資料正確填充在列表的每個item。建構元參數List<Product> products是填充每個item的資料來源。
需要定義好ProductViewHolder和實作三個方法。
onCreateViewHolder()中指定item要填充的layout(此為content_main_item.xml)
getItemCount() 回傳 products的大小。
onBindViewHolder將當前position位置的item資料填入holder中對應的View(此為nameTextView和summaryTextView)中
Step6 設定MainActivity
定義RecyclerView的Adapter和LayoutManager
layoutManager定義為LinearLayout(也可是GridLayout等等),沒設定也不報錯算是初學蠻常忘的東西。
adapter的productList是從Sqlite查詢得到的,
管理ProductSqlOpenHelper的生命週期
建立一個myHelper屬性,當onCreate時賦值給它一個ProductSqlOpenHelper。
當onDestroy時進行關閉的動作myHelper
結果
下篇 "新增、刪除、修改"
留言
張貼留言