Android数据库高手秘籍

Android数据库高手秘籍(六)LitePal的修改和删除操作

2020-01-14  本文已影响0人  as_pixar

我们刚学会了LitePal进行存储数据的功能。今天我们继续趁热抡起锤子继续打铁,使用LitePal进行修改和删除操作。还没有看过前一篇文章的朋友建议先去参考 Android数据库高手秘籍(五)LitePal的存储操作

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

logo.png

传统的修改和删除数据方式

上篇文章中我们已经得知,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表中目前有两条数据,如下图所示:


image.png

然后comment表中也有两条数据,如下图所示:


image.png
其中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表中查询一下:


image.png

只剩下一条记录了,id为2的那条记录确实被删除了。那么再到comment表中看一下呢,如下图所示:


image.png

数据全没了!为什么呢?因为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的查询艺术

上一篇下一篇

猜你喜欢

热点阅读