我們剛學會了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的記錄的標題改成“今天下雪了”,就可以這樣寫:
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("title", "今天下雪了");
db.update("news", values, "id = ?", new String[] {"2"});
其作用相當于如下SQL語句:
update news set title='今天下雪了' where id=2;
接下來再看一下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;
使用LitePal修改數據
LitePal修改數據的API比較簡單,并沒有什么太多的用法,也比較好理解,方法都是定義在LitePal類中的,我們先來看一下方法定義:
public static int update(Class<?> modelClass, ContentValues values, long id)
這個靜態的update()方法接收三個參數,第一個參數是Class,傳入我們要修改的那個類的Class就好,第二個參數是ContentValues對象,這三個參數是一個指定的id,表示我們要修改哪一行數據。
那么比如說我們想把news表中id為2的記錄的標題改成“今天下雪了”,就可以這樣寫:
News updateNews = new News();
updateNews.setTitle("今天下雪了");
updateNews.update(2);
創建一個News對象,把要修改的數據直接set進去,最后調用一下update()方法并傳入id歐耶
如果我們想把某一條數據修改成默認值,比如說將發布日期改為0,調用updateNews.setPublishDate(0)這樣是不能修改成功的,因為即使不調用這行代碼,publishDate的值也默認是0。所以如果想要將某一列的數據修改成默認值的話,還需要借助setToDefault()方法。用法也很簡單,在setToDefault()方法中傳入要修改的字段名就可以了(類中的字段名),比如說我們想要把news表中所有新聞的發布日期清零,就可以這樣寫:
News updateNews = new News();
updateNews.setToDefault("publishDate");
updateNews.updateAll();
如果我們想把news表中標題為 “Android Q” 改成“今日Android Q 發布”,就可以這樣寫:
News updateNews = new News();
updateNews.setTitle("今日Android Q 發布");
updateNews.updateAll("title = ?", "Android Q");
可以看出,通過占位符的方式來實現條件約束要比原生的API更加簡單易用。
如果我們想把news表中所有新聞的標題都改成“今日Android Q 發布”,該怎么寫呢?其實這就更簡單了,只需要把最后的約束條件去掉就行了,如下所示:
News updateNews = new News();
updateNews.setTitle("今日Android Q 發布");
int i = updateNews.updateAll();
Log.d(TAG, "---i=" + i);
感覺太嗨了
使用LitePal刪除數據
LitePal刪除數據的API和修改數據是比較類似的,但是更加的簡單一些,我們先來看一下LitePal類中的方法定義,如下所示:
public static int delete(Class<?> modelClass, long id)
delete()方法接收兩個參數,第一個參數是Class,傳入我們要刪除的那個類的Class就好,第二個參數是一個指定的id,表示我們要刪除哪一行數據。
那么比如說我們想刪除news表中id為2的記錄,就可以這樣寫:
int delete = LitePal.delete(News.class, 2);
Log.d(TAG, "delete=" + delete);
這不僅僅會將news表中id為2的記錄刪除,同時還會將其它表中以news id為2的這條記錄作為外鍵的數據一起刪除掉,因為外鍵既然不存在了,那么這么數據也就沒有保留的意義了。
說起來可能有點拗口,我們還是舉例看一下。比如news表中目前有兩條數據,如下圖所示:
然后comment表中也有兩條數據,如下圖所示:
其中comment表中兩條數據的外鍵都是2,指向的news表中id為2的這條記錄。那么下面我們執行如下刪除語句:
int deleteCount = LitePal.delete(News.class, 2);
Log.d("TAG", "delete count is " + deleteCount);
其中delete()方法的返回值表示被刪除的記錄數,打印結果如下所示:
2020-01-14 11:36:05.952 7824-7824/? D/MainActivity: delete=3
可以看到,有三條記錄被刪除了,那我們再到news表中查詢一下:
只剩下一條記錄了,id為2的那條記錄確實被刪除了。那么再到comment表中看一下呢,如下圖所示:
數據全沒了!為什么呢?因為comment表中的兩條數據都是以news表中id為2的數據作為外鍵的,現在外鍵不存在了,那么這兩條數據自然也沒有存在的意義了,因此被刪除的記錄數一共是3條。這樣是不是就好理解了很多呢?
除了刪除指定id的數據之外,LitePal中也提供了一個通過where語句來批量刪除數據的方法,先看一下方法定義:
public static int deleteAll(Class<?> modelClass, String... conditions)
看起來很眼熟吧?非常簡單,deleteAll()方法接收兩個參數,第一個參數是Class,傳入我們要刪除的那個類的Class就好,第二個參數是一個conditions數組,用于指定刪除哪些行的約束條件,返回值表示此次刪除了多少行數據,用法和updateAll()方法是基本相同的。
那么比如說我們想把news表中標題為“今天下雪了”所有新聞都刪除掉,就可以這樣寫:
LitePal.deleteAll(News.class, "title = ?", "今天下雪了");
而如果我們想把news表中所有的數據全部刪除掉,就可以這樣寫:
LitePal.deleteAll(News.class);
在不指定約束條件的情況下,deleteAll()方法就會刪除表中所有的數據了。
除了LitePal類中提供的靜態刪除方法之外,還有一個刪除方法是作用于對象上的,即任何一個繼承自LitePalSupport類的實例都可以通過調用delete()這個實例方法來刪除數據。但前提是這個對象一定是要持久化之后的,一個非持久化的對象如果調用了delete()方法則不會產生任何效果。
比如說下面這種寫法:
News news = new News();
news.delete();
這里創建一個News對象,這個對象沒有持久化,調用delete()方法不會刪除任何數據。
如果我們之前將這個對象持久化過了,那么再調用delete()方法就會把這個對象對應的數據刪除掉了,比如:
News news = new News();
news.setTitle("這是一條新聞標題");
news.setContent("這是一條新聞內容");
news.save();
...
news.delete();
一個對象如果save過了之后,那就是持久化的了。除了調用save()方法之外,通過LitePalSupport中提供的查詢方法從數據庫中查出來的對象也是經過持久化的,查詢的功能我們會在下篇博客中講解。
另外還有一個簡單的辦法可以幫助我們判斷一個對象是否是持久化之后的,LitePalSupport類中提供了一個isSaved()方法,這個方法返回true就表示該對象是經過持久化的,返回false則表示該對象未經過持久化。那么刪除一個對象對應的數據也就可以這樣寫了:
News news;
...
if (news.isSaved()) {
news.delete();
}
LitePal中提供的修改和刪除數據操作我們搞完了,下一篇文章中會開始講解查詢數據的用法,感興趣的朋友請繼續閱讀 Android數據庫高手秘籍(七)LitePal的查詢藝術 。