Objective-C访问SQLite

数据库的相关知识我就不去说明了,毕竟只要会sql语言的人就大家都一样。

  本案例是在Xcode7.2环境下创建的single view application进行演示操作。

  首先第一点,为什么要使用sqlite3?   

  在iOS的编程中,毫无疑问接触最多的就是界面的代码编排和设计,数据的解析与放置,算法的各种挠头问题。。。   在数据的解析与放置这一块,就会涉及到数据库缓存的操作,我们都知道,iOS手机编程是在手机端运行的,你不能老是去服务器端读取数据啊,好,就算你不烦,手机也跑的起来,流量不要过啊,对于手机控或者应用使用者来说,流量就是生命,而且,如果总是去服务器端读取数据,对手机的运行速度也会有影响,毕竟有一个网络传输的过程,所以,为了让用户有一个更好的体验,一般建议的做法是,将服务器的数据进行下载,然后通过数据库缓存起来,这样就不用每次每次的去请求服务器数据了,如果在数据库中有的数据,直接可以通过数据库查询得到,而省去了一次甚至多次的服务器请求操作。而sqlite3就是提供了一种C语言的访问数据库的形式。之后我们的代码会看到,其实sqlite3的语法可能比较难以理解,不过,我也会给大家来进行介绍的。      

  那么第二点,使用sqlite3的好处是什么?

  使用sqlite3的好处么,除开语法的各种蛋疼之外,访问的速度还是会比FMDB快一些的。而且,随着一步步的汇总和总结,你可以清晰的知道每一句sqlite3的语句的作用,而不是使用封装好了的语句,只要用就可以了,但是不知道是为什么。我个人觉得,学习学习吧,还是要知其然,亦知其所以然这样才能学的踏实。

第一步,引入 libsqlite3.tbd 静态库

第二步,在要使用 SQLite 的地方导入库主头文件 #import <sqlite3.h>

第三步,创建sqlite数据库文件

  * sqlite3提供的是一种访问操纵数据库的形式,那么,如果想要使用sqlite3来访问操纵数据库,首先我们得先有个数据库,下面就是使用代码生成一个数据库文件。

// SQLite文件名称
static NSString * const fileName = @"SQLite.sqlite";

// 得到数据库文件地址,这是一个拼接的地址字符串,是沙盒路径下面的shop.sqlite文件
// 这个文件名可以随便取名字,后缀最好是db啊或者sqlite这种,用来表示这是一个数据库文件
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
              stringByAppendingPathComponent:fileName];

  打开数据库连接,如果有就打开,没有就重新创建连接。

  * sqlite3_open是我们接触到的第一条sqlite3语句,它的作用时打开数据库连接,如果有数据库文件就打开它,没有就重新创建数据库,这个方法有一个枚举的返回值表示是否正常打开了数据库,我用int的变量status去接收了这个值,后面会进行判断。  

  * sqlite3_open有两个参数,第一个参数是数据库文件的路径,第二个参数是一个数据库的引用,即一个sqlite3 *类型的引用;

  * filePath.UTF8String: filename本身是oc的字符串类型,但是sqlite3_open要求传递的是C类型的字符串,所以,使用UTF8String将oc的字符串类型转换为C类型的字符串

@interface ViewController ()
{
    sqlite3 *_sqlite;
}
@end

// 打开数据库连接,如果有就打开,没有就重新创建连接
NSInteger state = sqlite3_open(filePath.UTF8String, &_sqlite);
// 枚举值SQLITE_OK代表成功的状态
if (state == SQLITE_OK)
    NSLog(@"----- 打开数据库成功 -----");
else
    NSLog(@"----- 打开数据库失败 -----");

  

第四步,创建数据库表

  * 当我们打开了数据库连接的时候,表示在程序的沙盒路径下已经创建了一个 SQLite.sqlite 的数据库文件,而这个数据库里现在什么东西都没有,我们需要创建一张数据库表来存放数据。

  * sqlite3_exec 是我们接触到的第二个sqlite3语句,这个语句用于执行除了查询语句以外的其他语句.

 它有一个枚举类型的返回值,和 sqlite3_open 返回的枚举值一致,这里我并没有使用变量保存,因为我有其他形式来获得创建表是否成功。

  * sqlite3_exec 需要传递5个参数,第一个参数是数据库引用即 sqlite3 *_shop,第二个参数是要执行的sql语句,

 第三个参数是执行完sql语句后要执行的函数,第四个参数是执行完sql语句后要执行的函数的参数,第五个参数是执行完sql语句后的报错信息。

// 创表语句,IF NOT EXISTS防止创建重复的表,AUTOINCREMENT是自动增长关键字,real是数字类型
const char *sql = "CREATE TABLE IF NOT EXISTS t_SQLite(id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, price real)";
//保存错误信息的变量
char *errorMessage = NULL;
sqlite3_exec(_sqlite, sql, NULL, NULL, &errorMessage);
// 如果存在报错信息,代表语句执行失败,比判断枚举值要更简单一些
if (errorMessage)
    NSLog(@"----- 创建表失败 -> errorMessage: %s -----", errorMessage);
else
    NSLog(@"----- 创建表成功 -----");

第五步,数据表操纵

  所谓的数据表操纵即是对数据表中数据的增删改,也是最经常会使用到的功能。即执行insert, update, delete语句。

  (1)增

    * 注:这里我在 Main.storyboard 里面拖了两个输入框(UITextField)和一个按钮(UIButton),并建立关联

@interface ViewController ()
{
    sqlite3 *_sqlite;
}
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *priceField;
@end

#pragma mark 增
- (IBAction)addDataEvent:(UIButton *)sender {
    NSString *name = [self.nameField.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    CGFloat price = self.priceField.text.floatValue;
    // 拼接插入数据的sql语句
    NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_SQLite(name,price) VALUES(‘%@‘,%f)", name, price];
    char *errorMessage = NULL;
    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &errorMessage);
    if (errorMessage)
        NSLog(@"----- 插入数据失败 -> errorMessage: %s -----", errorMessage);
    else
        NSLog(@"----- 插入数据成功 -----");
}

  

  (2)删

    * 注:这里我在 Main.storyboard 里 新增按钮下方拖放了一个输入框(UITextField)和一个删除按钮(UIButton),并建立关联

      这里是以 id 为关键字进行定位到数据的,所以,这个 id 的值必须是已有的数据的 id 值

@interface ViewController ()
{
    sqlite3 *_sqlite;
}
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *priceField;
@property (weak, nonatomic) IBOutlet UITextField *lbl;
@end

#pragma mark - 删
- (IBAction)deleteDataEvent:(UIButton *)sender {
    NSString *lbl = [self.lbl.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    // 拼接sql删除语句
    NSString *sql = [NSString stringWithFormat:@"DELETE FROM t_SQLite where id=%ld", lbl.integerValue];
    char *error = NULL;
    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &error);
    if (error)
        NSLog(@"----- 删除数据失败 -> error: %s -----", error);
    else
        NSLog(@"----- 删除数据成功 -----");
}

  (3)改

    * 注:这里我在 Main.storyboard 里新拖了一个修改按钮(UIButton),并建立关联

      这里是以 id 为关键字进行定位到数据的,所以,这个 id 的值必须是已有的数据的 id 值

#pragma mark - 改
- (IBAction)updateDataEvent:(UIButton *)sender {
    NSString *name = [self.nameField.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSString *price = [self.priceField.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSString *lbl = [self.lbl.text stringByReplacingOccurrencesOfString:@" " withString:@""];
    // 拼接更新数据的sql语句
    NSString *sql = [NSString stringWithFormat:@"update t_SQLite set name=‘%@‘,price=‘%@‘ where id=%@", name, price, lbl];
    char *error = NULL;
    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &error);
    if (error)
        NSLog(@"----- 更新数据失败 -> error: %s -----", error);
     else
        NSLog(@"----- 更新数据成功 -----");
}

    大家可以观察上面的三个方法,会发现除了sql语句的拼接不一样以外,其他的地方几乎一模一样,所以,增删改的操作相对来说还是比较简单的。

  (4)查

    * sqlite3_prepare_v2函数是准备要执行sql查询的一个函数,可以当做这个函数就是用来做sql查询之前的准备工作的,它也是返回一个枚举作为准备工作的结果,SQLITE_OK则代表准备工作ok

    * sqlite3_prepare_v2需要传入5个参数,第一个参数是数据库引用即(sqlite3* _shop),第二个参数是要执行的sql语句,第三个参数是sql语句的长度,第四个参数是查询结果stmt的引用,查询完成后,查询结果将会存入该引用,第五个参数是指向无法使用的部分的指针,一般不会用到,给NULL就可以了

    * sqlite3_step(stmt)函数将会执行查询并且将查询到的当前记录存入到stmt(sqlite3_stmt * 类型)中

    * 第一次执行sqlite3_step(stmt)将会将表中的第一条数据存入到stmt中,第二次执行sqlite3_step(stmt)将会把表中的第二条记录存入到stmt中

    * 也就是说,while(sqlite3_step(stmt)==SQLITE_ROW)将会一条一条的去读取表中的记录,而SQLITE_ROW枚举判断的是有读取到数据行的情况

#pragma mark - 查
- (void)inquiryData {
    // 查询sql语句
    const char *sql = "select * from t_SQLite";
    // stmt用来取出查询结果
    sqlite3_stmt *stmt = NULL;
    NSInteger state = sqlite3_prepare_v2(_sqlite, sql, -1, &stmt, NULL);
    // 准备成功,SQL语句正确
    if (state == SQLITE_OK)
        // 成功指向一条记录
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            // 封装的实体
            Shop *shop = [[Shop alloc] init];
            //sqlite3_column_xxxx函数:它用来读取数据行中不同类型的数据,该函数的返回值就是读取到得数据内容,该函数需要2个参数,          第一个参数是存放数据的stmt,第二个参数是数据列下标
            // 读取stmt中存储的第0列数据
            shop.pid= sqlite3_column_int(stmt, 0);
            // 读取stmt中存储的第1列数据
            const char *name = (const char*)sqlite3_column_text(stmt, 1);
            // 读取stmt中存储的第2列数据
            const char *price = (const char*)sqlite3_column_text(stmt, 2);
            // 将C类型的字符串转换为oc类型的字符串并存储
            shop.name = [NSString stringWithUTF8String:name];
            // 将C类型的字符串转换为oc类型的字符串并存储
            shop.price = [NSString stringWithUTF8String:price];
        }
    else
        NSLog(@"----- 读取数据失败 -----");

对sqlite3的基本使用大致就这些,平时我们要用的也只是这些操作,其他的SQL操作正常情况下是不会涉及到。

接下来就是将上面的代码重复的运用到你的项目中! 

附源码地址: 源码链接 密码: 5xgm

时间: 2025-01-02 14:20:22

Objective-C访问SQLite的相关文章

SQLitedatabase实现访问sqlite

通过SQLiteDatabase 来访问sqlite数据库 ----Main.java public class Main extends Activity { SQLiteDatabase db; ListView listView; EditText editText1, editText2;  //要添加的标题和context Button button; @Override protected void onCreate(Bundle savedInstanceState) { supe

【Android】13.0 第13章 创建和访问SQLite数据库&mdash;本章示例主界面

分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 Android 内置了三种数据存取方式:SQLite数据库.文件.SharedPreferences. 这一章我们主要学习如何使用SQLite数据库存取数据. 1.SQLite是个什么档次的数据库 SQLite是一种免费的.开源的数据库,由于它独特的设计(把各种数据类型都转换为它自己内部处理的5种类型)导致其占用内存极少,因此很多项目都喜欢使用它. Android集成了SQLite并内置了专门对SQLite操作

13.4 使用SQLite.NET.Async-PCL访问SQLite数据库

分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 这一节演示如何利用以异步方式(async.await)访问SQLite数据库. 二.示例4运行截图 下面左图为初始页面,右图为单击[创建数据库]按钮后的结果.   下面左图为单击[添加单行]按钮的结果,右图为单击[添加多行]按钮的结果.   注意:不想再像上一节的例子那样逐个添加页面了,毕竟例子的目的仅仅是为了演示最基本的异步操作用法,代码太多容易冲淡要关注的内容,所以该例子并没有去解决重复添加相同学号的记录引

应用EF访问SQLite数据

1.创建项目 项目结构初始结构如下图所示,Netage.Data.SQLite 类库项目用于定义访问数据的接口和方法,Netage.SQLiteTest.UI 控制台项目引用 Netage.Data.SQLite 类库,调用其相应的方法来访问数据. 2.在项目中加入SQLite类库 右键 Netage.Data.SQLite 项目,选择"Manage Nuget Packages"菜单,在输入框中输入"System.Data.SQLite",查询到"Sys

Android中使用adb访问SQLite的方法

(1)打开命令提示符,输入:adb,按回车,如果得到下面一大堆命令说明(如图 1),表示adb的配置是成功的,如果提示"不是内部或外部命令,也不是可运行的程序或批处理文件",那么需要将AndroidSDK中adb.exe文件的目录添加到系统的环境变量中. 图 1 (2)输入adb shell,进入Linux命令环境.(如图 2) 图 2 (3)输入cd data,回车,进入根目录下的data文件夹,如图 3. 图 3 (4)输入ls –l命令,查看data文件夹下的文件,如图 4. 图

13.3 使用SQLite.NET-PCL访问SQLite数据库

分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 本章开头已经说过了,SQLite.NET-PCL用起来很爽,这一节咱们看看怎样使用吧. 二.示例3运行截图 下面左图是单击[初始化表数据]后的结果,右图是单击[获取所有记录]后的结果.    下面左图是单击[添加新行]后的界面,右图是添加后重新获取的所有记录:    修改.删除.查找不再截图了,有兴趣自己玩吧. 三.主要设计步骤 1.添加SQLite.NET-PCL程序包 通过NuGet直接添加即可. 2.创建

Dapper C# 访问SQLite

1.以操作SQLite为例.先下载Dapper,项目引用添加Dapper.dll,然后入下 SQLiteConnectionStringBuilder sb = new SQLiteConnectionStringBuilder(); sb.DataSource = @"D:sqlite.db"; SQLiteConnection con = new SQLiteConnection(sb.ToString()); con.Open(); string sql = "sele

C#访问加密的SQLite数据库

前提:一个项目需要存储各种密码数据,使用的嵌入式的SQLite数据库.默认的SQLite数据库是没有加密的,这样相当不安全.找呀找呀找方法... 方法: 1.使用SQLite管理器加密. 部分SQLite管理器是有对SQLite数据库有加密功能的.本小菜使用的是:SQLite Developer管理工具.加密如下:        密码就设置OK了. 2.C#访问SQLite带密码的数据库 首先说说,不带密码的SQLite访问字符串格式,只需写入数据库所在路径即可: string ConnStr=

SQLite数据库--C#访问加密的SQLite数据库

前提:一个项目需要存储各种密码数据,使用的嵌入式的SQLite数据库.默认的SQLite数据库是没有加密的,这样相当不安全.找呀找呀找方法... 方法: 1.使用SQLite管理器加密. 部分SQLite管理器是有对SQLite数据库有加密功能的.本小菜使用的是:SQLite Developer管理工具.加密如下:        密码就设置OK了. 2.C#访问SQLite带密码的数据库 首先说说,不带密码的SQLite访问字符串格式,只需写入数据库所在路径即可: string ConnStr=