Android数据库高手秘籍(五)——LitePal的存储操作

电力现货交易市场-报价方式 电是一种能源,也是一种商品,既然是商品自然可以在市场中进行自由交易。 阅读详情

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

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

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

传统的存储数据方式

其实最传统的存储数据方式肯定是通过SQL语句拼接字符串来进行存储的,不过这种方式有点过于“传统”了,今天我们在这里就不讨论这种情况。实际上,Android专门提供了一种用于存储数据的简便方法,使得我们不用编写SQL语句就可以执行存储操作。下面来看一下SQLiteDatabase中的insert()方法:

[java]  view plain copy
  1. public long insert(String table, String nullColumnHack, ContentValues values)  
可以看到,insert方法接收三个参数,第一个参数是表名,第二个参数通常都用不到,直接传null,第三个参数则是一个封装了待存储数据的ContentValues对象。因此,比如说我们想往news表中插入一条新闻,就可以这样写:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. SQLiteDatabase db = dbHelper.getWritableDatabase();  
  2. ContentValues values = new ContentValues();  
  3. values.put("title", "这是一条新闻标题");  
  4. values.put("content", "这是一条新闻内容");  
  5. values.put("publishdate", System.currentTimeMillis());  
  6. long id = db.insert("news", null, values);  
其中,调用ContentValues的put()方法来添加待存储数据,put()方法接收两个参数,第一个参数是数据库表中对应的列名,第二个参数就是要存储的值,最后调用一下insert()方法,这条新闻就会插入到news表当中了,并且该数据行对应的id会作为返回值进行返回。

用法很简单是吗?确实,比起直接使用SQL语句,SQLiteDatabase中提供的insert()方法的确简单了很多。但insert()方法也并非是那么的完美,它还是有很多不方便的地方的,比如说没有考虑表关联的情况,我们需要手动对关联表的外键进行存储。再比如说,没有提供批量存储的功能,当我们有一个集合的数据需要存储时,需要通过循环来遍历这个集合,然后一次次地调用insert()方法来插入数据。

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

使用LitePal存储数据

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

在前面几篇文章当中,我们在项目里已经建好了News、Comment、Introduction、Category这几个实体类,通过这些实体类,LitePal就可以把相应的表自动创建出来。现在来观察这几个实体类,我们发现这几个类都是没有继承结构的。没错,因为LitePal进行表管理操作时不需要这些实体类有任何的继承结构,当时为了简单起见就没有写。但是进行CRUD操作时就不行了,LitePal要求所有的实体类都要继承自DataSupport这个类,因此这里我们就要把继承结构给加上才行。修改News类的代码,如下所示:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class News extends DataSupport{  
  2.       
  3.     ......  
  4.       
  5.     // 自动生成get、set方法  
  6. }  
可以看到,这里只是让News类继承自了DataSupport,其它什么都没有改变。另外几个Comment、Introduction、Category类也使用同样的改法,这里就不一一演示了。

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. News news = new News();  
  2. news.setTitle("这是一条新闻标题");  
  3. news.setContent("这是一条新闻内容");  
  4. news.setPublishDate(new Date());  
  5. news.save();  
怎么样?是不是非常简单,不需要SQLiteDatabase,不需要ContentValues,不需要通过列名组装数据,甚至不需要指定表名,只需要new出一个News对象,然后把要存储的数据通过setter方法传入,最后调用一下save()方法就好了,而这个save()方法自然就是从DataSupport类中继承而来的了。

除此之外,save()方法还是有返回值的,我们可以根据返回值来判断存储是否成功,比如说这样写:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (news.save()) {  
  2.     Toast.makeText(context, "存储成功", Toast.LENGTH_SHORT).show();  
  3. } else {  
  4.     Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show();  
  5. }  
可以看出,save()方法返回的是一个布尔值,用于表示存储成功还是失败,但同时也说明这个方法是不会抛出异常的。有些朋友希望如果存储失败的话就抛出异常,而不是返回一个false,那就可以使用saveThrows()方法来代替,如下所示:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. News news = new News();  
  2. news.setTitle("这是一条新闻标题");  
  3. news.setContent("这是一条新闻内容");  
  4. news.setPublishDate(new Date());  
  5. news.saveThrows();  
使用saveThrows()方法来存储数据,一旦存储失败就会抛出一个DataSupportException异常,我们可以通过对这个异常进行捕获来处理存储失败的情况。

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. News news = new News();  
  2. news.setTitle("这是一条新闻标题");  
  3. news.setContent("这是一条新闻内容");  
  4. news.setPublishDate(new Date());  
  5. Log.d("TAG", "news id is " + news.getId());  
  6. news.save();  
  7. Log.d("TAG", "news id is " + news.getId());  
在save之前打印一下news的id,在save之后再打印一次,现在运行一下,打印结果如下所示:


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


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

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

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Comment comment1 = new Comment();  
  2. comment1.setContent("好评!");  
  3. comment1.setPublishDate(new Date());  
  4. comment1.save();  
  5. Comment comment2 = new Comment();  
  6. comment2.setContent("赞一个");  
  7. comment2.setPublishDate(new Date());  
  8. comment2.save();  
  9. News news = new News();  
  10. news.getCommentList().add(comment1);  
  11. news.getCommentList().add(comment2);  
  12. news.setTitle("第二条新闻标题");  
  13. news.setContent("第二条新闻内容");  
  14. news.setPublishDate(new Date());  
  15. news.setCommentCount(news.getCommentList().size());  
  16. news.save();  
可以看到,这里先是存储了一条comment1数据,然后存储一条comment2数据,接着在存储News之前先把刚才的两个Comment对象添加到了News的commentList列表当中,这样就表示这两条Comment是属于这个News对象的,最后再把News存储到数据库中,这样它们之间的关联关系就会自动建立了。让我们查看数据库表检查一下吧,首先看一下news表,如下所示:


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


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

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. List<News> newsList;  
  2. ...  
  3. for (News news : newsList) {  
  4.     news.save();  
  5. }  
通过一个循环来遍历出这个集合中的每一个News对象,然后逐个调用save()方法。这样的写法当然是可以的,但是效率会比较低,因为调用save()方法的时候除了会执行存储操作之外,还会去分析News类的关联关系,那么每次循环都去重新分析一遍关联关系显然是比较耗时的。因此,LitePal提供了一个saveAll()方法,专门用于存储集合数据的,用法如下所示:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. List<News> newsList;  
  2. ...  
  3. DataSupport.saveAll(newsList);  
saveAll()方法接收一个Collection集合参数,只要把待存储的集合数据传入即可。这个方法可以完成和上面一段代码完全一样的功能,但效率却会高得多,而且写法也更加简单。

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

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

详解【异质图卷积网络 RGCN】回顾:图神经网络问题的三大处理步骤 | 从起源说起,RGCN核心公式解释,两种降低模型参数量/优化的方式,附核心代码实现讲解 本篇,我们深入分析和学习RGCN的原理以及为何要这么做。首先让我们来回顾对于图神经网络问题的三大处理步骤,可以说,这是该深度学习模型的基本理解,后续都是在深化其中的细节处理。然后以容易理解的方式,引出异质图卷积网络RGCN的由来,主要讲解其核心公式和论文中作者所提出的两种降低模型参数量/优化的处理办法,并给出基础分解以及块对角分解的核心实现代码讲解。最后附上RGCN源代码及说明。 阅读详情

相关推荐

CentOS 7环境下GLPI与OCS Inventory资产管理系统集成部署指南

本文详细介绍了在CentOS 7环境下,如何将GLPI与OCS Inventory两大开源工具进行集成部署,构建自动化资产管理系统。指南涵盖环境准备、核心服务安装、Web界面初始化、OCS插件配置及资产同步实战,帮助运维人员实现IT资产的自动发现、统一管理与可视化,大幅提升资产管理效率。

weixin_29274337的博客 326

LitePal使用遇到的坑

LitePal的使用看郭神的帖子就差不多了,简间易用,上手快。这是它的链接 http://blog.youkuaiyun.com/guolin_blog/article/details/38461239 我跟大家分享的是在使用中遇到的一些坑: 1. android.database.sqlite.SQLiteException: Can't downgrade database from v

liuyu0915的博客 1万+

C语言—for循环打印矩形,正三角形,倒三角形,九九乘法,等腰三角形,倒着的等腰三角形(简易版代码)(重点考察for循环嵌套)

本章节教大家如何利用for循环打印正三角形,倒三角形,九九乘法表及等腰三角形(简易版代码)说明:1、循环语句的循环体内又包含另一个完整的循环结构,称为循环结构的嵌套。内嵌的循环语句中还可以再嵌套循环结构,这样就形成多重循环结构的嵌套。2、for 语句、while 语句和 do-while 语句都允许嵌套。三种循环语句可以相互嵌套。3、内层的循环语句必须完全被包含在外层的循环体中,不能发生交叉。

m0_63501145的博客 1695

Android Studio使用Litepal方法以及遇到的坑

为什么要写呢:以前Eclipse使用的时候遇到问题没总结,现在就想写下来,告诉大家不要走我的老路!!!!走老坑!!!! 1.首先需要引用Litepal implementation 'org.litepal.android:core:1.4.1' 这个都没啥问题。 2.创建litepal.xml文件在assets文件下,这个在创建的时候选择file就是了,然后文件结尾自己加上.xml就好了 3.创建的实体类集成DataSupport,然后在litepal.xml中把bean添加进去,要具体的路径

csdn_zxw的博客 2344

发那科FOCAS 1/2文档——核心库文件

在开始开发前,明确目标 CNC 的具体型号、连接方式(HSSB/TCP/IP)、软件版本和配置(如轴数、程序号位数),并据此正确配置开发环境和编译选项。开发时需要包含相应的头文件。这是开发跨平台应用时需要特别注意的地方。这是开发应用时必须了解的核心文件。

snailiot的博客 1021

PCRNet: Point Cloud Registration Network using PointNet Encoding

PCRNet算是在ModelNet40这种object-centric数据集上用deep-learning做配准最好入手的一篇文章了,整体架构涉及简洁明了,一句话描述就是简单粗暴,话不多说,直接上网络架构图: Work Flow: 首先对输入source (N×3N \times 3N×3)与template (M×3M \times 3M×3)进行PointNet操作,即MLP + max-pooling后,分别得到描述各自点云的维度为1024的global feature vector:Φ(PS).

dloading7的博客 1647

Android使用LitePal时所遇到的问题及解决办法

在阅读《第一行代码》学习LitePal操作数据库时遇到了问题,以下是所遇到的问题及解决办法: 问题1:javabean无法继承自DataSupport 在《第一行代码》中我们若想使用LitePal进行CRUD操作的话需要为Book类继承自DataSupport,但是输入代码后报错,查看报错信息后发现原来DataSupport已经被弃用,通过查阅GitHub上LitePal官网中的最新版本的使用说...

qq_36271550的博客 4727

Halcon工业相机开发全流程:从SDK配置到实时图像采集(C++版)

本文详细介绍了使用C++进行Halcon工业相机开发的完整流程,从SDK配置到实时图像采集的实现。涵盖环境搭建、设备初始化、回调机制、参数控制等关键环节,并提供异常处理和实战案例,帮助开发者快速掌握工业视觉系统的开发技巧。

weixin_33728268的博客 512

Android数据库开发 LitePal的使用详解(2)

Android数据库开发增删改查等操作

weixin_42703246的博客 2271

【详细】芯片设计全流程(包括每个流程需要用到的工具以及需要参与的工作人员)

一颗芯片的诞生经历了设计、制造和测试(分别对应集成电路产业链的设计业、制造业和封测业),而每一步都包含了复杂的步骤和流程。 图0-1 集成电路产业链 现在,我们重点介绍芯片设计的全流程以及每个流程需要用到的设计工具和需要参与的工作人员。 一、IC设计分类 首先对IC设计的分类做个介绍,如图1-1所示。 图1-1 IC设计分类 如图1-1所示,IC设计可以粗分为数字IC设计和射频/模拟IC设计,数字IC设计又可分为ASIC设计和FPGA/CPLD设计,此外还有一部分IC设计.

qq_36045093的博客 8万+

刷机维修进阶教程-----adb禁用错了系统app导致无法开机 如何保数据无损恢复机型

在刷机维修过程中 。我们会遇到一些由于客户使用adb指令来禁用手机app而导致手机无法开机进入系统的故障机型。通常此类问题机型有好几种解决方法。但如果客户需要保数据来恢复机型。其实操作也是很简单的.还有类似误删除应用导致不开机等等如何保数据。  通过博文了解💝💝💝    1💝💝💝----adb禁用或者删除系统app导致无法开机的几种解决方法 2💝💝💝----如何保数据来无损恢复机型 3💝💝💝----其他保数据解决系统类故障无法开机的步骤解析

小马哥的专栏 1352

Android数据库高手秘籍 五 ——LitePal的存储操作

Android数据库高手秘籍 五 ——LitePal的存储操作

hfdhjjj的博客 207

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: Android数据库高手秘籍(四)——使用LitePal建立表关联
下一篇: Android数据库高手秘籍(六)——LitePal的修改和删除操作
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值