標籤:資料庫操作 android news 解決
-
-
- 概述
- 去年一滴相思淚今年剛流到腮邊
- 問君能有幾多愁恰似一江春水向東流
- 衣帶漸寬終不悔為伊消得人憔悴
概述
接著上回的說,雖然我們已經找出了阻擋我們通用化Android資料庫操作的五個問題,但是現在我們還不能立即開始去解決這些問題。
試想一下,我們有一個News,那麼,相應的就會有NewsDao和NewsDaoImpl,同理,如果出現一個Book,是不是也要寫出BookDao和BookDaoImpl? 這個問題想想就覺得太瘋狂!
這裡的BookDao等等都是假想的,和NewsDao是一樣的東西,就不在複製黏貼一遍了。(偷笑中….)
那麼,在解決五個問題之前我們需要做的工作就是,把NewsDao和BookDao中公用的部分在提取一次;把NewsDaoImpl和BookDaoImpl中的公用部分也再提取一次。
去年一滴相思淚,今年剛流到腮邊
工作需要一步一步做,那麼我們首先抽取NewsDao和BookDao介面中公用的部分,並放在BaseDao中。既然是抽取公用的,那麼原先位於NewsDao中,傳入特定的參數(如:Integer、News)可能就不在適用了,我們需要尋找更為一般、通用的東西來替代,而泛型就是我們的好幫手(O(∩_∩)O~)。
public interface BaseDao<M> { /** * 增加 */ long insert(M m); /** * 刪除< * 傳入的參數可能或是Integer或者Long或者String, * 那麼此處就不能夠使用具有特殊性的類型,要使用具有一般性的、公用的。< * 而Serizlizable,則是Integer、Long、String共性的不二選擇。 */ int delete(Serializable id); /** * 修改 */ int update(M m); /** * 查詢所有 */ List<M> findAll();}
是不是很簡單?
我們把公用的方法抽取到BaseDao中,並把參數替換成為泛型和Serializable,這樣NewsDao只需要繼承我們的BaseDao並傳入泛型,就大功告成了。代碼如下:
public interface NewsDao extends BaseDao<News> { // 既然提取完公用的了,那麼這些具有特殊性的就不需要了 // 另外,實現BaseDao介面 // long insert(News news); // int delete(int id); // int update(News news); // List<News> findAll(); // 當然,除了通用的增刪改查,還具有一些特有的方法 // 比如,查詢按時間排序的最新的新聞}
是不是這個樣子?NewsDao裡面空空如也,當然,如果我們需要一些更為特殊的方法,還是需要寫在這裡面的,例如:查詢按時間排序的最新的新聞。
問君能有幾多愁?恰似一江春水向東流
既然介面中的公用的方法能夠抽取,那麼它們的實作類別也是不能夠例外的。我們抽取實作類別(NewsDaoImpl和BookDaoImpl)中公用的部分,放在BaseDaoSupport中。
這裡要記住BaseDao和BaseDaoSupport之間,只不過是NewsDao和NewsDaoImpl的映射,它們之間也是實作類別的關係。
public abstract class BaseDaoSupport<M> implements BaseDao<M> { // * 抽取公用部分應該解決的問題:<br> // * 問題1:表名的擷取<br> // * 問題2:如何將實體中的資料,按照對應關係匯入到資料庫中<br> // * 問題3:明確實體中主鍵是誰?擷取到主鍵中封裝的值<br> // * 問題4:實體的對象建立<br> // * 問題5:如何將資料庫中表的列的資料,按照對應關係,封裝到實體中<br> private Context context; private DBHelper helper; private SQLiteDatabase db; public BaseDaoSupport(Context context) { super(); this.context = context; this.helper = new DBHelper(context); this.db = helper.getWritableDatabase(); } @Override public long insert(M m) { // 請在此處填寫代碼 return 0; } @Override public int delete(Serializable id) { // 請在此處填寫代碼 return 0; } @Override public int update(M m) { // 請在此處填寫代碼 return 0; } @Override public List<M> findAll() { // 請在此處填寫代碼 return null; }}
我們來看一下BaseDaoSupport中的東西,我們抽取出了Context、DBHelper、SQLiteOpenHelper還有建構函式,看起來和我們的NewsDaoImpl中的東西一樣。
再看看下面的insert、delete、update、findAll等方法,模子是一樣的,只不過裡面具體的參數替換成了泛型。
回過頭我們看看被抽取完的NewsDaoImpl變成什麼樣子了,首先繼承了BaseDaoSupport<News>並傳入了自己所要操作的實體bean,然後又實現了NewsDao介面。代碼如下:
public class NewsDaoImpl extends BaseDaoSupport<News> implements NewsDao { public NewsDaoImpl(Context context) { super(context); }}
好像除了建構函式就空空如野了,但實際情況並非如此,我們在BaseDaoSupport中,已經實現了BaseBase介面,並且重寫了insert、update、delete、findAll等方法,這樣我們NewsDaoImple中就繼承了這些公用的方法了。
到了這一步是不是很開心! O(∩_∩)O~ ,代碼看著越來越清爽了!
衣帶漸寬終不悔,為伊消得人憔悴
到了這一步,我們的抽取和重構就基本完成了,那麼我們接下來的工作重點就位於BaseDaoSupport,只要我們能夠在此類中解決上一篇文章中碰到的五個問題,那麼我們就可以做到Android中資料庫的通用操作了。
是不是有點小激動了!! 別著急,我們慢慢來,請看下回分解!
最後把重構完成後的包結構展示給大家:
如果你浪費了自己的年齡,那是挺可悲的。因為你的青春只能持續一點兒時間——很短的一點兒時間。 —— 王爾德
如何將Android資料庫操作通用化(二)