zoukankan      html  css  js  c++  java
  • iOS_数据存取(二)

    本节内容目录:

    一、SQLite3

    二、Core Data

    一、SQlite3

    SQLite3是⼀款开源的嵌入式关系型数据库,可移植性好、易使用、内存开销小
    SQLite3是⽆类型的,意味着你可以保存任何类型的数据到任意表的任意字段中。⽐如下列的创表语句是合法的:
    create table t_person(name, age);
    为了保证可读性,建议还是把字段类型加上:

    create table t_person(name text, age integer);

    SQLite3常用的5种数据类型:text、integer、float、boolean、blob 在iOS中使用SQLite3,⾸先要添加库文件libsqlite3.dylib和导入主头文件
     
    1.sqlite3的基本操作(增删改查)
    #import "ViewController.h"
    #import <sqlite3.h>
    @interface ViewController ()
    {
        sqlite3 *_db;
    }
    @end
    @implementation ViewController
    -(void)queryAll
    {
        //准备结果集
        sqlite3_stmt *pStmt = NULL;
        /*
         第一个参数为sqlite3 *类型,为指向sqlite3_open()类函数打开的数据库连接。
         第二个参数为需要编译成字节码的sql语句。如果输入的参数有多条sql语句,只有第一个SQL语句被编译。
         第三个参数,若为小于0的值,系统会自动读取第一个参数一直到出现字符结束符。若该参数大于0,则它表明要读入的SQL的最大的程度,建议设置其值为sql语句的字节数加上字符结束符后的值,此时执行的效率会有提升。
         第四个参数,返回编译好的sqlite3_stmt指针,若第一个参数不包含SQL语句或传进来的SQL语句有错,则此函数返回时被置为NULL。
         第五个参数若不为NULL,则它会指向第一条SQL语句结尾后面的第一个字节。这个参数用于指向剩下的未编译的语句。
         */
          sqlite3_prepare_v2(_db, "select *from user", -1, &pStmt, NULL);
        while (sqlite3_step(pStmt) == SQLITE_ROW) {
            //取出对应列的字段值,
            int ID = sqlite3_column_int(pStmt, 0);
            const unsigned char *name = sqlite3_column_text(pStmt, 1);
            const unsigned char *password = sqlite3_column_text(pStmt, 2);
            NSLog(@"%d,%s,%s",ID,name,password);
        }
    }
    -(void)execSql:(NSString *)sql
    {
        char *errorMsg = nil;
        /*
         第一个参数为sqlite3 *类型。通过sqlite3_open()函数得到
         第二个参数是一个指向一个字符串的指针,该字符串的内容为一条完整的SQL语句(不需要在语句结束后加";"),字符串都是以/0结尾的,这个也不例外。
         第三个参数为一个回调函数,当这条语句执行之后,sqlite3会去调用这个函数。其原型为
         typedef  int (*sqlite_callback)(void *,int,char **colvalue,char **colname);
         第四个参数为提供给回调函数的参数。如果不需要传递参数,则可以写为NULL。
         第五个参数为错误信息。注意,是指针的指针。通过打印printf("%s
    ",errmsg),可以知道错误发生在什么地方。
         */
        sqlite3_exec(_db, [sql UTF8String], nil, nil, &errorMsg);
        if (errorMsg) {
            NSLog(@"执行失败:%s",errorMsg);
        }
        else
        {
            NSLog(@"执行成功");
        }
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        //拼接数据库保存路径
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [documents lastObject];
        NSString *dbName = [path stringByAppendingPathComponent:@"test.db"];
      
        //打开数据库
        if (sqlite3_open([dbName UTF8String], &_db) == SQLITE_OK) {
            //创建表
            [self execSql:@"create table user(ID integer,name text,password text)"];
            //插入两条新纪录
            [self execSql:@"insert into user values(1,'admin','123456')"];
            [self execSql:@"insert into user values(2,'guest','123456')"];
            //查询记录
            [self queryAll];
            //更新记录
            [self execSql:@"update user set password = password + 10 where name = 'admin'"];
            [self queryAll];
            //关闭数据库
            sqlite3_close(_db);
        }
        else
        {
            NSLog(@"打开失败");
        } 
    }
    @end

     以上案例中通过C语言函数的形式实现了简单地Sqlite基本操作,这并不符合面向对象程序设计的基本思想,接下来案例中,通过自定义对象来创建数据库。

    Student.h头文件代码如下:
    
    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject
    @property(assign,nonatomic)NSInteger ID;
    @property(copy,nonatomic)NSString *name;
    @property(assign,nonatomic)int age;
    @property(assign,nonatomic)char gender;
    @property(assign,nonatomic)float chineseScore;
    @property(assign,nonatomic)float mathScore;
    @property(assign,nonatomic)float englishScore;
    @end
    
    Student.m代码如下:
    #import "Student.h"
    
    @implementation Student
    -(NSString *)description
    {
        return [NSString stringWithFormat:@"%ld,%@,%d,%c,%.2f,%.2f,%.2f",_ID,_name,_age,_gender,_chineseScore,_mathScore,_englishScore];
    }
    @end

    以上代码,构建了Student模型。

    StudentDAO.h头文件代码如下:

    #import <Foundation/Foundation.h>
    #import <sqlite3.h>
    @class Student;
    @interface StudentDAO : NSObject
    {
        sqlite3 *_db;
    }
    +(StudentDAO *)shardManger;
    //初始化:创建表,添加数据;
    -(void)initDataBase;
    //添加学生记录
    -(BOOL)addStudent:(Student *)student;
    //删除学生记录
    -(BOOL)deleteStudentByName:(NSString *)name;
    //更新学生记录
    -(BOOL)updateStudent:(Student *)student;
    //查询学生记录
    -(NSArray *)queryStudentAll;
    -(Student*)queryStudentByName:(NSString *)name;
    @end

    StudentDAO.m代码如下:

    #import "StudentDAO.h"
    #import "Student.h"
    #import <sqlite3.h>
    static StudentDAO *instace = nil;
    @implementation StudentDAO
    //创建单例对象,确保数据库只被初始化一次,
    +(StudentDAO *)shardManger
    {
        static dispatch_once_t once;
        dispatch_once(&once,^{
            instace = [StudentDAO new];
            [instace initDataBase];
        });
        return instace;
    }
    //拼接数据库路径
    -(NSString *)dbPath
    {
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [documents lastObject];
       return [path stringByAppendingPathComponent:@"test.db"];
    }
    //此方法会多次被调用,用户创建表
    -(BOOL)execSql:(NSString *)sql
    {
        char *errorMsg = NULL;
        //参数详解,请参考⬆️上个案例
        sqlite3_exec(_db, [sql UTF8String], nil, nil, &errorMsg);
        if (errorMsg)
        {
            NSLog(@"执行失败:%s",errorMsg);
            return NO;
        }
        else
        {
            NSLog(@"执行成功");
            return YES;
            
        }
    }
    -(void)initDataBase
    {
        //打开数据库
        if (sqlite3_open([[self dbPath]UTF8String], &_db) == SQLITE_OK)
        {
            //创建表
            if ([self execSql:@"create table student (ID integer primary key autoincrement,name text,age integer,gender integer,chineseScore real,mathScore real,englishScore real)"])
            {
                for (int i = 0; i < 5; i++)
                {
                    Student *stu = [[Student alloc]init];
                    stu.name = [NSString stringWithFormat:@"name%d",i+1];
                    stu.age = 22+i;
                    stu.gender = (i % 2 == 0 ? 'F':'M');
                    stu.chineseScore = 74+i;
                    stu.mathScore = 85+i;
                    stu.englishScore = 92+i;
                    [self addStudent:stu];
                    
                }
            }
        }
        sqlite3_close(_db);
    }
    //添加学生记录
    -(BOOL)addStudent:(Student *)student
    {
        NSString *insertSql = @"insert into student(name text,age integer,gender integer,chineseScore real,mathScore real,englishScore real)";
        sqlite3_stmt *pStmt = nil;
        if (sqlite3_prepare_v2(_db, [insertSql UTF8String], -1, &pStmt, nil) == SQLITE_OK)
        {
            //使用sqlite3_bind_xxx()对字段进行绑定,通配符与绑定的字段一一对应。序号从1开始。
            sqlite3_bind_text(pStmt, 1, [student.name UTF8String], -1, NULL);
            sqlite3_bind_int(pStmt, 2, student.age);
            sqlite3_bind_int(pStmt, 3, student.gender);
            sqlite3_bind_double(pStmt, 4, student.chineseScore);
            sqlite3_bind_double(pStmt, 5, student.mathScore);
            sqlite3_bind_double(pStmt, 6, student.englishScore);
    //        SQLITE_DONE:SQL语句执行完成
            if (sqlite3_step(pStmt) == SQLITE_DONE)
            {
                return YES;
            }
            //释放结果集
            sqlite3_finalize(pStmt);
        }
        return NO;
    }
    //更新学生记录
    -(BOOL)updateStudent:(Student *)student
    {
        NSString *updateSql = @"update student set math = ? where name = ?";
        //准备结果集
        sqlite3_stmt *pStmt = NULL;
        if (sqlite3_prepare_v2(_db, [updateSql UTF8String], -1, &pStmt, NULL)== SQLITE_OK)
        {
            sqlite3_bind_int(pStmt, 1, student.mathScore);
            sqlite3_bind_text(pStmt, 2, [student.name UTF8String], -1, NULL);
            if (sqlite3_step(pStmt) == SQLITE_DONE)
            {
                return YES;
            }
        }
        //清理结果集
        sqlite3_finalize(pStmt);
        return NO;
    }
    
    //通过姓名进行删除
    -(BOOL)deleteStudentByName:(NSString *)name
    {
        NSString *deleteSql = @"delete from student where name = ?";
        sqlite3_stmt *pStmt = NULL;
        if (sqlite3_prepare_v2(_db, [deleteSql UTF8String], -1, &pStmt, nil) == SQLITE_OK)
        {
            sqlite3_bind_text(pStmt, 1, [name UTF8String], -1, NULL);
            if (sqlite3_step(pStmt) == SQLITE_OK)
            {
                return YES;
            }
        }
        sqlite3_finalize(pStmt);
        return NO;
    }
    //查询学生记录
    -(NSArray *)queryStudentAll
    {
        NSMutableArray *array = [NSMutableArray array];
        //准备结果集
        sqlite3_stmt *pStmt = NULL;
        if (sqlite3_prepare_v2(_db, [@"select * from student" UTF8String], -1, &pStmt, NULL) == SQLITE_OK)
        {
            //遍历结果集
            while (sqlite3_step(pStmt) == SQLITE_ROW)
            {
                
                Student *stu = [[Student alloc]init];
                stu.ID = sqlite3_column_int(pStmt, 0);
                stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, 1)];
                stu.age = sqlite3_column_int(pStmt, 2);
                stu.gender = sqlite3_column_int(pStmt, 3);
                stu.chineseScore = sqlite3_column_double(pStmt, 4);
                stu.mathScore = sqlite3_column_double(pStmt, 5);
                stu.englishScore = sqlite3_column_double(pStmt, 6);
                
                [array addObject:stu];
            }
        }
        //清理结果集
        sqlite3_finalize(pStmt);
        return array;
    }
    //通过姓名进行查找
    -(Student *)queryStudentByName:(NSString *)name
    {
        NSString *sql = @"select * from student where name = ?";
        //准备结果集
        sqlite3_stmt *pStmt = NULL;
        if (sqlite3_prepare_v2(_db,[sql UTF8String], -1, &pStmt, NULL) == SQLITE_OK) {
            sqlite3_bind_text(pStmt, 1, [name UTF8String], -1, NULL);
            //执行语句
            if(sqlite3_step(pStmt)== SQLITE_ROW)
            {
                Student *stu = [Student new];
    //            使用sqlite3_column_xxx()进行获取某列的字段值。
                stu.ID = sqlite3_column_int(pStmt, 0);
                stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, 1)];
                stu.age = sqlite3_column_int(pStmt, 2);
                stu.gender = sqlite3_column_int(pStmt, 3);
                stu.chineseScore = sqlite3_column_double(pStmt, 4);
                stu.mathScore = sqlite3_column_double(pStmt, 5);
                stu.englishScore = sqlite3_column_double(pStmt, 6);
                
                return stu;
            }
        }
        sqlite3_finalize(pStmt);
        return nil;
    }
    @end

    以下内容是从网络中摘抄的一些东西,供大家学习参考。

    sqlite提供了一些C函数的接口,有100多个,可以通过这些接口操作数据库,传递一些标准sql语句(以char * 类型)给sqlite函数,sqlite就会为你操作数据库。关于SQL语句,在本目录下已经由文章详细介绍,读者自己查看。
    大部分函数,如sqlite3_open()一般还有sqlite3_open16()的版本,前一个表示使用的是UTF-8编码,后一个表示使用的是UTF-16编码。本文为节省篇幅和考虑实用性,仅介绍sqlite3_open()系列,即UTF-8编码的函数,一些不常用或基本不用的系统API将被忽略。
     
    SQLITE关键数据结构:sqlite3 *
    包含于头文件:#include  <sqlite3.h> ,关于这个类型的原型自然可以找到,但是对于数据库的操作不需要知道这个,因此,我也没去关注它。sqlite3 *类型,从数据库打开到关闭,都需要使用到它。
    SQLITE打开数据库:sqlite3_open()
    1】函数原型:int sqlite3_open(const char *filename,sqlite3 **ppDb);
    2】函数参数:
    第一个是数据库文件名,可以包含路径。如 "./sqlite3/student.db"
    第二个参数为指向sqlite *类型的一个指针。
    3】返回值:操作成功,返回SQLITE_OK。否则返回其他宏。定义在#include  <sqlite3.h>中
    例句:
    sqlite3_open([dbName UTF8String], &_db);
     
    SQLITE关闭数据库:sqlite3_close()
    函数原型:int  sqlite3_close(sqlite3 *ppDb);
     
    SQLITE错误消息:sqlite3_errmsg()
    1】函数原型:const  char  *sqlite3_errmsg(sqlite3 *ppDb);
    2】返回值:提示出错信息的字符串,可以直接用%s打印 
     
    SQLITE操作SQL语句:sqlite3_exec()
    1】函数原型:int   sqlite3_exec(sqlite3 *ppDb,const char *sql,sqlite3_callback,void *,char **errmsg);
    2】参数说明:
    第一个参数为sqlite3 *类型。通过sqlite3_open()函数得到
    第二个参数是一个指向一个字符串的指针,该字符串的内容为一条完整的SQL语句(不需要在语句结束后加";"),字符串都是以/0结尾的,这个也不例外。
    第三个参数为一个回调函数,当这条语句执行之后,sqlite3会去调用这个函数。其原型为 
    typedef  int (*sqlite_callback)(void *,int,char **colvalue,char **colname);
    第四个参数为提供给回调函数的参数。如果不需要传递参数,则可以写为NULL。
    第五个参数为错误信息。注意,是指针的指针。通过打印printf("%s ",errmsg),可以知道错误发生在什么地方。
    3】返回值:执行成功,返回SQLITE_OK,失败返回其他值。
    -(void)execSQL:(NSString *)sql
    {
        char *errormessage = NULL;
        sqlite3_exec(_db, [sql UTF8String],NULL,NULL, &errormessage);
        if (errormessage)
        {
            NSLog(@"执行%@失败:%s",sql,errormessage);    
        }
        else
        {
            NSLog(@"执行成功");
        }
    }
    SQLITE非回调方法查询数据库:sqlite3_get_table()
    1】函数原型:int  sqlite3_get_table(sqlite3 *,const  char *sql,char ***resultp,int   *nrow,int  *ncolumn,char  **errmsg);
    2】参数说明:
    第一个参数为sqlite3 *类型
    第二个参数为一条SQL语句,与sqlite3_exec()函数的第二个参数相同。
    第三个参数为查询结果。注意,这个仍然是一个一维数组(不是三维,更不是二维)。在内存中的布局是第一行是字段名称,后面紧接着是每个字段的值。
    第四个参数是查询出多少条数据(即查出多少行)
    第五个参数为多少个字段,即查出多少列。
    第六个参数为错误信息。与sqlite3_exec()的第五个参数相同。
    3】例程:省略。在本文开头的引用页内有详细代码,读者自己理解。
     
    SQLITE中sqlite3_exec()的替代:sqlite3_prepare()、sqlite3_step()、sqlite3_finalize()
    1】共同涉及到的类型sqlite3_stmt  
    typedef  struct  sqlite3_stmt  sqlite3_stmt;
    2】函数版本说明:则三个函数实现将sql语句编译成字节码,然后执行和释放。这三个函数都有V2版本,应该尽量使用新版本。v2版本和原版本都是基于UTF-8编码说明。v2版本和原版本一个很大的不同,在于返回值上,v2版本要更丰富。
    3】函数原型
    int sqlite3_prepare(sqlite3 *db,const char *zSql,int nByte,sqlite3_stmt **ppStmt,const char **pzTail);
    int sqlite3_prepare_v2(sqlite3 *db,const char *zSql,int nByte,sqlite3_stmt **ppStmt,const char **pzTail);
    例如:
    sqlite3_stmt *pStmt = NULL;
    //*stmt, 这个相当于ODBC的Command对象,用于保存编译好的SQL语句
    sqlite3_prepare_v2(_db, "select *from user", 256, &pStmt, NULL);
    int sqlite3_step(sqlite3_stmt*);
     
    int sqlite3_finalize(sqlite3_stmt *pStmt);
    4】参数说明:(针对sqlite3_prepare()函数进行参数说明)
    第一个参数为sqlite3 *类型,为指向sqlite3_open()类函数打开的数据库连接。
    第二个参数为需要编译成字节码的sql语句。如果输入的参数有多条sql语句,只有第一个SQL语句被编译。
    第三个参数,若为小于0的值,系统会自动读取第一个参数一直到出现字符结束符。若该参数大于0,则它表明要读入的SQL的最大的程度,建议设置其值为sql语句的字节数加上字符结束符后的值,此时执行的效率会有提升。
    第四个参数,返回编译好的sqlite3_stmt指针,若第一个参数不包含SQL语句或传进来的SQL语句有错,则此函数返回时被置为NULL。
    第五个参数若不为NULL,则它会指向第一条SQL语句结尾后面的第一个字节。这个参数用于指向剩下的未编译的语句。
    5】函数功能说明:sqlite3_prepare()函数用于将sql语句编译成字节码,并通过sqlite3_stmt类型的参数返回,sqlite3_step()函数,通过使用这个参数一次或者多次来执行这个SQL语句。根据sqlite3_prepare()函数使用的版本,其操作也不同。最后需要调用sqlite3_finalize()函数将这个准备的SQL声明(sqlite3_stmt类型的参数)销毁,避免内存泄露。
    6】 返回值:sqlite3_prepare()系列函数和sqlite3_finalize()函数执行成功返回SQLITE_OK,否则返回错误码。sqlite3_step()函数返回值(根据sqlite3_prepare()的版本不同)如下:
    老版本里面:
    SQLITE_BUSY:无法获取数据库锁来执行此操作
    SQLITE_DONE:SQL语句执行完成,在没有再次调用sqlite3_reset()重设SQL到初始状态前不能再调用sqlite3_step()
    SQLITE_ROW:如果执行的SQL语句返回了数据,则每次返回一行新的数据
    SQLITE_ERROR:执行SQL语句出错。
    SQLITE_MISUSE:未知
    新版本里面返回任何可能的结果编号。
    SQLITE重置一个SQL声明的状态sqlite3_reset()
    1】函数原型:int  sqlite3_reset(sqlite3_stmt  *stmt);
    2】返回值,执行成功返回SQLITE_OK,否则返回错误码
    3】功能说明:sqlite3_reset()函数用来重置一个SQL声明的状态,使得它可以被再次执行。任何的SQL声明中使用sqlite3_bind_*()绑定的变量仍然保留原来的值,可以用sqlite3_clear_bindings()来重设这些绑定的值。
     
    SQLITE表内写入二进制步骤:
    1、create table  Tbl_2(ID interger,file_content  blob)。要插入二进制,前提是这个表的字段的类型是blob类型。
    2、声明sqlite3_stmt  *stat变量,运用sqlite3_prepare(db,"insert  into Tbl_2(ID,file_content)VALUES(10,?)",-1,&stat,NULL);将SQL语句解析到stat结构里去。与前面不同的是,第二个参数sql语句中,在values里面有个"?",表示一个未定的值,也可以理解为是一个占位符。其值通过后续步骤才能插入。
    3、使用sqlite3_bind_blob()绑定一个blob类型的值。调用语句为:
    sqlite3_bind_blob(stat,1,pdata,(int)(length_of_data_in_bytes),NULL);
    1】函数原型为:int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

    2】参数说明:

    第一个参数为sqlite3_stmt *类型,由sqlite3_prepare()函数返回。
    第二个参数为"?"的索引,表示第几个"?"的位置。如果有多个问号,那就写多个sqlite3_bind_blob()函数。
    第三个参数为二进制数据的起始指针。
    第四个参数为二进制数据的长度,以字节为单位。
    第五个参数是个析构回调函数,告诉sqlite当把数据处理完后,调用此函数来析构数据。通常设为NULL,调用完后自己释放。
    4、上步的bind操作将二进制数据写入到了经过字节编码的sql语句里面了,调用sqlite3_step(stat)将其保存到数据库中。最后用sqlite3_finalize(stat)函数对其进行释放。
     
    SQLITE表内读出二进制步骤: 
    1、读出数据,就是写入过程的一个逆过程。首先定义一个sqlite3_stmt  *stat 变量,调用sqlite3_prepare(db,"select * from Tbl_2",-1,&stat,NULL)将一个sql语句解析到stat结构里去。
    2、调用sqlite3_step(stat)来查询数据,当返回值为SQLITE_ROW时表示成功(注意不是SQLITE_OK),可以循环执行sqlite3_step函数,一次step查询出一条记录。直到返回值不是SQLITE_ROW时表示查询结束。
    3、调用sqlite3_column_int(stat,0)获取第一个字段的数值id。调用sqlite3_column_blob(stat,1)获取const void *pFileContent,即file_content二进制数据的指针,调用sqlite3_column_bytes(stat,1)获取它的长度len。这样就得到了二进制的值。
    这三个函数sqlite3_column_int()、sqlite3_column_blob()、sqlite3_column_bytes()是同一个系列的函数。其通用的函数原型为 int    sqlite3_column_xxx(sqlite3_stmt*, int iCol);其中第二个参数为列数,即第几个参数。关于这个系列函数的更多细节,请自行查看CSDN上大神的解读,引用页http://blog.csdn.net/mamong/article/details/8441091
    4、经过上面3步后,第四步就是保存pFileContent指向的内容,同时不要忘记释放sqlite3_stmt结构。调用sqlite3_finalize(stat),把刚才分配的内容析构掉。
     
    SQLITE事务处理:
    sqlite支持事务处理。通常一次sqlite3_exec()就是一次事务,如果要删除1万条数据,开始新事务->删除一条数据->提交事务->开始新事务->删除一条数据->提交事务-> ......用这种方法是很慢的。你可以把这些同类的操作做成一个事务,这样如果操作错误,还能够回滚事务。事务的操作没有特别的接口函数,它就是一个普通的sql语句而已,分别如下:
    int  result;
    result = sqlite3_exec(db,"begin transaction",0,0,&zErrorMsg);//开始一个事务
    result = sqlite3_exec(db,"commit transaction",0,0,&zErrorMsg);//提交事务
    result = sqlite3_exec(db,"rollback transaction",0,0,&zErrorMsg);//回滚事务
     
    SQLITE数据库加密:
    SQLITE支持加密扩展,首先要定义一个宏SQLITE_HAS_CODEC。在代码最前面(也可以在sqlite3.h文件的第一行)定义:
    #ifndef    SQLITE_HAS_CODEC
    #define SQLITE_HAS_CODEC
    #endif
    。。。。。。
     
     
    在使用Sqlite3进行数据库操作时我大致划分:
    准备工作:导入系统框架(C语言)。(libsqlite3)
    libsqlite3.dylib
    1.初始化数据,其中在初始化阶段要做的工作有:
    1)设置数据库的存储路径
    NSArray *document = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentPath = [document lastObject];
       
        return [documentPath stringByAppendingPathComponent:@"student1.db"];
     (2)在数据库建立成功之后,使用sqlite3_open()进行打开数据库,如果返回值等于SQLITE_OK则表示打开成功。
    if (sqlite3_open([[self pathForDB]UTF8String], &_db)== SQLITE_OK)
    {  
    }
     
    (3)接下来要做的就在数据库中进行创建表;
              1).编写SQL语句
      NSString *insertSql = @"insert into student (name,age,gender,math,english,chinese)values(?,?,?,?,?,?)"; 
              2).通过sqlite3_prepare_v2()函数对象SQL语句进行编译执行,在执行成功之后,将结果保存到sqlite3_stmt()结果集中。
    //准备结果集
    sqlite3_stmt *pStmt = NULL;
    if(sqlite3_prepare_v2(_db, [insertSql UTF8String], -1, &pStmt, NULL)== SQLITE_OK)
    {}
    以上代码中注意:参数3:若为小于0的值,系统会自动读取第一个参数一直到出现字符结束符。若该参数大于0,则它表明要读入的SQL的最大的程度,建议设置其值为sql语句的字节数加上字符结束符后的值,此时执行的效率会有提升。
    2.在对数据进行修改操作时(比如:插入,修改,删除),SQL语句中在为之字段值是可以使用通配符“?”进行代替
         (1)使用sqlite3_bind_xxx()对字段进行绑定,通配符与绑定的字段一一对应。序号从1开始。
         其中:xxx表示的是字段类型
         例如: sqlite3_bind_int(pStmt, 1, (int)student.age);
     
    3.在对数据进行查询操作时,SQL语句中在也可为之字段值是可以使用通配符“?”进行代替。
         (1)使用sqlite3_column_xxx()进行获取某列的字段值。
    例如:stu.age = sqlite3_column_int(pStmt, 2);
    4.在对结果集使用结束之后,使用sqlite3_finalize函数进行清理结果集。
    //清理结果集
    sqlite3_finalize(pStmt);
    5.最后就是关闭数据库。
    sqlite3_close(_db);
     

    SQLite支持的常见数据类型如下所示。

    1. INTEGER 有符号的整数类型
    2. REAL 浮点类型
    3. TEXT 字符串类型,采用UTF-8和UTF-16字符编码
    4. BLOB 二进制大对象类型,能够存放任何二进制数据
  • 相关阅读:
    每日日报
    每日日报
    java笔记
    每日日报
    每日日报
    每日日报
    查看当前mysql时区 并设置为北京时间
    springboot 指定配置文件启动, 区分开发和线上分支
    Js Contains方法
    vue $refs的基本用法
  • 原文地址:https://www.cnblogs.com/xjf125/p/4849571.html
Copyright © 2011-2022 走看看