Android數據庫高手秘籍(六)——LitePal的改動和刪除操作


轉載請注明出處:http://blog.csdn.net/guolin_blog/article/details/40083685

在上一篇文章中,我們學會了使用LitePal進行存儲數據的功能。確實,比起直接使用Android原生的API,LitePal明顯簡單方便了太多。那么,在增刪改查四種操作中,我們已經把“增”學完了,今天就讓我們繼續趁熱打鐵,學習一下怎樣使用LitePal進行改動和刪除操作。還沒有看過前一篇文章的朋友建議先去參考 Android數據庫高手秘籍(五)——LitePal的存儲操作

LitePal的項目地址是:https://github.com/LitePalFramework/LitePal

傳統的改動和刪除數據方式

上篇文章中我們已經得知,SQLiteDatabase類中提供了一個insert()方法用於插入數據,那么相似地,它還提供了update()和delete()這兩個方法,分別用於改動和刪除數據。先來看一下update()方法的方法定義:

public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
update()方法接收四個參數,第一個參數是表名,第二個參數是一個封裝了待改動數據的ContentValues對象,第三和第四個參數用於指定改動哪些行,相應了SQL語句中的where部分。

那么比方說我們想把news表中id為2的記錄的標題改成“今日iPhone6公布”,就能夠這樣寫:

SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("title", "今日iPhone6公布");
db.update("news", values, "id = ?", new String[] {"2"});

其作用相當於例如以下SQL語句:

update news set title='今日iPhone6公布' where id=2;
能夠看出,比起直接使用SQL語句,update()方法的語義性明顯更強,也更easy讓人理解。

接下來再看一下delete()方法的方法定義:

public int delete(String table, String whereClause, String[] whereArgs)
delete()方法接收三個參數,第一個參數相同是表名,第二和第三個參數用於指定刪除哪些行,相應了SQL語句中的where部分。

那么比方說我們想把news表中全部沒有評論的新聞都刪除掉,就能夠這樣寫:

SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("news", "commentcount = ?", new String[] {"0"});
其作用相當於例如以下SQL語句:
delete from news where commentcount=0;

由此可見,Android給我們提供的這些幫助方法,在非常大程度上確實簡化了不少數據庫操作的復雜度。只是LitePal顯然做到了更好,以下就讓我們學習一下怎樣使用LitePal來進行改動和刪除操作。

使用LitePal改動數據

LitePal改動數據的API比較簡單,並沒有什么太多的使用方法,也比較好理解,方法都是定義在DataSupport類中的,我們先來看一下方法定義:

public static int update(Class<?> modelClass, ContentValues values, long id)
這個靜態的update()方法接收三個參數,第一個參數是Class,傳入我們要改動的那個類的Class就好,第二個參數是ContentValues對象,這三個參數是一個指定的id,表示我們要改動哪一行數據。

那么比方說我們想把news表中id為2的記錄的標題改成“今日iPhone6公布”,就能夠這樣寫:

ContentValues values = new ContentValues();
values.put("title", "今日iPhone6公布");
DataSupport.update(News.class, values, 2);
能夠看出,整體來講還是比原生的使用方法要簡單一些的,首先我們避免掉了要去獲取SQLiteDatabase對象的步驟,其次在指定改動某一條id記錄的時候僅僅須要傳入這個id即可,語法更簡練。

那么有的朋友可能會問了,或許我想改動的是某一個條件下的全部數據,而不是僅僅改動某個id的數據,那該怎么辦呢?別操心,LitePal還提供了另外一個簡便的方法,方法定義例如以下:

public static int updateAll(Class<?> modelClass, ContentValues values, String... conditions)
updateAll()方法表示改動多行記錄,當中第一個參數仍然是Class,第二個參數還是ContentValues對象,第三個參數是一個conditions數組,用於指定改動哪些行的約束條件,返回值表示此次改動影響了多少行數據。

那么比方說我們想把news表中標題為“今日iPhone6公布”的全部新聞的標題改成“今日iPhone6 Plus公布”,就能夠這樣寫:

ContentValues values = new ContentValues();
values.put("title", "今日iPhone6 Plus公布");
DataSupport.updateAll(News.class, values, "title = ?", "今日iPhone6公布");
前面都沒什么好說的,重點我們看一下最后的這個conditions數組,由於它的類型是一個String數組,我們能夠在這里填入隨意多個String參數,當中最前面一個String參數用於指定約束條件,后面全部的String參數用於填充約束條件中的占位符(即?號),比方約束條件中有一個占位符,那么后面就應該填寫一個參數,假設有兩個占位符,后面就應該填寫兩個參數,以此類推。

比方說我們想把news表中標題為“今日iPhone6公布”且評論數量大於0的全部新聞的標題改成“今日iPhone6 Plus公布”,就能夠這樣寫:

ContentValues values = new ContentValues();
values.put("title", "今日iPhone6 Plus公布");
DataSupport.updateAll(News.class, values, "title = ? and commentcount > ?", "今日iPhone6公布", "0");
能夠看出,通過占位符的方式來實現條件約束明顯要比原生的API更加簡單易用。

那么假設我們想把news表中全部新聞的標題都改成“今日iPhone6公布”,該怎么寫呢?事實上這就更簡單了,僅僅須要把最后的約束條件去掉即可了,例如以下所看到的:

ContentValues values = new ContentValues();
values.put("title", "今日iPhone6 Plus公布");
DataSupport.updateAll(News.class, values);
怎么樣,這樣的寫法是不是感覺語義性非常強?updateAll()方法在不指定約束條件的情況下就是改動全部行的數據,的的確確是update all了。

當然有些朋友可能會認為這樣用起來還是有點復雜,由於這個ContentValues對象非常煩人,每次創建它的時候都要寫非常多繁瑣的代碼。沒關系,LitePal也充分考慮了這樣的情況,提供了一種不須要ContentValues就能改動數據的方法,以下我們嘗試使用這樣的新方法來完畢上述相同的功能。

比方把news表中id為2的記錄的標題改成“今日iPhone6公布”,就能夠這樣寫:

News updateNews = new News();
updateNews.setTitle("今日iPhone6公布");
updateNews.update(2);
這次我們並沒實用ContentValues,而是new出了一個News對象,把要改動的數據直接set進去,最后調用一下update()方法並傳入id就能夠了。不僅不用創建ContentValues對象,連表名都不用指定了,由於News對象默認就是改動的news表。

這是當中一種使用方法,那么假設我們想把news表中標題為“今日iPhone6公布”且評論數量大於0的全部新聞的標題改成“今日iPhone6 Plus公布”,就能夠這樣寫:

News updateNews = new News();
updateNews.setTitle("今日iPhone6公布");
updateNews.updateAll("title = ? and commentcount > ?", "今日iPhone6公布", "0");
還是非常好理解的,這里我就不再詳解了。

可是這樣的使用方法有一點須要注意,就是假設我們想把某一條數據改動成默認值,比方說將評論數改動成0,僅僅是調用updateNews.setCommentCount(0)這樣是不能改動成功的,由於即使不調用這行代碼,commentCount的值也默認是0。所以假設想要將某一列的數據改動成默認值的話,還須要借助setToDefault()方法。使用方法也非常easy,在setToDefault()方法中傳入要改動的字段名就能夠了(類中的字段名),比方說我們想要把news表中全部新聞的評論數清零,就能夠這樣寫:

News updateNews = new News();
updateNews.setToDefault("commentCount");
updateNews.updateAll();

使用LitePal刪除數據

LitePal刪除數據的API和改動數據是比較相似的,可是更加的簡單一些,我們先來看一下DataSupport類中的方法定義,例如以下所看到的:

public static int delete(Class<?> modelClass, long id)
delete()方法接收兩個參數,第一個參數是Class,傳入我們要刪除的那個類的Class就好,第二個參數是一個指定的id,表示我們要刪除哪一行數據。

那么比方說我們想刪除news表中id為2的記錄,就能夠這樣寫:

DataSupport.delete(News.class, 2);

須要注意的是,這不僅僅會將news表中id為2的記錄刪除,同一時候還會將其他表中以news id為2的這條記錄作為外鍵的數據一起刪除掉,由於外鍵既然不存在了,那么這么數據也就沒有保留的意義了。

說起來可能有點拗口,我們還是舉例看一下。比方news表中眼下有兩條數據,例如以下圖所看到的:


然后comment表中也有兩條數據,例如以下圖所看到的:


當中comment表中兩條數據的外鍵都是2,指向的news表中id為2的這條記錄。那么以下我們運行例如以下刪除語句:

int deleteCount = DataSupport.delete(News.class, 2);
Log.d("TAG", "delete count is " + deleteCount);
當中delete()方法的返回值表示被刪除的記錄數,打印結果例如以下所看到的:


能夠看到,有三條記錄被刪除了,那我們再到news表中查詢一下:


OK,僅僅剩下一條記錄了,id為2的那條記錄確實被刪除了。那么再到comment表中看一下呢,例如以下圖所看到的:


數據全沒了!為什么呢?由於comment表中的兩條數據都是以news表中id為2的數據作為外鍵的,如今外鍵不存在了,那么這兩條數據自然也沒有存在的意義了,因此被刪除的記錄數一共是3條。這樣是不是就好理解了非常多呢?

除了刪除指定id的數據之外,DataSupport中也提供了一個通過where語句來批量刪除數據的方法,先看一下方法定義:

public static int deleteAll(Class<?> modelClass, String... conditions)
看起來非常眼熟吧?非常easy,deleteAll()方法接收兩個參數,第一個參數是Class,傳入我們要刪除的那個類的Class就好,第二個參數是一個conditions數組,用於指定刪除哪些行的約束條件,返回值表示此次刪除了多少行數據,使用方法和updateAll()方法是基本相同的。

那么比方說我們想把news表中標題為“今日iPhone6公布”且評論數等於0的全部新聞都刪除掉,就能夠這樣寫:

DataSupport.deleteAll(News.class, "title = ? and commentcount = ?", "今日iPhone6公布", "0");
而假設我們想把news表中全部的數據全部刪除掉,就能夠這樣寫:
DataSupport.deleteAll(News.class);
在不指定約束條件的情況下,deleteAll()方法就會刪除表中全部的數據了。

除了DataSupport類中提供的靜態刪除方法之外,另一個刪除方法是作用於對象上的,即不論什么一個繼承自DataSupport類的實例都能夠通過調用delete()這個實例方法來刪除數據。但前提是這個對象一定是要持久化之后的,一個非持久化的對象假設調用了delete()方法則不會產生不論什么效果。

比方說以下這樣的寫法:

News news = new News();
news.delete();
這里new出了一個News對象,這個對象明顯是沒有持久化的,那么此時調用delete()方法則不會刪除不論什么數據。

但假設我們之前將這個對象持久化過了,那么再調用delete()方法就會把這個對象相應的數據刪除掉了,比方:

News news = new News();
news.setTitle("這是一條新聞標題");
news.setContent("這是一條新聞內容");
news.save();
...
news.delete();
一個對象假設save過了之后,那就是持久化的了。除了調用save()方法之外,通過DataSupport中提供的查詢方法從數據庫中查出來的對象也是經過持久化的,查詢的功能我們會在下篇博客中解說。

另外另一個簡單的辦法能夠幫助我們推斷一個對象是否是持久化之后的,DataSupport類中提供了一個isSaved()方法,這種方法返回true就表示該對象是經過持久化的,返回false則表示該對象未經過持久化。那么刪除一個對象相應的數據也就能夠這樣寫了:

News news;
...
if (news.isSaved()) {
	news.delete();
}

好了,這樣我們就把LitePal中提供的改動和刪除數據操作的使用方法基本都學習完了,那么今天的文章就到這里,下一篇文章中會開始解說查詢數據的使用方法,感興趣的朋友請繼續閱讀 Android數據庫高手秘籍(七)——體驗LitePal的查詢藝術 。

LitePal開源項目地址:https://github.com/LitePalFramework/LitePal


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM