首页 > 代码库 > 数据缓存——SQLite关系型数据库的使用

数据缓存——SQLite关系型数据库的使用

SQLite关系型数据库的使用

Demo下载地址


数据库(Database): 存放数据的仓库, 存放的是一张的表, 特别像Excel, Numbers, 都以表格的形式存放数据, 可以创建多张表。

 

常见的数据库: sqlite, MySQL, SQLServer, Oracle, Access。

使用数据库,主要是因为文件读写和归档读取数据需要一次把数据全部读出来, 占用内存开销大;其次是数据库数据效率高, 体现在增删改查。

 

数据库存储数据的步骤

1、新建一个数据库

2、新建一张表(table)

3、添加多个字段(column,列,属性)

4、添加多行记录(row,每行存放多个字段对应的值)

 

数据库的操作语句 (增删改查),即SQL(Structured Query Language)

SQL 语句不区分大小写, 字符串需要加""或‘‘

常用语法:(主键: 是一条数据的唯一标示符, 一张表只能有一个主键, 主键不能够重复, 一般把主键名设为"id", 不需要赋值, 会自增;*代表所有的字段;where是条件)

1 表操作

(1)创建表: creat table 表名 (字段名字段数据类型 是否为主键, 字段名 字段数据类型, 字段名 字段数据类型...)

(2)修改表名:ALTER TABLE 旧表名  RENAME TO 新表名

(3)删除表:DROP TABLE 表名

(4)表添加一列:ALTER TABLE 表名 ADD COLUMN 列名数据类型 限定符

2 表数据操作

(1)查: select 字段名 (或者*) from 表名 where 字段名 = 值

(2)加: insert into 表名 (字段1, 字段2...) values (值1, 值2...)

(3)改: update 表名 set 字段 = 值 where 字段 = 值

(4)删: delete from 表名 where 字段 = 值

 

SQLite是一款轻型的嵌入式数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就足够了。它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快。

 

SQLite名词解释

2个重要结构体

1 sqlite3 *pdb(数据库句柄,跟文件句柄FILE类似)

2 sqlite3_stmt *stmt(这个相当于ODBC的Command对象,用于保存编译好的SQL语句)

5个主要函数

1 sqlite3_open()(打开数据库)

2 sqlite3_exec()(执行非查询的sql语句)

3 sqlite3_prepare()(准备sql语句,执行select语句或者要使用parameterbind时,用这个函数(封装了sqlite3_exec))

4 Sqlite3_step()(在调用sqlite3_prepare后,使用这个函数在记录集中移动)

5 Sqlite3_close()(关闭数据库文件)

 

SQLite 存储类

1 NULL(值是一个 NULL 值)

2 INTEGER(值是一个带符号的整数,根据值的大小存储在1、2、3、4、6 或 8 字节中)

3 REAL(值是一个浮点值,存储为 8 字节的 IEEE 浮点数字)

4 TEXT (值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储)

5 BLOB (值是一个 blob 数据,完全根据它的输入存储)

 

SQLite常用语句

1、打开数据库 sqlite3_open函数

2、预处理SQL语句sqlite3_prepare_v2函数

3、绑定参数sqlite3_bind_text函数

4、执行SQL语句sqlite3_step函数(状态:*SQLITE_BUSY-数据库被锁定、*SQLITE_DONE-成功执行过程、*SQLITE_ROW-返回一行结果、*SQLITE_ERROR-运行错误、*SQLITE_MISUSE-错误的使用了本函数)

5、提取字段数据sqlite3_column_text、sqlite3_column_blob、sqlite3_column_int等函数

6、释放statement对象资源 sqlite3_finalize函数

7、关闭数据库 sqlite3_close函数

 

SQLite的使用

1、在iOS中使用SQLite时,首先需要添加库文件libsqlite3.tbd

技术分享

2、导入主头文件 #import<sqlite3.h>

技术分享

3、数据库操作(注:设置数据库名称及路径)

 

示例代码:

设置数据库路径

[objc] view plain copy 技术分享技术分享
  1. - (void)setSQLitePath  
  2. {  
  3.    if (self.filePath == nil)  
  4.     {  
  5.        // document目录下  
  6.        NSArray *documentArray =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);  
  7.        NSString *document = [documentArray objectAtIndex:0];  
  8.        _filePath = [document stringByAppendingPathComponent:SQLiteFile];  
  9.     }  
  10.      
  11.     NSLog(@"filePath %@", _filePath);  
  12. }  


打开数据库,创建表

[objc] view plain copy 技术分享技术分享
  1. - (void)New  
  2. {  
  3.    NSString *sql = @"CREATE TABLE IF NOT EXISTS STUDENT(NAME TEXTPRIMARY KEY, ADDRESS TEXT, PHONE TEXT)";  
  4.    if (sql && 0 != sql.length)  
  5.     {  
  6.        [self setSQLitePath];  
  7.          
  8.        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath])  
  9.        {  
  10.            // 打开数据库  
  11.            sqlite3 *dataBase; // sqlite3  
  12.            const charchar *fileName = [self.filePath UTF8String]; // [xxx UTF8String]是将NSString转换为C字符串,因为SQLite3是采用可移植的C(而不是            Objective-C)编写的,它不知道什么是NSString.  
  13.            int openStatus = sqlite3_open(fileName, &dataBase);  
  14.            if (openStatus != SQLITE_OK)  
  15.            {  
  16.                 // 数据库打开失败,关闭数据库  
  17.                 sqlite3_close(dataBase);  
  18.                NSAssert(0@"打开数据库失败");  
  19.                  
  20.                 NSLog(@"打开数据库失败");  
  21.            }  
  22.           
  23.            NSLog(@"打开数据库成功");  
  24.              
  25.            // 创建表  
  26.            charchar *errorMsg;  
  27.            const charchar *execSql = [sql UTF8String];  
  28.             int execStatus = sqlite3_exec(dataBase,execSql, NULLNULL, &errorMsg);  
  29.            if (execStatus != SQLITE_OK)  
  30.            {  
  31.                 // 创建表失败,关闭数据库  
  32.                 sqlite3_close(dataBase);  
  33.                 NSAssert1(0@"创建表失败:%s",errorMsg);  
  34.            }  
  35.              
  36.            NSLog(@"创建表成功");  
  37.        }  
  38.     }  
  39. }  

 

插入数据

[objc] view plain copy 技术分享技术分享
  1. - (void)Insert  
  2. {  
  3.    // ?号表示一个未定的值  
  4.    NSString *sql = @"INSERT OR REPLACE INTO STUDENT (NAME, ADDRESS,PHONE) VALUES (?,?,?)";  
  5.    if (sql && 0 != sql.length)  
  6.     {  
  7.        [self setSQLitePath];  
  8.          
  9.        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath])  
  10.        {  
  11.            // 打开数据库  
  12.            sqlite3 *dataBase; // sqlite3  
  13.            const charchar *fileName = [self.filePath UTF8String];  
  14.             int openStatus = sqlite3_open(fileName,&dataBase);  
  15.            if (openStatus != SQLITE_OK)  
  16.            {  
  17.                 // 数据库打开失败,关闭数据库  
  18.                 sqlite3_close(dataBase);  
  19.                 NSAssert(0@"打开数据库失败");  
  20.                  
  21.                NSLog(@"打开数据库失败");  
  22.            }  
  23.              
  24.            NSLog(@"打开数据库成功");  
  25.              
  26.              
  27.            const charchar *execSql = [sql UTF8String];  
  28.            sqlite3_stmt *statment;  
  29.            int execStatus = sqlite3_prepare_v2(dataBase, execSql, -1,&statment, nil); // 接口把一条SQL语句解析到statement结构里去. 使用该接口访问数据库是当前比较好的的一种方法  
  30.            if (execStatus == SQLITE_OK)  
  31.            {  
  32.                 NSLog(@"插入更新表成功");  
  33.                  
  34.                 // 绑定参数开始  
  35.                 // 这里的数字1,2,3代表上面的第几个问号,这里将三个值绑定到三个绑定变量  
  36.                 sqlite3_bind_text(statment, 1,[@"zhangshaoyu" UTF8String], -1NULL);  
  37.                 sqlite3_bind_text(statment, 2,[@"meizhou" UTF8String], -1NULL);  
  38.                 sqlite3_bind_text(statment, 3,[@"13800138000" UTF8String], -1NULL);  
  39.                  
  40.                 // 执行SQL语句 执行插入  
  41.                 if (sqlite3_step(statment) !=SQLITE_DONE)  
  42.                 {  
  43.                     NSAssert(NO@"插入更新表失败。");  
  44.                 }  
  45.                 else  
  46.                 {  
  47.                    NSLog(@"插入更新表成功");  
  48.                 }  
  49.            }  
  50.            else  
  51.            {  
  52.                 NSLog(@"插入更新表失败");  
  53.            }  
  54.              
  55.            // 释放sqlite3_stmt对象资源  
  56.            sqlite3_finalize(statment);  
  57.              
  58.            // 关闭数据库  
  59.            sqlite3_close(dataBase);  
  60.        }  
  61.     }  
  62. }  

 

修改更新数据

[objc] view plain copy 技术分享技术分享
  1. - (void)Update  
  2. {  
  3.    NSString *sql = @"UPDATE STUDENT SET ADDRESS = ? where NAME =?";  
  4.      
  5.    if (sql && 0 != sql.length)  
  6.     {  
  7.        [self setSQLitePath];  
  8.          
  9.         if ([[NSFileManager defaultManager]fileExistsAtPath:self.filePath])  
  10.        {  
  11.            // 打开数据库  
  12.            sqlite3 *dataBase; // sqlite3  
  13.            const charchar *fileName = [self.filePath UTF8String];  
  14.            int openStatus = sqlite3_open(fileName, &dataBase);  
  15.            if (openStatus != SQLITE_OK)  
  16.            {  
  17.                 // 数据库打开失败,关闭数据库  
  18.                 sqlite3_close(dataBase);  
  19.                 NSAssert(0@"打开数据库失败");  
  20.                  
  21.                 NSLog(@"打开数据库失败");  
  22.            }  
  23.              
  24.            NSLog(@"打开数据库成功");  
  25.              
  26.            const charchar *execSql = [sql UTF8String];  
  27.            sqlite3_stmt *statment;  
  28.            int execStatus = sqlite3_prepare_v2(dataBase, execSql, -1,&statment, nil);  
  29.            if (execStatus == SQLITE_OK)  
  30.            {  
  31.                 NSLog(@"更新表成功");  
  32.                  
  33.                 // 绑定text类型的数据库数据  
  34.                 // 这里的数字1,2,3代表第几个问号。这里只有1个问号,这是一个相对比较简单的数据库操作,真正的项目中会远远比这个复杂  
  35.                 sqlite3_bind_text(statment, 1,[@"meizhouWUHUA" UTF8String], -1NULL);  
  36.                 sqlite3_bind_text(statment, 2,[@"zhangshaoyu" UTF8String], -1NULL);  
  37.                  
  38.                 // 执行插入  
  39.                 if (sqlite3_step(statment) !=SQLITE_DONE)  
  40.                 {  
  41.                    NSAssert(NO@"更新表失败。");  
  42.                 }  
  43.                 else  
  44.                 {  
  45.                     NSLog(@"更新表成功");  
  46.                 }  
  47.            }  
  48.            else  
  49.            {  
  50.                 NSLog(@"更新表失败");  
  51.            }  
  52.              
  53.            // 释放sqlite3_stmt对象资源  
  54.            sqlite3_finalize(statment);  
  55.              
  56.            // 关闭数据库  
  57.            sqlite3_close(dataBase);  
  58.        }  
  59.     }  
  60. }  

 

查找数据

[objc] view plain copy 技术分享技术分享
  1. - (void)Select  
  2. {  
  3.    NSString *sql = @"SELECT * FROM STUDENT";  
  4.    if (sql && 0 != sql.length)  
  5.     {  
  6.        [self setSQLitePath];  
  7.          
  8.        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath])  
  9.        {  
  10.            // 打开数据库  
  11.            sqlite3 *dataBase; // sqlite3  
  12.            const charchar *fileName = [self.filePath UTF8String];  
  13.            int openStatus = sqlite3_open(fileName, &dataBase);  
  14.            if (openStatus != SQLITE_OK)  
  15.            {  
  16.                 // 数据库打开失败,关闭数据库  
  17.                 sqlite3_close(dataBase);  
  18.                 NSAssert(0@"打开数据库失败");  
  19.                  
  20.                 NSLog(@"打开数据库失败");  
  21.            }  
  22.              
  23.            NSLog(@"打开数据库成功");  
  24.              
  25.            const charchar *execSql = [sql UTF8String];  
  26.            sqlite3_stmt *statment;  
  27.            int execStatus = sqlite3_prepare_v2(dataBase, execSql, -1,&statment, nil);  
  28.            if (execStatus == SQLITE_OK)  
  29.            {  
  30.                 NSLog(@"查询成功");  
  31.                  
  32.                 // 查询成功,执行遍历操作  
  33.                 // 查询结果集中一条一条的遍历所有的记录,这里的数字对应的是列值,注意这里的列值,跟上面sqlite3_bind_text绑定的列值不一样!一定要分开,不然会crash,只有这一处的列号不同,注意!  
  34.                 while(sqlite3_step(statment) ==SQLITE_ROW)  
  35.                 {  
  36.                     const charchar *NAME = (char*)sqlite3_column_text(statment, 0);  
  37.                     if (NAME != NULL)  
  38.                     {  
  39.                         NSString *name =[[NSString alloc] initWithUTF8String:NAME];  
  40.                         NSLog(@"NAME%@", name);  
  41.                     }  
  42.                      
  43.                     charchar *ADDRESS = (char*)sqlite3_column_text(statment, 1);  
  44.                     if (ADDRESS != NULL)  
  45.                     {  
  46.                         NSString *address =[[NSString alloc] initWithUTF8String:ADDRESS];  
  47.                         NSLog(@"ADDRESS%@", address);  
  48.                     }  
  49.                      
  50.                     charchar *PHONE = (char*)sqlite3_column_text(statment, 2);  
  51.                     if (PHONE != NULL)  
  52.                     {  
  53.                         NSString *phone =[[NSString alloc] initWithUTF8String:PHONE];  
  54.                         NSLog(@"PHONE%@", phone);  
  55.                     }  
  56.                 }  
  57.            }  
  58.            else  
  59.            {  
  60.                 NSLog(@"查询失败");  
  61.            }  
  62.              
  63.            // 释放sqlite3_stmt对象资源  
  64.            sqlite3_finalize(statment);  
  65.              
  66.            // 关闭数据库  
  67.            sqlite3_close(dataBase);  
  68.        }  
  69.     }  
  70. }  

 

删除数据

[objc] view plain copy 技术分享技术分享
  1. - (void)Delete  
  2. {  
  3. //   NSString *sql = @"DELETE FROM STUDENT"; // 方法1  
  4.    NSString *sql = @"DELETE FROM STUDENT where NAME = ?"// 方法2  
  5.    if (sql && 0 != sql.length)  
  6.     {  
  7.        [self setSQLitePath];  
  8.          
  9.        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath])  
  10.        {  
  11.            // 打开数据库  
  12.            sqlite3 *dataBase; // sqlite3  
  13.            const charchar *fileName = [self.filePath UTF8String];  
  14.             int openStatus = sqlite3_open(fileName,&dataBase);  
  15.            if (openStatus != SQLITE_OK)  
  16.            {  
  17.                 // 数据库打开失败,关闭数据库  
  18.                 sqlite3_close(dataBase);  
  19.                 NSAssert(0@"打开数据库失败");  
  20.                  
  21.                NSLog(@"打开数据库失败");  
  22.            }  
  23.              
  24.            NSLog(@"打开数据库成功");  
  25.              
  26.            const charchar *execSql = [sql UTF8String];  
  27.            sqlite3_stmt *statment;  
  28.            int execStatus = sqlite3_prepare_v2(dataBase, execSql, -1, &statment,nil);  
  29.            if (execStatus == SQLITE_OK)  
  30.            {  
  31.                 // 绑定text类型的数据库数据  
  32.                 // 这里的数字1,2,3代表第几个问号。这里只有1个问号,这是一个相对比较简单的数据库操作,真正的项目中会远远比这个复杂  
  33.                 sqlite3_bind_text(statment, 1,[@"zhangshaoyu" UTF8String], -1NULL);  
  34.                  
  35.                 // 执行删除  
  36.                 if (sqlite3_step(statment) !=SQLITE_DONE)  
  37.                 {  
  38.                     NSAssert(NO@"删除数据失败。");  
  39.                     NSLog(@"删除数据失败");  
  40.                 }  
  41.                 else  
  42.                 {  
  43.                     NSLog(@"删除数据成功");  
  44.                 }  
  45.            }  
  46.            else  
  47.            {  
  48.                 NSLog(@"删除数据失败");  
  49.            }  
  50.              
  51.            // 释放sqlite3_stmt对象资源  
  52.            sqlite3_finalize(statment);  
  53.               
  54.            // 关闭数据库  
  55.            sqlite3_close(dataBase);  
  56.        }  
  57.     }  
  58. }  

 

删除表

[objc] view plain copy 技术分享技术分享
  1. - (void)DeleteTable  
  2. {  
  3.    NSString *sql = @"DROP TABLE STUDENT";  
  4.    if (sql && 0 != sql.length)  
  5.     {  
  6.        [self setSQLitePath];  
  7.          
  8.        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath])  
  9.        {  
  10.            // 打开数据库  
  11.            sqlite3 *dataBase; // sqlite3  
  12.            const charchar *fileName = [self.filePath UTF8String];  
  13.            int openStatus = sqlite3_open(fileName, &dataBase);  
  14.            if (openStatus != SQLITE_OK)  
  15.            {  
  16.                 // 数据库打开失败,关闭数据库  
  17.                 sqlite3_close(dataBase);  
  18.                 NSAssert(0@"打开数据库失败");  
  19.                  
  20.                 NSLog(@"打开数据库失败");  
  21.            }  
  22.              
  23.            NSLog(@"打开数据库成功");  
  24.              
  25.            const charchar *execSql = [sql UTF8String];  
  26.            sqlite3_stmt *statment;  
  27.            int execStatus = sqlite3_prepare_v2(dataBase, execSql, -1,&statment, nil);  
  28.            if (execStatus == SQLITE_OK)  
  29.            {  
  30.                 // 执行删除  
  31.                 if (sqlite3_step(statment) !=SQLITE_DONE)  
  32.                 {  
  33.                     NSAssert(NO@"删除表失败。");  
  34.                     NSLog(@"删除表失败");  
  35.                 }  
  36.                 else  
  37.                 {  
  38.                     NSLog(@"删除表成功");  
  39.                 }  
  40.            }  
  41.            else  
  42.            {  
  43.                 NSLog(@"删除表失败");  
  44.            }  
  45.              
  46.            // 释放sqlite3_stmt对象资源  
  47.            sqlite3_finalize(statment);  
  48.               
  49.            // 关闭数据库  
  50.            sqlite3_close(dataBase);  
  51.        }  
  52.     }  
  53. }  


 

数据查看

技术分享

技术分享

技术分享

 

注意事项:

1、由于sqlite3是基于C语言编写的,而不是纯粹的object-c,所以有关字符串,我们不能使用NSString,因为它不识别,所以只能用c语言的字符串,char*,好在Nsstring提供了转换的方法,那就是 UTF8String。如:

NSString*sql = @"DELETE FROM STUDENT where NAME = ?";

constchar *execSql = [sql UTF8String];

2sql语句中,不确定值使用?符号。如:

NSString*sql = @"DELETE FROM STUDENT where NAME = ?";

3、提取查询数据函数中的数字表示sql语句中的第几列(0~N)。如:

表示第1列:constchar *NAME = (char *)sqlite3_column_text(statment, 0);

4、绑定数据时函数中的数字表示sql语句中的第几个值。如:

NSString*sql = @"INSERT OR REPLACE INTO STUDENT (NAME, ADDRESS, PHONE) VALUES(?,?,?)";

表示第1个值:sqlite3_bind_text(statment,1, [@"zhangshaoyu" UTF8String], -1, NULL);

表示第2个值:sqlite3_bind_text(statment,2, [@"meizhou" UTF8String], -1, NULL);

表示第3个值:sqlite3_bind_text(statment,3, [@"13510213244" UTF8String], -1, NULL);

5、创建表时,必须设置一个主键PRIMARY KEY。如:

NSString*sql = @"CREATE TABLE IF NOT EXISTS STUDENT(NAME TEXT PRIMARY KEY, ADDRESSTEXT, PHONE TEXT)";

数据缓存——SQLite关系型数据库的使用