转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/39345833

经过前面几篇文章的学习,我们已经把LitePal的表管理模块的功能都非常好地掌握了,相信大家都已经体会到了使用LitePal来创建表、升级表、以及建立表关联所带来的便利。那么从本篇文章開始,我们将进入到一个新模块的学习旅程其中,使用LitePal来进行表的CRUD操作。还没有看过前一篇文章的朋友建议先去參考 Android数据库高手秘籍(四)——使用LitePal建立表关联

LitePal提供的CRUD操作的API还是颇为丰富的,一篇文章肯定是介绍不全的。因此这里我们仍然是分几篇文章进行解说,本篇主要是介绍存储方面的API。

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

传统的存储数据方式

事实上最传统的存储数据方式肯定是通过SQL语句拼接字符串来进行存储的,只是这样的方式有点过于“传统”了。今天我们在这里就不讨论这样的情况。

实际上,Android专门提供了一种用于存储数据的简便方法,使得我们不用编写SQL语句就能够运行存储操作。以下来看一下SQLiteDatabase中的insert()方法:

public long insert(String table, String nullColumnHack, ContentValues values)

能够看到。insert方法接收三个參数,第一个參数是表名,第二个參数通常都用不到,直接传null,第三个參数则是一个封装了待存储数据的ContentValues对象。因此,比方说我们想往news表中插入一条新闻,就能够这样写:

SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("title", "这是一条新闻标题");
values.put("content", "这是一条新闻内容");
values.put("publishdate", System.currentTimeMillis());
long id = db.insert("news", null, values);

其中,调用ContentValues的put()方法来加入待存储数据,put()方法接收两个參数,第一个參数是数据库表中相应的列名,第二个參数就是要存储的值,最后调用一下insert()方法。这条新闻就会插入到news表其中了,而且该数据行相应的id会作为返回值进行返回。

使用方法非常easy是吗?确实,比起直接使用SQL语句,SQLiteDatabase中提供的insert()方法的确简单了非常多。但insert()方法也并不是是那么的完美,它还是有非常多不方便的地方的,比方说没有考虑表关联的情况,我们须要手动对关联表的外键进行存储。

再比方说,没有提供批量存储的功能,当我们有一个集合的数据须要存储时。须要通过循环来遍历这个集合。然后一次次地调用insert()方法来插入数据。

好了。那么关于传统存储数据的使用方法就简介到这里,由于确实没什么的很多其它的使用方法了,而且它也不是我们今天的主角。接下来。就让我们看一看今天的惊喜,学习如何使用LitePal来进行数据库存储的操作。

使用LitePal存储数据

LitePal中与存储相关的API事实上并不多。但使用方法还是颇为丰富的。而且比起传统的insert()方法。使用LitePal来存储数据能够简单到让你惊叹的地步,那么今天我们就来完整地学习一下LitePal存储数据的全部使用方法。

在前面几篇文章其中,我们在项目里已经建好了News、Comment、Introduction、Category这几个实体类,通过这些实体类,LitePal就能够把相应的表自己主动创建出来。

如今来观察这几个实体类。我们发现这几个类都是没有继承结构的。没错,由于LitePal进行表管理操作时不须要这些实体类有不论什么的继承结构,当时为了简单起见就没有写。可是进行CRUD操作时就不行了。LitePal要求全部的实体类都要继承自DataSupport这个类。因此这里我们就要把继承结构给加上才行。改动News类的代码。例如以下所看到的:

public class News extends DataSupport{

	......

	// 自己主动生成get、set方法
}

能够看到,这里仅仅是让News类继承自了DataSupport,其它什么都没有改变。

另外几个Comment、Introduction、Category类也使用相同的改法,这里就不一一演示了。

继承了DataSupport类之后,这些实体类就拥有了进行CRUD操作的能力,那么比方想要存储一条数据到news表其中,就能够这样写:

News news = new News();
news.setTitle("这是一条新闻标题");
news.setContent("这是一条新闻内容");
news.setPublishDate(new Date());
news.save();

怎么样?是不是非常easy,不须要SQLiteDatabase。不须要ContentValues,不须要通过列名组装数据。甚至不须要指定表名,仅仅须要new出一个News对象。然后把要存储的数据通过setter方法传入,最后调用一下save()方法就好了。而这个save()方法自然就是从DataSupport类中继承而来的了。

除此之外。save()方法还是有返回值的。我们能够依据返回值来推断存储是否成功。比方说这样写:

if (news.save()) {
Toast.makeText(context, "存储成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show();
}

能够看出,save()方法返回的是一个布尔值,用于表示存储成功还是失败,但同一时候也说明这种方法是不会抛出异常的。

有些朋友希望假设存储失败的话就抛出异常,而不是返回一个false,那就能够使用saveThrows()方法来取代,例如以下所看到的:

News news = new News();
news.setTitle("这是一条新闻标题");
news.setContent("这是一条新闻内容");
news.setPublishDate(new Date());
news.saveThrows();

使用saveThrows()方法来存储数据,一旦存储失败就会抛出一个DataSupportException异常。我们能够通过对这个异常进行捕获来处理存储失败的情况。

那有些细心的朋友可能已经注意到。使用的insert()方法来存储数据时是有返回值的。返回的是插入行相应的id。但LitePal中的save()方法返回的是布尔值,那么我们如何才干拿到存储成功之后这条数据相应的id呢?对此。LitePal使用了一种非常巧妙的做法。还记得我们在每个实体类中都定义了一个id字段吗?当调用save()方法或saveThrows()方法存储成功之后。LitePal会自己主动将该条数据相应的id赋值到实体类的id字段上。让我们来做个试验吧。代码例如以下所看到的:

News news = new News();
news.setTitle("这是一条新闻标题");
news.setContent("这是一条新闻内容");
news.setPublishDate(new Date());
Log.d("TAG", "news id is " + news.getId());
news.save();
Log.d("TAG", "news id is " + news.getId());

在save之前打印一下news的id,在save之后再打印一次,如今运行一下,打印结果例如以下所看到的:

OK。在save之前打印的id是0,说明此时id这个字段还没有被赋值,在save之后打印的id是1,说明此时id已经被赋值了。那么我们再到数据库表中再查看一下这条记录究竟有没有存储成功吧,例如以下图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvbGluX2Jsb2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

能够看到,这条新闻确实已经存储成功了,而且相应的id正是1。和我们前面打印的结果是一致的。

只是LitePal的存储功能显示不仅仅仅仅有这些使用方法,事实上。LitePal在存储数据的时候默默帮我们做了非常多的事情,比方多个实体类之间有关联关系的话,我们不须要考虑在存储数据的时候怎么去建立数据与数据之间的关联,由于LitePal一切都帮我们做好了。

还是通过一个样例来看一下吧,Comment和News之间是多对一的关系,一条News中是能够包括多条评论的,因此我们就能够这样写:

Comment comment1 = new Comment();
comment1.setContent("好评!");
comment1.setPublishDate(new Date());
comment1.save();
Comment comment2 = new Comment();
comment2.setContent("赞一个");
comment2.setPublishDate(new Date());
comment2.save();
News news = new News();
news.getCommentList().add(comment1);
news.getCommentList().add(comment2);
news.setTitle("第二条新闻标题");
news.setContent("第二条新闻内容");
news.setPublishDate(new Date());
news.setCommentCount(news.getCommentList().size());
news.save();

能够看到,这里先是存储了一条comment1数据,然后存储一条comment2数据,接着在存储News之前先把刚才的两个Comment对象加入到了News的commentList列表其中,这样就表示这两条Comment是属于这个News对象的。最后再把News存储到数据库中,这样它们之间的关联关系就会自己主动建立了。让我们查看数据库表检查一下吧,首先看一下news表。例如以下所看到的:

OK,第二条新闻已经成功存储到news表中了。这条新闻的id是2。那么从哪里能够看出来关联关系呢?我们在上一篇文章中学过,多对一关联的时候,外键是存放在多方的,因此关联关系我们要到comment表中去查看。例如以下所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvbGluX2Jsb2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

能够看到,两条评论都已经成功存储到comment表中了。而且这两条评论的news_id都是2,说明它们是属于第二条新闻的。怎么样,仅仅是在存储数据之前建立好实体类之间的关系,再调用一下save()方法,那么数据之间的关联关系就会自己主动建立了。是不是非常easy?上面的代码仅仅是多对一情况的一种使用方法,另一对一和多对多的情况,其有使用方法都是差点儿相同的,相信你已经能举一反三了。

另外,LitePal对集合数据的存储还专门提供了一个方法。比方说我们有一个News集合。那么应该如何去存储这个集合中的每条News呢?传统情况下能够这样写:

List<News> newsList;
...
for (News news : newsList) {
news.save();
}

通过一个循环来遍历出这个集合中的每个News对象,然后逐个调用save()方法。

这样的写法当然是能够的。可是效率会比較低,由于调用save()方法的时候除了会运行存储操作之外。还会去分析News类的关联关系,那么每次循环都去又一次分析一遍关联关系显然是比較耗时的。因此,LitePal提供了一个saveAll()方法,专门用于存储集合数据的。使用方法例如以下所看到的:

List<News> newsList;
...
DataSupport.saveAll(newsList);

saveAll()方法接收一个Collection集合參数。仅仅要把待存储的集合数据传入就可以。这种方法能够完毕和上面一段代码全然一样的功能,但效率却会高得多,而且写法也更加简单。

好了,这样我们就把LitePal中提供的存储操作的使用方法全部都学完了。那么今天的文章就到这里。下一篇文章其中会開始解说更新和删除操作的使用方法。感兴趣的朋友请继续阅读 Android数据库高手秘籍(六)——LitePal的改动和删除操作 。

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

第一时间获得博客更新提醒。以及很多其它技术信息分享,欢迎关注我的微信公众号,扫一扫下方二维码或搜索微信号guolin_blog。就可以关注。

Android数据库高手秘籍(五)——LitePal的存储操作的更多相关文章

  1. Android数据库高手秘籍(六)——LitePal的改动和删除操作

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/40083685 在上一篇文章中,我们学会了使用LitePal进行存储数据的功能.确实 ...

  2. Android数据库高手秘籍(二):创建表和LitePal的基本用法

    原文:http://blog.jobbole.com/77157/ 上一篇文章中我们学习了一些Android数据库相关的基础知识,和几个颇为有用的SQLite命令,都是直接在命令行操作的.但是我们都知 ...

  3. Android数据库高手秘籍(三)——使用LitePal升级表

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/39151617 在上一篇文章中,我们学习了LitePal的基本使用方法,体验了使用框 ...

  4. Android数据库高手秘籍(一)——SQLite命令

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/38461239 要想熟练地操作不论什么一个数据库.最最主要的要求就是要懂SQL语言, ...

  5. Android数据库高手秘籍(零)——前言

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/38083103 在我刚開始接触Android的时候甚至都不敢相信.Android系统 ...

  6. Android数据库高手秘籍:SQLite命令

    要想熟练地操作任何一个数据库,最最基本的要求就是要懂SQL语言,这也是每个程序员都应该掌握的技能.虽说SQL博大精深,要想精通确实很难,但最基本的一些建表命令,增删改查,大家还是必须要学会的. SQL ...

  7. Android数据库专家秘籍(七)经验LitePal查询艺术

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/40153833 经过了多篇文章的学习,我们已经把LitePal中的绝大部分内容都掌握 ...

  8. Android中常用的五种数据存储方式

    第一种: 使用SharedPreferences存储数据 适用范围: 保存少量的数据,且这些数据的格式非常简单:字符串型.基本类型的值.比如应用程序的各种配置信息(如是否打开音效.是否使用震动效果.小 ...

  9. LitePal的存储操作

    传统的存储数据方式   其实最传统的存储数据方式肯定是通过SQL语句拼接字符串来进行存储的,不过这种方式有点过于“传统”了,今天我们在这里就不讨论这种情况.实际上,Android专门提供了一种用于存储 ...

随机推荐

  1. ZOJ 3829 贪心 思维题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...

  2. perl 异步超时 打印错误

    #!/usr/bin/perl use AnyEvent; use AnyEvent::HTTP; my $cv = AnyEvent->condvar; sub doit{ my $url = ...

  3. HealthKit教程 Swift版:锻炼信息

    原文:HealthKit Tutorial with Swift: Workouts 作者:Ernesto García 译者:Mr_cyz ) 欢迎回到我们的HealthKit系列教程! 在我们系列 ...

  4. Delphi的类型转换 good

    Delphi是一种强类型转换的语言.在VC中,赋值符用″=″,例如x=1;到了Delphi赋值符就变成了″:=″,例如x:=1. 从赋值时用符号″:=″而不用″=″,就隐约可见Delphi对类型匹配要 ...

  5. DB2错误码解释对照

    表 2. SQLSTATE 类代码 类  代码    含义 要获得子代码,  参阅...  00 完全成功完成 表 3  01 警告 表 4  02 无数据 表 5  07 动态 SQL 错误 表 6 ...

  6. 旧发票要保留SIRET等信息,或者整个PDF

    查看旧发票时,每次都实时生成发票是不行的,因为公司的SIRET居然会是变的!!

  7. TComponent明明实现了IDispatch接口,但是却不加上声明,难道是因为FVCLComObject实体对象不存在?

    TComponent明明实现了IDispatch接口,可是它的声明却是: TComponent = class(TPersistent, IInterface, IInterfaceComponent ...

  8. [Android学习笔记]Canvas的使用

    Canvas文档 http://developer.android.com/training/index.html 在绘制view时候,重写onDraw(canvas)方法,可能需要在canvas上绘 ...

  9. iOS 如何创建单例对象

    一.什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了iOS的行列. 算了,入正轨,我现在正是铁树银花的青春美少女, ...

  10. SharePoint 内容部署-PowerShell

    1. 创建一个新的内容部署路径 New-SPContentDeploymentPath –Name "Marketing Internet Content" –SourceSPWe ...