Android資料庫高手祕籍(6):LitePal的修改和刪除操作

發表於2015-09-04

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

LitePal的專案地址是:https://github.com/LitePalFramework/LitePal

傳統的修改和刪除資料方式

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

update()方法接收四個引數,第一個引數是表名,第二個引數是一個封裝了待修改資料的ContentValues物件,第三和第四個引數用於指定修改哪些行,對應了SQL語句中的where部分。

那麼比如說我們想把news表中id為2的記錄的標題改成“今日iPhone6釋出”,就可以這樣寫:

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

可以看出,比起直接使用SQL語句,update()方法的語義性明顯更強,也更容易讓人理解。

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

delete()方法接收三個引數,第一個引數同樣是表名,第二和第三個引數用於指定刪除哪些行,對應了SQL語句中的where部分。

那麼比如說我們想把news表中所有沒有評論的新聞都刪除掉,就可以這樣寫:

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

由此可見,Android給我們提供的這些幫助方法,在很大程度上確實簡化了不少資料庫操作的複雜度。不過LitePal顯然做到了更好,下面就讓我們學習一下如何使用LitePal來進行修改和刪除操作。

使用LitePal修改資料

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

這個靜態的update()方法接收三個引數,第一個引數是Class,傳入我們要修改的那個類的Class就好,第二個引數是ContentValues物件,這三個引數是一個指定的id,表示我們要修改哪一行資料。

那麼比如說我們想把news表中id為2的記錄的標題改成“今日iPhone6釋出”,就可以這樣寫:

可以看出,總體來講還是比原生的用法要簡單一些的,首先我們避免掉了要去獲取SQLiteDatabase物件的步驟,其次在指定修改某一條id記錄的時候只需要傳入這個id即可,語法更簡練。

那麼有的朋友可能會問了,也許我想修改的是某一個條件下的所有資料,而不是僅僅修改某個id的資料,那該怎麼辦呢?別擔心,LitePal還提供了另外一個簡便的方法,方法定義如下:

updateAll()方法表示修改多行記錄,其中第一個引數仍然是Class,第二個引數還是ContentValues物件,第三個引數是一個conditions陣列,用於指定修改哪些行的約束條件,返回值表示此次修改影響了多少行資料。

那麼比如說我們想把news表中標題為“今日iPhone6釋出”的所有新聞的標題改成“今日iPhone6 Plus釋出”,就可以這樣寫:

前面都沒什麼好說的,重點我們看一下最後的這個conditions陣列,由於它的型別是一個String陣列,我們可以在這裡填入任意多個String引數,其中最前面一個String引數用於指定約束條件,後面所有的String引數用於填充約束條件中的佔位符(即?號),比如約束條件中有一個佔位符,那麼後面就應該填寫一個引數,如果有兩個佔位符,後面就應該填寫兩個引數,以此類推。

比如說我們想把news表中標題為“今日iPhone6釋出”且評論數量大於0的所有新聞的標題改成“今日iPhone6 Plus釋出”,就可以這樣寫:

可以看出,通過佔位符的方式來實現條件約束明顯要比原生的API更加簡單易用。

那麼如果我們想把news表中所有新聞的標題都改成“今日iPhone6釋出”,該怎麼寫呢?其實這就更簡單了,只需要把最後的約束條件去掉就行了,如下所示:

怎麼樣,這種寫法是不是感覺語義性非常強?updateAll()方法在不指定約束條件的情況下就是修改所有行的資料,的的確確是update all了。

當然有些朋友可能會覺得這樣用起來還是有點複雜,因為這個ContentValues物件很煩人,每次建立它的時候都要寫很多繁瑣的程式碼。沒關係,LitePal也充分考慮了這種情況,提供了一種不需要ContentValues就能修改資料的方法,下面我們嘗試使用這種新方法來完成上述同樣的功能。

比如把news表中id為2的記錄的標題改成“今日iPhone6釋出”,就可以這樣寫:

這次我們並沒有用ContentValues,而是new出了一個News物件,把要修改的資料直接set進去,最後呼叫一下update()方法並傳入id就可以了。不僅不用建立ContentValues物件,連表名都不用指定了,因為News物件預設就是修改的news表。

這是其中一種用法,那麼如果我們想把news表中標題為“今日iPhone6釋出”且評論數量大於0的所有新聞的標題改成“今日iPhone6 Plus釋出”,就可以這樣寫:

還是非常好理解的,這裡我就不再詳細解釋了。

但是這種用法有一點需要注意,就是如果我們想把某一條資料修改成預設值,比如說將評論數修改成0,只是呼叫updateNews.setCommentCount(0)這樣是不能修改成功的,因為即使不呼叫這行程式碼,commentCount的值也預設是0。所以如果想要將某一列的資料修改成預設值的話,還需要藉助setToDefault()方法。用法也很簡單,在setToDefault()方法中傳入要修改的欄位名就可以了(類中的欄位名),比如說我們想要把news表中所有新聞的評論數清零,就可以這樣寫:

使用LitePal刪除資料

LitePal刪除資料的API和修改資料是比較類似的,但是更加的簡單一些,我們先來看一下DataSupport類中的方法定義,如下所示:

delete()方法接收兩個引數,第一個引數是Class,傳入我們要刪除的那個類的Class就好,第二個引數是一個指定的id,表示我們要刪除哪一行資料。

那麼比如說我們想刪除news表中id為2的記錄,就可以這樣寫:

需要注意的是,這不僅僅會將news表中id為2的記錄刪除,同時還會將其它表中以news id為2的這條記錄作為外來鍵的資料一起刪除掉,因為外來鍵既然不存在了,那麼這麼資料也就沒有保留的意義了。

說起來可能有點拗口,我們還是舉例看一下。比如news表中目前有兩條資料,如下圖所示:

11

然後comment表中也有兩條資料,如下圖所示:

22

其中comment表中兩條資料的外來鍵都是2,指向的news表中id為2的這條記錄。那麼下面我們執行如下刪除語句:

其中delete()方法的返回值表示被刪除的記錄數,列印結果如下所示:

33

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

44

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

55

資料全沒了!為什麼呢?因為comment表中的兩條資料都是以news表中id為2的資料作為外來鍵的,現在外來鍵不存在了,那麼這兩條資料自然也沒有存在的意義了,因此被刪除的記錄數一共是3條。這樣是不是就好理解了很多呢?

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

看起來很眼熟吧?非常簡單,deleteAll()方法接收兩個引數,第一個引數是Class,傳入我們要刪除的那個類的Class就好,第二個引數是一個conditions陣列,用於指定刪除哪些行的約束條件,返回值表示此次刪除了多少行資料,用法和updateAll()方法是基本相同的。

那麼比如說我們想把news表中標題為“今日iPhone6釋出”且評論數等於0的所有新聞都刪除掉,就可以這樣寫:

而如果我們想把news表中所有的資料全部刪除掉,就可以這樣寫:

在不指定約束條件的情況下,deleteAll()方法就會刪除表中所有的資料了。

除了DataSupport類中提供的靜態刪除方法之外,還有一個刪除方法是作用於物件上的,即任何一個繼承自DataSupport類的例項都可以通過呼叫delete()這個例項方法來刪除資料。但前提是這個物件一定是要持久化之後的,一個非持久化的物件如果呼叫了delete()方法則不會產生任何效果。

比如說下面這種寫法:

這裡new出了一個News物件,這個物件明顯是沒有持久化的,那麼此時呼叫delete()方法則不會刪除任何資料。

但如果我們之前將這個物件持久化過了,那麼再呼叫delete()方法就會把這個物件對應的資料刪除掉了,比如:

一個物件如果save過了之後,那就是持久化的了。除了呼叫save()方法之外,通過DataSupport中提供的查詢方法從資料庫中查出來的物件也是經過持久化的,查詢的功能我們會在下篇部落格中講解。

另外還有一個簡單的辦法可以幫助我們判斷一個物件是否是持久化之後的,DataSupport類中提供了一個isSaved()方法,這個方法返回true就表示該物件是經過持久化的,返回false則表示該物件未經過持久化。那麼刪除一個物件對應的資料也就可以這樣寫了:

好了,這樣我們就把LitePal中提供的修改和刪除資料操作的用法基本都學習完了,那麼今天的文章就到這裡,下一篇文章中會開始講解查詢資料的用法,感興趣的朋友請繼續閱讀 Android資料庫高手祕籍(7):體驗LitePal的查詢藝術 。

 

LitePal開源專案地址:https://github.com/LitePalFramework/LitePal

 

相關文章