iOS_数据存取(二)

时间:2021-06-02 00:27:58

本节内容目录:

一、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", -, &pStmt, NULL);
while (sqlite3_step(pStmt) == SQLITE_ROW) {
//取出对应列的字段值,
int ID = sqlite3_column_int(pStmt, );
const unsigned char *name = sqlite3_column_text(pStmt, );
const unsigned char *password = sqlite3_column_text(pStmt, );
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\n",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 = ; i < ; i++)
{
Student *stu = [[Student alloc]init];
stu.name = [NSString stringWithFormat:@"name%d",i+];
stu.age = +i;
stu.gender = (i % == ? 'F':'M');
stu.chineseScore = +i;
stu.mathScore = +i;
stu.englishScore = +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], -, &pStmt, nil) == SQLITE_OK)
{
//使用sqlite3_bind_xxx()对字段进行绑定,通配符与绑定的字段一一对应。序号从1开始。
sqlite3_bind_text(pStmt, , [student.name UTF8String], -, NULL);
sqlite3_bind_int(pStmt, , student.age);
sqlite3_bind_int(pStmt, , student.gender);
sqlite3_bind_double(pStmt, , student.chineseScore);
sqlite3_bind_double(pStmt, , student.mathScore);
sqlite3_bind_double(pStmt, , 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], -, &pStmt, NULL)== SQLITE_OK)
{
sqlite3_bind_int(pStmt, , student.mathScore);
sqlite3_bind_text(pStmt, , [student.name UTF8String], -, 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], -, &pStmt, nil) == SQLITE_OK)
{
sqlite3_bind_text(pStmt, , [name UTF8String], -, 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], -, &pStmt, NULL) == SQLITE_OK)
{
//遍历结果集
while (sqlite3_step(pStmt) == SQLITE_ROW)
{ Student *stu = [[Student alloc]init];
stu.ID = sqlite3_column_int(pStmt, );
stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, )];
stu.age = sqlite3_column_int(pStmt, );
stu.gender = sqlite3_column_int(pStmt, );
stu.chineseScore = sqlite3_column_double(pStmt, );
stu.mathScore = sqlite3_column_double(pStmt, );
stu.englishScore = sqlite3_column_double(pStmt, ); [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], -, &pStmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(pStmt, , [name UTF8String], -, NULL);
//执行语句
if(sqlite3_step(pStmt)== SQLITE_ROW)
{
Student *stu = [Student new];
// 使用sqlite3_column_xxx()进行获取某列的字段值。
stu.ID = sqlite3_column_int(pStmt, );
stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, )];
stu.age = sqlite3_column_int(pStmt, );
stu.gender = sqlite3_column_int(pStmt, );
stu.chineseScore = sqlite3_column_double(pStmt, );
stu.mathScore = sqlite3_column_double(pStmt, );
stu.englishScore = sqlite3_column_double(pStmt, ); 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\n",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 二进制大对象类型,能够存放任何二进制数据