[原创] Xcode中使用sqlite3访问数据库

  最近开始写博客了,把我学习到的东西进行汇总和总结,今天就说说怎么使用sqlite3来操纵数据库吧   算法

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

  本案例是在Xcode环境下建立的single view application进行演示操做,若有不清楚的朋友能够找我下载代码。qq:1750587828.数据库

  首先第一点,为何要使用sqlite3?   编程

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

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

  使用sqlite3的好处么,除开语法的各类蛋疼以外,访问的速度仍是会比FMDB快一些的。并且,随着一步步的汇总和总结,你能够清晰的知道每一句sqlite3的语句的做用,而不是使用封装好了的语句,只要用就能够了,可是不知道是为何。我我的以为,学习学习吧,仍是要知其然,亦知其因此然这样才能学的踏实。   网络

  第三点,让咱们来开始学习sqlite3的使用方式吧:  app

  3.1 第一步,引入sqlite3库,并在使用sqlite3的地方导入sqlite3.函数

   

  3.2 第二步,建立sqlite数据库文件   学习

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

/*获得数据库文件地址,这是一个拼接的地址字符串,是沙盒路径下面的shop.sqlite文件,

这个文件名能够随便取名字,后缀最好是db啊或者sqlite这种,用来表示这是一个数据库文件*/

    NSString* filename=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"shop.sqlite"];

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

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

filename.UTF8String:filename自己是oc的字符串类型,可是sqlite3_open要求传递的是C类型的字符串,因此,使用UTF8String将oc的字符串类型转换为C类型的字符串

*/

    int status=sqlite3_open(filename.UTF8String, &_shop);

    if(status == SQLITE_OK)//枚举值SQLITE_OK,表明成功的状态

    {

    NSLog(@"打开数据库成功");

  }

    else

           NSLog(@"打开数据库失败");

 

  3.3 建立数据库表

  当咱们打开了数据库链接的时候,表示在程序的沙盒路径下已经建立了一个shop.sqlite的数据库文件,而这个数据库里如今什么东西都没有,咱们须要建立一张数据库表来存放数据。在这里我就封装一个setupTable来进行建立表的操做。

-(void) setupTable
{

     //创表语句,IF NOT EXISTS防止建立重复的表,AUTOINCREMENT是自动增加关键字,real是数字类型

        const char * sql="CREATE TABLE IF NOT EXISTS t_shop(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,price real);";

        //保存错误信息的变量

        char * errMsg=NULL;

    /*sqlite3_exec是咱们接触到的第二个sqlite3语句,这个语句用于执行除了查询语句之外的其余语句.

    它有一个枚举类型的返回值,和sqlite3_open返回的枚举值一致,这里我并无使用变量保存,由于我有其余形式来得到建立表是否成功。

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

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

  */

        sqlite3_exec(_shop, sql, NULL, NULL, &errMsg);

        if(errMsg)//若是存在报错信息,表明语句执行失败,比判断枚举值要更简单一些

        {

            NSLog(@"建立表shop失败-%s",errMsg);//打印错误信息

        }

}

 

  3.4 封装数据库链接和建立数据库表

-(void)setupDB

{

    //获得数据库文件地址

    NSString* filename=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"shop.sqlite"];

    //NSLog(@"%@",filename);

    //打开数据库链接,若是有就打开,没有就从新建立链接

    int status=sqlite3_open(filename.UTF8String, &_shop);

    

    if(status == SQLITE_OK)

    {

        NSLog(@"打开数据库成功");

        //创表语句

        [self setupTable];

    }

    else

    {

        NSLog(@"打开数据库失败");

    }

}

  3.5 数据表操纵

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

- (IBAction)add:(id)sender {//这里是一个按钮的点击提供的新增功能

    /*拼接插入数据的sql语句*/

    NSString * sql=[NSString stringWithFormat:@"INSERT INTO t_shop(name,price) VALUES('%@',%f)",self.name.text,self.price.text.doubleValue];

    char* errMsg=NULL;

    sqlite3_exec(self.shop, sql.UTF8String, NULL, NULL, &errMsg);

    

    if(errMsg)

    {

        NSLog(@"插入数据失败--%s",errMsg);

    }

}

 

-(void)updateData//这里是一个方法提供了更新功能

{

 //拼接sql更新语句

    NSString * sql=[NSString stringWithFormat:@"update t_shop set name='%@',price='%@' where id=%@",self.name.text,self.price.text,self.lbl.text];

    //NSLog(@"%@",sql);

    char* errMsg=NULL;

    sqlite3_exec(self.myShop, sql.UTF8String, NULL, NULL, &errMsg);

    if(errMsg)

    {

        NSLog(@"更新数据失败--%s",errMsg);

    }

}

 

-(void)deleteDataById:(int)pid

{//提供一个方法执行删除操做,该方法要求获得要删除的数据的id

  //拼接sql删除语句

    NSString * sql=[NSString stringWithFormat:@"DELETE FROM t_shop where id=%d",pid];

    char* errMsg=NULL;

    sqlite3_exec(self.shop, sql.UTF8String, NULL, NULL, &errMsg);

    if(errMsg)

    {

        NSLog(@"删除数据失败--%s",errMsg);

    }

}

  你们能够观察上面的三个方法,会发现除了sql语句的拼接不同之外,其余的地方几乎如出一辙,因此,增删改的操做相对来讲仍是比较简单的。

 

  3.6 查询数据 

/**

 *  查询数据

 */

-(void)setupData

{

    const char * sql="select * from t_shop";//查询sql语句

    //stmt用来取出查询结果

    sqlite3_stmt *stmt=NULL;

    /*sqlite3_prepare_v2函数是准备要执行sql查询的一个函数,能够当作这个函数就是用来作sql查询以前的准备工做的,

  它也是返回一个枚举做为准备工做的结果,SQLITE_OK则表明准备工做ok

  sqlite3_prepare_v2须要传入5个参数,第一个参数是数据库引用即(sqlite3* _shop),第二个参数是要执行的sql语句,第三个参数是sql语句的长度

  第四个参数是查询结果stmt的引用,查询完成后,查询结果将会存入该引用,第五个参数是指向没法使用的部分的指针,通常不会用到,给NULL就能够了

  */

    int status = sqlite3_prepare_v2(_shop, sql, -1, &stmt, NULL);

    if(status == SQLITE_OK)//准备成功,SQL语句正确

    {

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

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

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

        while(sqlite3_step(stmt) == SQLITE_ROW)//成功指向一条记录

        {

            Shop* shop=[[Shop alloc]init];//封装的实体

    /*sqlite3_column_xxxx函数:它用来读取数据行中不一样类型的数据,该函数的返回值就是读取到得数据内容,

      该函数须要2个参数,第一个参数是存放数据的stmt,第二个参数是数据列下标*/

            shop.pid= sqlite3_column_int(stmt, 0);//读取stmt中存储的第0列数据

            const char* pname= (const char*)sqlite3_column_text(stmt, 1);//读取stmt中存储的第1列数据

            const char* pprice = (const char*)sqlite3_column_text(stmt, 2);//读取stmt中存储的第2列数据

            shop.name = [NSString stringWithUTF8String:pname];//将C类型的字符串转换为oc类型的字符串并存储

            shop.price = [NSString stringWithUTF8String:pprice];//将C类型的字符串转换为oc类型的字符串并存储

            //NSLog(@"编号:%d,商品名:%s,价格:%s",shop.pid,pname,pprice);

        }

    }

}

 

  那么,写到这里,相信你们对sqlite3的基本使用已经有了大体的了解,若是对代码中有不理解的地方,或者有其余相关的问题,能够找我一块儿来研究讨论。

  第一次发博客,但愿你们提出宝贵的意见和建议,编程路上,与你同行。

相关文章
相关标签/搜索