分类:C#、Android、VS2015;

创建日期:2016-02-26

一、简介

Android 内置了三种数据存取方式:SQLite数据库、文件、SharedPreferences。

这一章我们主要学习如何使用SQLite数据库存取数据。

1、SQLite是个什么档次的数据库

SQLite是一种免费的、开源的数据库,由于它独特的设计(把各种数据类型都转换为它自己内部处理的5种类型)导致其占用内存极少,因此很多项目都喜欢使用它。

Android集成了SQLite并内置了专门对SQLite操作的API,因此开发人员可在手机应用程序中直接使用它。

本章示例演示的是SQLite3,该版本内部仅有NULL、INTEGER、REAL(浮点数)、TEXT(字符串)、BLOB(二进制对象)共5种数据类型。换言之,它所处理的各种SQL数据类型保存时都会在内部自动转换为这5种数据类型,由于SQLite这种独特的设计,使它占用的内存极少且可移植性高,但是,也正因为如此,它提供的功能也很有限(只提供了最基本的数据库操作),这也是为什么说它仅是一种轻量级的数据库,非常适合于在嵌入式和移动应用开发中使用的原因。

如果将大型数据库(Oracle、SQL Server、DB2等)和SQLite相比,可以将前者理解为是一个“大型超市”,各种商品从低档到高档应有尽有,但占用的空间也大;而后者则是一个“小超市”,它仅销售大家喜欢的最基本最常用的商品,因此占用的空间也少。

但是,如果你希望它像大型超市一样什么东西都有,那你还是直接到大型超市去吧。

2、访问SQLite数据库的方式

用C#编写Android应用程序时,创建和访问SQLite数据库的方式非常多,这些都可以通过NuGet免费下载。这一章仅介绍几种最基本的方式。

(1)用Android内置的API实现

本章的【例13-1】、【例13-2】都是用这种方式实现的。

需要引用的命名空间:

using Android.Database;

using Android.Database.Sqlite;

这里需要说明一点,直接用SQL语法来构造SQL语句是最原始的实现方式,熟悉SQL语法的可能比较喜欢用这种方式。不过,用这种方式编写SQL语句实在是太费劲了,不但要记住各种SQL语法,而且查找SQL字符串中的错误也非常困难。特别是初学者,用这种方式编写出来的程序常常漏洞百出、bug一堆。

(2)用Xamarin提供的API实现

这是安装Xamarin for VS时内置的API,版本较早(1.0.66),利用它可通过ADO.NET访问sqlite数据库。上一章(第12章)的【例12-5】简单记事本功能就是用这种方式实现的。

早期版本需要引用的命名空间:

using Mono.Data.Sqlite;

新版本(1.0.99)支持.NET的各种版本,包括.NET 4.5、4.6以及LINQ、Entity Framework等,但目前尚不成熟,还在持续改进中,暂时先不使用它吧,等它完善了再玩也不晚。

新版本需要引用的命名空间:

using System.Data.Sql;

using System.Data.SqlClient;

(3)用sqlite-net实现

sqlite-net是用C#编写的操作SQLite数据库的轻量级的、开源的程序包,该程序包的C#源程序可直接通过NuGet直接下载到你的项目中。这个程序包最初的设计目的是为了用于操作iPhone应用程序中的SQlite的,但也可以在安卓应用程序中使用它。

sqlite-net的主要目标是设计一个快速而方便的数据库访问层。它是按照下面的这些原则来设计这个库的:

  • 易于集成现有项目和MonoTouch项目。
  • 对SQLite快速高效的轻量级包装(不会因为使用了它而引起查询的性能瓶颈)。
  • 提供简单方法来安全执行CRUD操作(即:创建、读取、更新、删除),以及通过检索强类型检索方式来执行可带参数的查询,并快速返回结果。
  • 内部包含一个轻量级的ORM反射驱动层,从而让你可以完全使用你自己定义的数据模型。

注意:sqlite-net并没有提供ADO.NET的完整实现,也没有提供SQLite的完整驱动。如果你需要这些,请使用Mono.Data.SQLite(即13.1介绍的内容)或者csharp-sqlite。

可利用NuGet免费下载sqlite-net程序包:

  • sqlite-net:容量很小(最新的1.0.8版本解压后也仅有143KB)
  • SQLiteNetExtensions:这个是sqlite-net的ORM扩展包(最新版本为1.3.0),支持1对1、1对n、n对1、n对n的关联操作。

但是,由于后来又出现了改进的SQLite.NET-PCL,所以这个用C# 3.0写的早期版本的sqlite-net就变得没用了。

(4)用SQLite.NET-PCL和SQLite.NET.Async-PCL实现

本章的【例13-3】、【例13-4】都是用这种方式实现的。

SQLite.Net-PCL在sqlte-net的基础上改进的程序包(最新的版本是3.1.1版),它除了支持同步和异步操作以外,还支持跨多种平台,例如Xamarin.Android、Xamarin.iOS(Classic)、Xamarin.iOS(Unified)、Windows Phone 8.1、Win8、Win10、……)等。

使用SQLite.Net-PCL时不需要下载sqlte-net。但是,为了区分原来的sqlte-net,这个包才又将其命名为SQLlite.NET-PCL。

PCL是英文“Portable Class Library”的缩写,含义是:用它设计的库可运行在Win8、Win10、Win32、Window Phone、monotouch、MonoAndroid、……等平台上。

SQLite.Net-PCL对sqlte-net的API做了一些修改。具体修改的地方有:

  • 修改了SQLiteConnection类,使其可以跨多个平台。
  • 提供了SQliteAsyncConnection,使其支持跨多个平台的异步操作。注意在这个类中,你编写的Task.Run模式的程序由SQLiteAsyncConnection来管理它。
  • 修改了DateTime的串行化实现,以便可让其支持多区域。如果你要获取本地化的DateTime,需要调用dateTime.ToLocalTime()。

总的来说,如果你希望编写可跨Android、iOS、Windows Phone、……等多个平台的数据库公共操作类,建议用它来实现。

3、其他说明

不论你使用哪种数据库,也不论你采用哪种技术,一定要始终记住一点:手机应用程序是一种客户端程序,没有网络编程的基础你很难去完整地理解它。特别是别指望在实际项目中把数据库直接塞到手机中,你不会迷糊到用一个手机去当作服务器给很多人提供服务吧。在实际的大型应用中,数据库都是专门的服务器(到底需要多少个服务器那要看应用的规模了),而客户端仅仅是通过网络间接地和数据库服务器打交道来存取手机中需要的极小的一部分数据而已。那么,通过网络直接建立连接的是谁呢?是应用服务器中的程序对外公开的服务或接口,比如Web Service、Web API、……等。

但是,作为例子,都是把数据库也弄到手机上或者你自己的程序中,这样你调试和理解起来方便,添加、删除、复制数据库也方便,毕竟是学学、玩玩的阶段,反正记住一句话就行了:万丈高楼不是从中间凭空盖起来的,你只有学会和理解了它的最基本的用法,先学会盖一个小啪啪屋,然后再研究如何一点一点增加楼层的高度才靠谱。

二、观察本项目引用和下载的程序包

1、观察引用的.dll文件命名空间

到这一章为止,MyDemos项目已经添加了下列引用:

2、packages.config文件

再看看到这一章为止本项目已经通过NuGet下载了哪些程序包。MyDemos项目根目录下packages.config文件的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SQLite.Net.Async-PCL" version="3.1.1" targetFramework="monoandroid60" />
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="monoandroid60" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v4" version="23.1.1.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.AppCompat" version="23.1.1.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.CardView" version="23.1.1.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.RecyclerView" version="23.1.1.0" targetFramework="monoandroid60" />
</packages>

三、本章示例主界面

1、运行截图

2、MainActivity.cs文件中本章对应的代码

chItems.Add(new Chapter()
{
ChapterName = "第13章 SQLite数据库访问",
ChapterItems = new ChItem[]
{
new ChItem { type=typeof(ch1301MainActivity), Title="例13-1 SQLite基本用法1-SimpleCursorAdapter", Desc = "演示如何用SimpleCursorAdapter访问SQLite数据库" },
new ChItem { type=typeof(ch1302MainActivity), Title="例13-2 SQLite基本用法2-自定义CursorAdapter", Desc = "演示如何用自定义CursorAdapter访问SQLite数据库" },
new ChItem { type=typeof(ch1303MainActivity), Title="例13-3 SQLite基本用法3-SQLite.NET-PCL", Desc = "演示如何用SQLite.NET-PCL访问SQLite数据库" },
new ChItem { type=typeof(ch1303MainActivity), Title="例13-4 SQLite基本用法4-SQLite.NET.Async-PCL", Desc = "演示如何用SQLite.NET.Async-PCL访问SQLite数据库" },
}
});

【Android】13.0 第13章 创建和访问SQLite数据库—本章示例主界面的更多相关文章

  1. 【Android】13.1 用Android自带的API访问SQLite数据库

    分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 这一节我们先来看看如何直接用Android自带的API创建和访问SQLite数据库. 1.创建SQLite数据库 ...

  2. 【Android】13.4 使用SQLite.NET.Async-PCL访问SQLite数据库

    分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 这一节演示如何利用以异步方式(async.await)访问SQLite数据库. 二.示例4运行截图 下面左图为初始 ...

  3. 【Android】19.0 第19章 前面章节的代码优化及本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-03-05 一.简介 这一章我们介绍"共享存储和内容提供程序"的基本用法. 二.先优化一下前面章节例子的代码 在前面 ...

  4. 【Android】7.0 第7章 简单适配器和布局--本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-09 修改日期:2016-02-13 一.在AssemblyInfo.cs文件中配置应用程序清单 前面的章节我们说过,除了在And ...

  5. 【Android】13.2 使用自定义的CursorAdapter访问SQLite数据库

    分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 SQliteDemo1的例子演示了SimpleCursorAdapter的用法,本节我们将使用用途更广的自定义的游 ...

  6. 【Android】17.0 第17章 服务绑定—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-03-03 一.简介 通过服务绑定(Bound Services),可以轻松实现后台服务与界面(UI)的交互. 二.本章示例主界面 1. ...

  7. 【Android】12.0 第12章 Intent及其过滤器—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 这一章我们主要学习Intent的基本用法,并通过例子演示如下功能: 如何启动另一个界面: 如何获取另一个界面的返回 ...

  8. 【Android】11.0 第11章 活动和片段--本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-21 一.简介 这一章我们学习activity和fragment,深入理解activity和fragment的生命周期是如何工作的 ...

  9. 【Android】16.0 第16章 自定义服务和系统服务—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-03-01 一.简介 本章主要演示Started Service.带Intent过滤器的Started Service.IntentSe ...

随机推荐

  1. Linux内核的idle进程分析

    1. idle是什么 简单的说idle是一个进程,其pid号为 0.其前身是系统创建的第一个进程.也是唯一一个没有通过fork()产生的进程. 在smp系统中,每一个处理器单元有独立的一个执行队列,而 ...

  2. Glide Picasso Fresco UIL 图片框架 缓存 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. [Grunt] Minifying your output with grunt-uglify

    For production we want to use minified javascript to reduce the payload that is sent from the server ...

  4. linux安装卸载软件

    转自:http://www.cnblogs.com/propheteia/archive/2012/06/26/2563383.html configure作用:是源码安装软件时配置环境用的 他根据你 ...

  5. grid control 11.1.0.1 安装指南

    grid control 11.1.0.1 安装指南 废话少说,进入正题 系统版本号 [root@gridcontrol ~]# lsb_release -a LSB Version:    :bas ...

  6. 算法笔记_128:完美洗牌算法(Java)

    目录 1 问题描述 2 解决方案 2.1位置置换算法 2.2 走环算法   1 问题描述 有一个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后变成{a1 ...

  7. 算法笔记_024:字符串的包含(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力轮询法 2.2 素数相乘法 2.3 位运算法 1 问题描述 给定一长字符串A和一短字符串B.请问,如何最快地判断出短字符串B中的所有字符是否都在长字符串A ...

  8. ssh登陆不上

    用ssh key登陆不上某台机A的某个账号xy1,查看A的/var/log/messages,看到有这么句: User xy1 not allowed because account is locke ...

  9. 为SQL数据库创建登录名和密码

    为了保证数据库的安全性,需要为数据库创建一个登录帐号,通常每个数据库都有一个默认登录帐号sa,该帐号具有最高的管理权限,但是建议最好重新创建一个新帐号,这样不容易让访客知道,能够使数据库变得更安全.创 ...

  10. Python 转义符

    定义字符串前面我们讲解了什么是字符串.字符串可以用''或者""括起来表示.如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括 ...