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

在上一篇文章中,咱们学会了使用LitePal进行存储数据的功能。确实,比起直接使用Android原生的API,LitePal明显简单方便了太多。那么,在增删改查四种操做中,咱们已经把“增”学完了,今天就让咱们继续趁热打铁,学习一下如何使用LitePal进行修改和删除操做。尚未看过前一篇文章的朋友建议先去参考 Android数据库高手秘籍(五)——LitePal的存储操做 。java

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

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

上篇文章中咱们已经得知,SQLiteDatabase类中提供了一个insert()方法用于插入数据,那么相似地,它还提供了update()和delete()这两个方法,分别用于修改和删除数据。先来看一下update()方法的方法定义:github

[java] view plaincopy在CODE上查看代码片派生到个人代码片sql

  1. public int update(String table, ContentValues values, String whereClause, String[] whereArgs)  数据库

update()方法接收四个参数,第一个参数是表名,第二个参数是一个封装了待修改数据的ContentValues对象,第三和第四个参数用于指定修改哪些行,对应了SQL语句中的where部分。数组

那么好比说咱们想把news表中id为2的记录的标题改为“今日iPhone6发布”,就能够这样写:svg

[java] view plaincopy在CODE上查看代码片派生到个人代码片学习

  1. SQLiteDatabase db = dbHelper.getWritableDatabase();  spa

  2. ContentValues values = new ContentValues();  .net

  3. values.put("title""今日iPhone6发布");  

  4. db.update("news", values, "id = ?"new String[] {"2"});  

其做用至关于以下SQL语句:

[sql] view plaincopy在CODE上查看代码片派生到个人代码片

  1. update news set title='今日iPhone6发布' where id=2;  

能够看出,比起直接使用SQL语句,update()方法的语义性明显更强,也更容易让人理解。

接下来再看一下delete()方法的方法定义:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. public int delete(String table, String whereClause, String[] whereArgs)  

delete()方法接收三个参数,第一个参数一样是表名,第二和第三个参数用于指定删除哪些行,对应了SQL语句中的where部分。

那么好比说咱们想把news表中全部没有评论的新闻都删除掉,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. SQLiteDatabase db = dbHelper.getWritableDatabase();  

  2. db.delete("news""commentcount = ?"new String[] {"0"});  

其做用至关于以下SQL语句:

[sql] view plaincopy在CODE上查看代码片派生到个人代码片

  1. delete from news where commentcount=0;  

因而可知,Android给咱们提供的这些帮助方法,在很大程度上确实简化了很多数据库操做的复杂度。不过LitePal显然作到了更好,下面就让咱们学习一下如何使用LitePal来进行修改和删除操做。

使用LitePal修改数据

LitePal修改数据的API比较简单,并无什么太多的用法,也比较好理解,方法都是定义在DataSupport类中的,咱们先来看一下方法定义:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. public static int update(Class<?> modelClass, ContentValues values, long id)  

这个静态的update()方法接收三个参数,第一个参数是Class,传入咱们要修改的那个类的Class就好,第二个参数是ContentValues对象,这三个参数是一个指定的id,表示咱们要修改哪一行数据。

那么好比说咱们想把news表中id为2的记录的标题改为“今日iPhone6发布”,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. ContentValues values = new ContentValues();  

  2. values.put("title""今日iPhone6发布");  

  3. DataSupport.update(News.class, values, 2);  

能够看出,整体来说仍是比原生的用法要简单一些的,首先咱们避免掉了要去获取SQLiteDatabase对象的步骤,其次在指定修改某一条id记录的时候只须要传入这个id便可,语法更简练。

那么有的朋友可能会问了,也许我想修改的是某一个条件下的全部数据,而不是仅仅修改某个id的数据,那该怎么办呢?别担忧,LitePal还提供了另一个简便的方法,方法定义以下:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. public static int updateAll(Class<?> modelClass, ContentValues values, String... conditions)  

updateAll()方法表示修改多行记录,其中第一个参数仍然是Class,第二个参数仍是ContentValues对象,第三个参数是一个conditions数组,用于指定修改哪些行的约束条件,返回值表示这次修改影响了多少行数据。

那么好比说咱们想把news表中标题为“今日iPhone6发布”的全部新闻的标题改为“今日iPhone6 Plus发布”,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. ContentValues values = new ContentValues();  

  2. values.put("title""今日iPhone6 Plus发布");  

  3. DataSupport.updateAll(News.class, values, "title = ?""今日iPhone6发布");  

前面都没什么好说的,重点咱们看一下最后的这个conditions数组,因为它的类型是一个String数组,咱们能够在这里填入任意多个String参数,其中最前面一个String参数用于指定约束条件,后面全部的String参数用于填充约束条件中的占位符(即?号),好比约束条件中有一个占位符,那么后面就应该填写一个参数,若是有两个占位符,后面就应该填写两个参数,以此类推。

好比说咱们想把news表中标题为“今日iPhone6发布”且评论数量大于0的全部新闻的标题改为“今日iPhone6 Plus发布”,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. ContentValues values = new ContentValues();  

  2. values.put("title""今日iPhone6 Plus发布");  

  3. DataSupport.updateAll(News.class, values, "title = ? and commentcount > ?""今日iPhone6发布""0");  

能够看出,经过占位符的方式来实现条件约束明显要比原生的API更加简单易用。

那么若是咱们想把news表中全部新闻的标题都改为“今日iPhone6发布”,该怎么写呢?其实这就更简单了,只须要把最后的约束条件去掉就好了,以下所示:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. ContentValues values = new ContentValues();  

  2. values.put("title""今日iPhone6 Plus发布");  

  3. DataSupport.updateAll(News.class, values);  

怎么样,这种写法是否是感受语义性很是强?updateAll()方法在不指定约束条件的状况下就是修改全部行的数据,的的确确是update all了。

固然有些朋友可能会以为这样用起来仍是有点复杂,由于这个ContentValues对象很烦人,每次建立它的时候都要写不少繁琐的代码。不要紧,LitePal也充分考虑了这种状况,提供了一种不须要ContentValues就能修改数据的方法,下面咱们尝试使用这种新方法来完成上述一样的功能。

好比把news表中id为2的记录的标题改为“今日iPhone6发布”,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News updateNews = new News();  

  2. updateNews.setTitle("今日iPhone6发布");  

  3. updateNews.update(2);  

此次咱们并无用ContentValues,而是new出了一个News对象,把要修改的数据直接set进去,最后调用一下update()方法并传入id就能够了。不只不用建立ContentValues对象,连表名都不用指定了,由于News对象默认就是修改的news表。

这是其中一种用法,那么若是咱们想把news表中标题为“今日iPhone6发布”且评论数量大于0的全部新闻的标题改为“今日iPhone6 Plus发布”,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News updateNews = new News();  

  2. updateNews.setTitle("今日iPhone6发布");  

  3. updateNews.updateAll("title = ? and commentcount > ?""今日iPhone6发布""0");  

仍是很是好理解的,这里我就再也不详细解释了。

可是这种用法有一点须要注意,就是若是咱们想把某一条数据修改为默认值,好比说将评论数修改为0,只是调用updateNews.setCommentCount(0)这样是不能修改为功的,由于即便不调用这行代码,commentCount的值也默认是0。因此若是想要将某一列的数据修改为默认值的话,还须要借助setToDefault()方法。用法也很简单,在setToDefault()方法中传入要修改的字段名就能够了(类中的字段名),好比说咱们想要把news表中全部新闻的评论数清零,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News updateNews = new News();  

  2. updateNews.setToDefault("commentCount");  

  3. updateNews.updateAll();  

使用LitePal删除数据

LitePal删除数据的API和修改数据是比较相似的,可是更加的简单一些,咱们先来看一下DataSupport类中的方法定义,以下所示:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. public static int delete(Class<?> modelClass, long id)  

delete()方法接收两个参数,第一个参数是Class,传入咱们要删除的那个类的Class就好,第二个参数是一个指定的id,表示咱们要删除哪一行数据。

那么好比说咱们想删除news表中id为2的记录,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. DataSupport.delete(News.class2);  

须要注意的是,这不只仅会将news表中id为2的记录删除,同时还会将其它表中以news id为2的这条记录做为外键的数据一块儿删除掉,由于外键既然不存在了,那么这么数据也就没有保留的意义了。

提及来可能有点拗口,咱们仍是举例看一下。好比news表中目前有两条数据,以下图所示:


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


其中comment表中两条数据的外键都是2,指向的news表中id为2的这条记录。那么下面咱们执行以下删除语句:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. int deleteCount = DataSupport.delete(News.class2);  

  2. Log.d("TAG""delete count is " + deleteCount);  

其中delete()方法的返回值表示被删除的记录数,打印结果以下所示:


能够看到,有三条记录被删除了,那咱们再到news表中查询一下:


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


数据全没了!为何呢?由于comment表中的两条数据都是以news表中id为2的数据做为外键的,如今外键不存在了,那么这两条数据天然也没有存在的意义了,所以被删除的记录数一共是3条。这样是否是就好理解了不少呢?

除了删除指定id的数据以外,DataSupport中也提供了一个经过where语句来批量删除数据的方法,先看一下方法定义:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. public static int deleteAll(Class<?> modelClass, String... conditions)  

看起来很眼熟吧?很是简单,deleteAll()方法接收两个参数,第一个参数是Class,传入咱们要删除的那个类的Class就好,第二个参数是一个conditions数组,用于指定删除哪些行的约束条件,返回值表示这次删除了多少行数据,用法和updateAll()方法是基本相同的。

那么好比说咱们想把news表中标题为“今日iPhone6发布”且评论数等于0的全部新闻都删除掉,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. DataSupport.deleteAll(News.class"title = ? and commentcount = ?""今日iPhone6发布""0");  

而若是咱们想把news表中全部的数据所有删除掉,就能够这样写:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. DataSupport.deleteAll(News.class);  

在不指定约束条件的状况下,deleteAll()方法就会删除表中全部的数据了。

除了DataSupport类中提供的静态删除方法以外,还有一个删除方法是做用于对象上的,即任何一个继承自DataSupport类的实例均可以经过调用delete()这个实例方法来删除数据。但前提是这个对象必定是要持久化以后的,一个非持久化的对象若是调用了delete()方法则不会产生任何效果。

好比说下面这种写法:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News news = new News();  

  2. news.delete();  

这里new出了一个News对象,这个对象明显是没有持久化的,那么此时调用delete()方法则不会删除任何数据。

但若是咱们以前将这个对象持久化过了,那么再调用delete()方法就会把这个对象对应的数据删除掉了,好比:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News news = new News();  

  2. news.setTitle("这是一条新闻标题");  

  3. news.setContent("这是一条新闻内容");  

  4. news.save();  

  5. ...  

  6. news.delete();  

一个对象若是save过了以后,那就是持久化的了。除了调用save()方法以外,经过DataSupport中提供的查询方法从数据库中查出来的对象也是通过持久化的,查询的功能咱们会在下篇博客中讲解。

另外还有一个简单的办法能够帮助咱们判断一个对象是不是持久化以后的,DataSupport类中提供了一个isSaved()方法,这个方法返回true就表示该对象是通过持久化的,返回false则表示该对象未通过持久化。那么删除一个对象对应的数据也就能够这样写了:

[java] view plaincopy在CODE上查看代码片派生到个人代码片

  1. News news;  

  2. ...  

  3. if (news.isSaved()) {  

  4.     news.delete();  

  5. }  

好了,这样咱们就把LitePal中提供的修改和删除数据操做的用法基本都学习完了,那么今天的文章就到这里,下一篇文章中会开始讲解查询数据的用法,感兴趣的朋友请继续阅读 Android数据库高手秘籍(七)——体验LitePal的查询艺术 。

LitePal开源项目地址:https://github.com/LitePalFramework/LitePal

相关文章
相关标签/搜索