文档章节

iOS数据持久化——SQLite(数据库)

kinglin_fu
 kinglin_fu
发布于 2016/02/01 17:14
字数 2337
阅读 263
收藏 8

###1、 SQLite基本概述

  • SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。

  • ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

  • SQLite占用资源非常的低,只需要几百K的内存就够了。所以移动端和嵌入式设备的数据存多使用SQLite。

  • SQLite能够支持Windows/Linux/Unix等等主流的操作系统,支持多种开发语言,C, C++, PHP, Perl, Java, C#,Python, Ruby等。SQLite虽然很小巧,但是支持的SQL语句不会逊色于其他开源数据库,当前使用版本为SQLite3。

  • SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。

###2、 导入SQLite系统库和SQLiteManger下载 iOS中使用SQLite得依赖 libsqlite3.dylib 库,所以使用前先要导入这个库。步骤如下:

点击项目文件 -> TARGETS -> Build Phases -> Link Binary With Librarise -> 点击 + 号,XCode7以后不能直接搜索到libsqlite3.dylib,只能搜到libsqlite3.tbd,需要到指定目录中添加,所以需要如下图操作:

1、点击Add Other

输入图片说明

2、快捷键 command + shift + G 前往文件夹,输入/user/lib/libsqlite3.dylib 到达库文件目录。

输入图片说明

3、选择libsqlite3.dylib ,OK了。

输入图片说明

为了提高使用SQLite的效率,通常我们要结合一个可视化Mac端的SQLite软件 SQLiteManager 一起完成,如下软件界面:

输入图片说明

###3、 SQLite常用结构体\函数解析 SQLite提供是C语言的库,使用的时候调用的API都是函数,这些常用的函数包括数据库的创建打开、语句的预处理、执行、关闭等。

  • sqlite3: 数据库结构体,相当于数据库类。

  • sqlite3_stmt: sql语句结构体,相当于SQL语句类。

  • sqlite3_open(): 创建和打开数据库,返回值等于 SQLITE_OK 表示成功。

  • sqlite3_exec(): 执行非查询sql语句,返回值等于 SQLITE_OK 表示执行成功。

  • sqlite3_prepare_v2(): 预处理sql语句,用于数据查询。

  • sqlite3_step(): 可以用于多次执行sql语句,要先使用预处理,用于数据查询。

  • sqlite3_bind_text(): 绑定sql语句中 ?号对应的参数。

  • sqlite3_column_text(): 从sqlite3_step()的结果中获取指定列的数据,包含 int,double等多个。

  • sqlite3_finalize():销毁前面被sqlite3_prepare()创建的预处理语句sqlite3_stmt,在关闭之前完成。

  • sqlite3_close():关闭之前打开的数据库,使用完后必须关闭数据库释放资源。

###4、 创建数据库


    // 1、创建数据库指针,相当于创建一个数据库对象。
    sqlite3 *_sqlDB;
	
    // 2、创建数据库保存的路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dataPath = [docPath stringByAppendingFormat:@"/%@.sqlite",dbName];
    
    // 3、打开数据库
    int result = sqlite3_open([dataPath UTF8String], &_sqlDB);
    if (result == SQLITE_OK) {
        
		NSLog(@"创建/打开成功!");
    } else {
    
    	NSLog(@"创建/打开失败!");
    	
        // 4、关闭数据库
    	sqlite3_close(_sqlDB);
    }

代码解析

1、数据库扩展名称为.sqlite

2、sqlite3_open()函数包含两个参数,第一个为数据库的路径因为参数的类型是 char *类型,所有要用[dataPath UTF8String]进行类型转换,第二个为数据库sqlite3指针的地址。

3、如果函数的返回值等于 SQLITE_OK(宏) 表示成功。

4、数据库打开失败或者使用完后都要调用sqlite3_close()函数,关闭数据库释放资源。

###5、 创建数据库表


    // 1、创建创建表的 SQL 语句
    NSString *sql = @"CREATE TABLE IF NOT EXISTS Person(pID TEXT PRIMARY KEY,pName TEXT,pSex TEXT, pTel TEXT)";
	 
    // 2、执行语句SQL语句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql UTF8String], NULL, NULL, &error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"创建表成功!");
        
    } else {
        
        NSLog(@"创建表失败!");
        
        sqlite3_close(_sqlDB);
    }

输入图片说明

代码解析:

1、sql语句:**CREATE TABLE IF NOT EXISTS 表名(字段1 数据类型,字段2 数据类型...(还可以设置字段为主键、外键等))"**表示创建一个名称为Person的表,表包含pID、pName、pSex、pTel四个字段,主键(PRIMARY KEY)为pID,TEXT为字段的数据类型表示字符串类型,IF NOT EXISTS表示没有这个表时再创建有了就不创建了。

2、sqlite3_exec()执行sql语句函数,包含五个参数,第一个是数据库指针,第二个sql语句(char * 类型),第三个回调函数,如果不需要回调就用NULL。第四个回调函数的的第一个参数没有用NULL,第五个错误信息地址 char **类型。

###6、 添加数据到表


    // 1、创建给表添加数据的sql语句
    NSString *pID = @"1002";
    NSString *pName = @"kitty";
    NSString *pSex = @"女";
    NSString *pTel = @"98777331";
    NSString *sql_insert = [NSString stringWithFormat:@"INSERT INTO Person (pID,pName,pSex,pTel) VALUES ('%@','%@','%@','%@')",pID,pName,pSex,pTel];
    
    //2、执行 sql 语句
	 char *error;
    int result = sqlite3_exec(_sqlDB, [sql_insert UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"数据插入成功!");
        
    } else {
        
        NSLog(@"数据插入失败!");
    }

代码解析:

1、sql语句:**INSERT INTO Person (字段1,字段2...) VALUES (数据1,数据2...)"**表示在Person表里的 pID,pName,pSex,pTel 字段中,分别插入对应的值。

2、也sqlite3_exec()执行sql语句,非查询的sql语句都用这个函数执行。

###7、给数据库表添加字段(列)


    //1、在标准添加字段的 sql 语句
    NSString *culumn = @"pAge INTEGER";
    NSString *sql_addCulumn = [NSString stringWithFormat:@"ALTER TABLE Person ADD COLUMN %@ ",culumn];
    
    //2、执行 sql 语句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql_addCulumn UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"添加字段成功!");
        
    } else {
        
        NSLog(@"添加字段成功!");
    }

代码解析:

1、sql语句:ALTER TABLE 表名 ADD COLUMN 列名称和数据类型,表示在Person表格中添加一个字段(一列),这一列名称叫做 pAge数据类型为 interger。

2、执行函数也使用sqlite3_exec()

###7、 更新数据

	
    // 1、创建跟新数据的 sql 语句
    NSString *sql_update = [NSString stringWithFormat:@"UPDATE Person SET pAge = %d WHERE pName = 'kitty'",20];
	
    // 2、执行 sql 语句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql_update UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"数据更新成功!");
        
    } else {
        
        NSLog(@"数据更新失败!");
    }

代码解析:

1、sql语句:UPDATE 表名 SET 需要修改的数据 WHERE 条件,表示更新Person表格,将pName为‘kitty’的这些行的 pAge 改为 20。WHERE后面的表示更改的条件。

###8、 删除数据


    // 1、创建 sql 语句
    NSString *sql_Delete = [NSString stringWithFormat:@"DELETE FROM Person WHERE pName = '%@'",@"kitty"];
	
    //2、执行 sql 语句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"数据删除成功!");
        
    } else {
        
        NSLog(@"数据删除失败!");
    }  

代码解析

1、sql语句:DELETE FROM 表名 WHERE 条件",表示从Person 表中删除pName为‘kitty‘的所有行。

###9、 查询数据


    // 1、创建保存查询结果的数组
    NSMutableArray *perObjs = [NSMutableArray array];
	 
    // 2、创建查询的 sql 语句 
    NSString *sql_Select = [NSString stringWithFormat:@"SELECT * FROM Person WHERE pAge > %d",20];
	
    // 3、创建sql语句指针,相当于创建查询语句对象
    sqlite3_stmt *stmt;
    
    // 4、预处理SQL语句,相当于编译 sql 过程
    int result = sqlite3_prepare_v2(_sqlDB, [sql UTF8String], -1, &stmt, NULL);
    if(result == SQLITE_OK) {      
		// 5、执行SQL语句
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            
            // 6、获取对应的字段数据
            char *ID = (char *)sqlite3_column_text(stmt, 0);
            char *name = (char *)sqlite3_column_text(stmt, 1);
            char *sex = (char *)sqlite3_column_text(stmt, 2);
            char *tel = (char *)sqlite3_column_text(stmt, 3);
            int age = sqlite3_column_int(stmt, 4);
            
            // 7、将数据保存到数据mode中
            Person *per = [[Person alloc] init];
            per.pID = [NSString stringWithUTF8String:ID];
            per.pName = [NSString stringWithUTF8String:name];
            per.pSex = [NSString stringWithUTF8String:sex];
            per.pTel = [NSString stringWithUTF8String:tel];
            per.pAge = age;
            
            // 8、将查询的结果保存在数组中
            [perObjs addObject:per];  
        }
    } else {
        
        sqlite3_close(_sqlDB);
        NSLog(@"查询数据失败!");
    }
    // 9、释放stmt
    sqlite3_finalize(stmt);

代码解析:

1、sql语句:SELECT * FROM 表名 WHERE 查询条件,表示从Person表格中查询pAge大于20的所有行。

2、sqlite3_stmt 相当于sql语句的对象,执行语句、获取查询到的取都是对这个对象进行操作。

3、sqlite3_prepare_v2(),sql语句预处理操作,在执行语句前做的事相当于编译 sql 语句。包含五个参数,第一个数据库指针,第二个sql语句,第三个能从sql语句中获取的最大字节数,使用-1表示整个sql语句。第四个sqlite3_stmt对象地址,第五个指向未使用部分的 sql 语句的指针,如果为前面为-1就使用NULL。

4、sqlite3_step(),执行 sql 语句,将编译好的sql语句执行,这个函数可能会多次执行,因为查询的数据可能有多条,所有要一个循环语句一起使用。循环条件是sqlite3_step(stmt) == SQLITE_ROW 表示还有其他行数据。

5、sqlite3_column_text(stmt, 0),获取查询到的一行结果中对应列的数据,text表示字符串类型 返回char *类型,0表示获取第0列的数据。这个函数还有int、double等类型,返回值得类型也对应。选择列对应的数据类型的函数。

6、使用数据库查询到的数据通常要保存到 mode层中,方便使用,所有创建了一个Person对象保存对应的数据。

7、sqlite3_finalize(),使用完查询对象后要释放。

###10、Demo下载地址

####链接地址:https://github.com/fuqinglin/SQLDemos.git

####SQLite SQL语句学习:http://www.runoob.com/sqlite/sqlite-tutorial.html

© 著作权归作者所有

kinglin_fu
粉丝 16
博文 11
码字总数 14320
作品 0
石景山
私信 提问
盘点移动开发中最流行的5个数据库

嵌入式数据库是轻量级的,独立的库,没有服务器组件,无需管理,一个小的代码尺寸,以及有限的资源需求。目前有几种嵌入式数据库,你可以在移动应用程序中使用。让我们来看看这些最流行的数据...

kouxunli1
2014/11/21
0
0
iOS 数据库比较:SQLite vs. Core Data vs. Realm

如果你想开发一个能够快速运行并没有Bug的伟大应用,你就必须得仔细的考虑一下你的应用的各个方面。有这么一个你必须解决的方面是怎样存储和查询大数据,那么你就很可能会使用到数据库。在大...

oschina
2016/02/20
8.4K
17
iOS平台强大Sqlite操作引擎开源库

前言 首先写这篇文章之前自我介绍一下,我叫吴海超(WHC)在iOS领域有丰富的开发架构经验Github以后我也会以文章的形式分享具有实战意义的文章给大家,希望能够给大家有所帮助。 主题 这期我想...

WHC
2017/03/07
0
0
iOS学习之sqlite的创建数据库,表,插入查看数据

iOS sqlite数据库操作。步骤是: 先加入sqlite开发库libsqlite3.dylib, 新建或打开数据库, 创建数据表, 插入数据, 查询数据并打印 1、新建项目sqliteDemo,添加使用sqlite的库libsqlite3....

知行合一100
2012/06/29
0
0
大厂iOS面试题——备战2019

面试题 1、多线程的应用 2、GCD实现多个请求都完成之后返回结果 3、A、B两个int数组,得到A数组中B数组不包含的元素 4、事件传递链,页面上一个按钮,按钮和它的superView有一样的action,为什...

猿_员
2018/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

安装kibana、安装logstash,logstash收集syslog日志

安装kibana、安装logstash,logstash收集syslog日志 ELK安装 – 安装kibana(成图的、web工具) 以下在128(主节点)上执行(在一台机器上安装即可) wget https://artifacts.elastic.co/do...

oschina130111
6分钟前
0
0
一文带你理解Java中Lock的实现原理

当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题。java提供了两种方式来加锁,一种是关键字:synchronized,一种是concurrent包下的lock锁。synchro...

天王盖地虎626
10分钟前
0
0
hibernate 删除表异常 DataIntegrityViolationException: Could not execute JDBC batch update

最近在做项目中, hibernate 物理删除 delete 方法的时候, 爆了诡异的错误, 比如 org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL ......

之渊
11分钟前
0
0
架构师之路(四)-DNS在架构设计中的巧用

一、缘起 一个http请求从客户端到服务端,整个执行流程是怎么样的呢? 一个典型流程如上: (1)客户端通过域名daojia.com请求dns-server (2)dns-server返回域名对应的外网ip(1.2.3.4) (3)客户...

yaukie
11分钟前
1
0
spring boot 2.1.4 缓存 Hazelcast实现(四)

hazelcast.xml文件可以拆分成多个,并且在hazelcast.xml文件中默认可以从系统配置项读取配置属性,这里转成在spring配置文件中配置 private static final String GROUP_NAME = "group.name";...

花树堆雪
15分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部