生活随笔
收集整理的這篇文章主要介紹了
Android数据库LitePal的存储操作
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文屬于轉載,在此聲明,出處:http://blog.csdn.net/guolin_blog/article/details/38556989
并且感謝guolin分享了這么精彩的博文。以下正文:
經過前面幾篇文章的學習,我們已經把LitePal的表管理模塊的功能都很好地掌握了,相信大家都已經體會到了使用LitePal來創建表、升級表、以及建立表關聯所帶來的便利。那么從本篇文章開始,我們將進入到一個新模塊的學習旅程當中,使用LitePal來進行表的CRUD操作。還沒有看過前一篇文章的朋友建議先去參考?Android數據庫高手秘籍(四)——使用LitePal建立表關聯?。
LitePal提供的CRUD操作的API還是頗為豐富的,一篇文章肯定是介紹不全的,因此這里我們仍然是分幾篇文章進行講解,本篇主要是介紹存儲方面的API。
LitePal的項目地址是:https://github.com/LitePalFramework/LitePal
傳統的存儲數據方式
其實最傳統的存儲數據方式肯定是通過SQL語句拼接字符串來進行存儲的,不過這種方式有點過于“傳統”了,今天我們在這里就不討論這種情況。實際上,Android專門提供了一種用于存儲數據的簡便方法,使得我們不用編寫SQL語句就可以執行存儲操作。下面來看一下SQLiteDatabase中的insert()方法:
[java]?view plaincopy
public?long?insert(String?table,?String?nullColumnHack,?ContentValues?values)??
可以看到,insert方法接收三個參數,第一個參數是表名,第二個參數通常都用不到,直接傳null,第三個參數則是一個封裝了待存儲數據的ContentValues對象。因此,比如說我們想往news表中插入一條新聞,就可以這樣寫:
[java]?view plaincopy
SQLiteDatabase?db?=?dbHelper.getWritableDatabase();?? ContentValues?values?=?new?ContentValues();?? values.put("title",?"這是一條新聞標題");?? values.put("content",?"這是一條新聞內容");?? values.put("publishdate",?System.currentTimeMillis());?? long?id?=?db.insert("news",?null,?values);??
其中,調用ContentValues的put()方法來添加待存儲數據,put()方法接收兩個參數,第一個參數是數據庫表中對應的列名,第二個參數就是要存儲的值,最后調用一下insert()方法,這條新聞就會插入到news表當中了,并且該數據行對應的id會作為返回值進行返回。
用法很簡單是嗎?確實,比起直接使用SQL語句,SQLiteDatabase中提供的insert()方法的確簡單了很多。但insert()方法也并非是那么的完美,它還是有很多不方便的地方的,比如說沒有考慮表關聯的情況,我們需要手動對關聯表的外鍵進行存儲。再比如說,沒有提供批量存儲的功能,當我們有一個集合的數據需要存儲時,需要通過循環來遍歷這個集合,然后一次次地調用insert()方法來插入數據。
好了,那么關于傳統存儲數據的用法就簡單介紹到這里,因為確實沒什么的更多的用法了,并且它也不是我們今天的主角。接下來,就讓我們看一看今天的驚喜,學習如何使用LitePal來進行數據庫存儲的操作。
使用LitePal存儲數據
LitePal中與存儲相關的API其實并不多,但用法還是頗為豐富的,而且比起傳統的insert()方法,使用LitePal來存儲數據可以簡單到讓你驚嘆的地步,那么今天我們就來完整地學習一下LitePal存儲數據的所有用法。
在前面幾篇文章當中,我們在項目里已經建好了News、Comment、Introduction、Category這幾個實體類,通過這些實體類,LitePal就可以把相應的表自動創建出來。現在來觀察這幾個實體類,我們發現這幾個類都是沒有繼承結構的。沒錯,因為LitePal進行表管理操作時不需要這些實體類有任何的繼承結構,當時為了簡單起見就沒有寫。但是進行CRUD操作時就不行了,LitePal要求所有的實體類都要繼承自DataSupport這個類,因此這里我們就要把繼承結構給加上才行。修改News類的代碼,如下所示:
[java]?view plaincopy
public?class?News?extends?DataSupport{?? ?????? ????......?? ?????? ?????? }??
可以看到,這里只是讓News類繼承自了DataSupport,其它什么都沒有改變。另外幾個Comment、Introduction、Category類也使用同樣的改法,這里就不一一演示了。
繼承了DataSupport類之后,這些實體類就擁有了進行CRUD操作的能力,那么比如想要存儲一條數據到news表當中,就可以這樣寫:
[java]?view plaincopy
News?news?=?new?News();?? news.setTitle("這是一條新聞標題");?? news.setContent("這是一條新聞內容");?? news.setPublishDate(new?Date());?? news.save();??
怎么樣?是不是非常簡單,不需要SQLiteDatabase,不需要ContentValues,不需要通過列名組裝數據,甚至不需要指定表名,只需要new出一個News對象,然后把要存儲的數據通過setter方法傳入,最后調用一下save()方法就好了,而這個save()方法自然就是從DataSupport類中繼承而來的了。
除此之外,save()方法還是有返回值的,我們可以根據返回值來判斷存儲是否成功,比如說這樣寫:
[java]?view plaincopy
if?(news.save())?{?? ????Toast.makeText(context,?"存儲成功",?Toast.LENGTH_SHORT).show();?? }?else?{?? ????Toast.makeText(context,?"存儲失敗",?Toast.LENGTH_SHORT).show();?? }??
可以看出,save()方法返回的是一個布爾值,用于表示存儲成功還是失敗,但同時也說明這個方法是不會拋出異常的。有些朋友希望如果存儲失敗的話就拋出異常,而不是返回一個false,那就可以使用saveThrows()方法來代替,如下所示:
[java]?view plaincopy
News?news?=?new?News();?? news.setTitle("這是一條新聞標題");?? news.setContent("這是一條新聞內容");?? news.setPublishDate(new?Date());?? news.saveThrows();??
使用saveThrows()方法來存儲數據,一旦存儲失敗就會拋出一個DataSupportException異常,我們可以通過對這個異常進行捕獲來處理存儲失敗的情況。
那有些細心的朋友可能已經注意到,使用的insert()方法來存儲數據時是有返回值的,返回的是插入行對應的id。但LitePal中的save()方法返回的是布爾值,那么我們怎樣才能拿到存儲成功之后這條數據對應的id呢?對此,LitePal使用了一種非常巧妙的做法,還記得我們在每個實體類中都定義了一個id字段嗎?當調用save()方法或saveThrows()方法存儲成功之后,LitePal會自動將該條數據對應的id賦值到實體類的id字段上。讓我們來做個試驗吧,代碼如下所示:
[java]?view plaincopy
News?news?=?new?News();?? news.setTitle("這是一條新聞標題");?? news.setContent("這是一條新聞內容");?? news.setPublishDate(new?Date());?? Log.d("TAG",?"news?id?is?"?+?news.getId());?? news.save();?? Log.d("TAG",?"news?id?is?"?+?news.getId());??
在save之前打印一下news的id,在save之后再打印一次,現在運行一下,打印結果如下所示:
OK,在save之前打印的id是0,說明此時id這個字段還沒有被賦值,在save之后打印的id是1,說明此時id已經被賦值了。那么我們再到數據庫表中再查看一下這條記錄到底有沒有存儲成功吧,如下圖所示:
可以看到,這條新聞確實已經存儲成功了,并且對應的id正是1,和我們前面打印的結果是一致的。
不過LitePal的存儲功能顯示不僅僅只有這些用法,事實上,LitePal在存儲數據的時候默默幫我們做了很多的事情,比如多個實體類之間有關聯關系的話,我們不需要考慮在存儲數據的時候怎么去建立數據與數據之間的關聯,因為LitePal一切都幫我們做好了。
還是通過一個例子來看一下吧,Comment和News之間是多對一的關系,一條News中是可以包含多條評論的,因此我們就可以這樣寫:
[java]?view plaincopy
Comment?comment1?=?new?Comment();?? comment1.setContent("好評!");?? comment1.setPublishDate(new?Date());?? comment1.save();?? Comment?comment2?=?new?Comment();?? comment2.setContent("贊一個");?? comment2.setPublishDate(new?Date());?? comment2.save();?? News?news?=?new?News();?? news.getCommentList().add(comment1);?? news.getCommentList().add(comment2);?? news.setTitle("第二條新聞標題");?? news.setContent("第二條新聞內容");?? news.setPublishDate(new?Date());?? news.setCommentCount(news.getCommentList().size());?? news.save();??
可以看到,這里先是存儲了一條comment1數據,然后存儲一條comment2數據,接著在存儲News之前先把剛才的兩個Comment對象添加到了News的commentList列表當中,這樣就表示這兩條Comment是屬于這個News對象的,最后再把News存儲到數據庫中,這樣它們之間的關聯關系就會自動建立了。讓我們查看數據庫表檢查一下吧,首先看一下news表,如下所示:
OK,第二條新聞已經成功存儲到news表中了,這條新聞的id是2。那么從哪里可以看出來關聯關系呢?我們在上一篇文章中學過,多對一關聯的時候,外鍵是存放在多方的,因此關聯關系我們要到comment表中去查看,如下所示:
可以看到,兩條評論都已經成功存儲到comment表中了,并且這兩條評論的news_id都是2,說明它們是屬于第二條新聞的。怎么樣,僅僅是在存儲數據之前建立好實體類之間的關系,再調用一下save()方法,那么數據之間的關聯關系就會自動建立了,是不是非常簡單?上面的代碼只是多對一情況的一種用法,還有一對一和多對多的情況,其實用法都是差不多的,相信你已經能舉一反三了。
另外,LitePal對集合數據的存儲還專門提供了一個方法,比如說我們有一個News集合,那么應該怎樣去存儲這個集合中的每條News呢?傳統情況下可以這樣寫:
[java]?view plaincopy
List<News>?newsList;?? ...?? for?(News?news?:?newsList)?{?? ????news.save();?? }??
通過一個循環來遍歷出這個集合中的每一個News對象,然后逐個調用save()方法。這樣的寫法當然是可以的,但是效率會比較低,因為調用save()方法的時候除了會執行存儲操作之外,還會去分析News類的關聯關系,那么每次循環都去重新分析一遍關聯關系顯然是比較耗時的。因此,LitePal提供了一個saveAll()方法,專門用于存儲集合數據的,用法如下所示:
[java]?view plaincopy
List<News>?newsList;?? ...?? DataSupport.saveAll(newsList);??
saveAll()方法接收一個Collection集合參數,只要把待存儲的集合數據傳入即可。這個方法可以完成和上面一段代碼完全一樣的功能,但效率卻會高得多,而且寫法也更加簡單。
好了,這樣我們就把LitePal中提供的存儲操作的用法全部都學完了,那么今天的文章就到這里,下一篇文章當中會開始講解更新和刪除操作的用法。感興趣的朋友請繼續閱讀?Android數據庫高手秘籍(六)——LitePal的修改和刪除操作?。
LitePal開源項目地址:
https://github.com/LitePalFramework/LitePal
總結
以上是生活随笔為你收集整理的Android数据库LitePal的存储操作的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。