SQLite⼊门使⽤教程(⼀)
⾸先,只要是对数据库操作有些了解的朋友都知道:数据库操作⽆⾮就是增,删,改,查,这些基本的操作。学习SQLite之前,⾸先要安装好SQLite的库⽂件,这个⼤家可以去官⽹上下。在Linux 下安装SQLite是⾮常⽅便的,我是⽤新得⽴软件包这个软件⼀键安装的,在Windows下,就需要sqlite3.dll,sqlite3.h,sqlite3.lib这三个⽂件,分别为动态库⽂件,头⽂件和静态库⽂件。然后相应的进⾏配置,这个可以去⽹上查。
接下来我们就来看官⽹上的介绍:
(⼀)核⼼对象和接⼝:
1. 在SQLite中最核⼼的两个对象是,databa_connection和prepared_statement。databa_connection对象是由sqlite3_open()接⼝函数创建并返回的,它是⼀个数据库连接对象,在程序使⽤任何其他SQLite接⼝函数之前,必须先调⽤该函数以便获得databa connection 对象,否则不能打开⼀个数据库。严格来讲,prepared statement对象不是必须的,因为有两个更为⽅便的包装接⼝: sqlite3_exec和sqlite3_get_table,这两个接⼝可以被⽅便的使⽤并且隐藏了 prepared statement对象。然⽽,对 prepared statement对象的理解对我们充分理解和使⽤SQLite数据库有很⼤的帮助。这两个接⼝函数在下⼀篇博⽂中讲解。
2.在SQLite中最核⼼的六个接⼝是:
sqlite3_open();
sqlite3_prepare();
sqlite3_step();
sqlite3_column();
sqlite3_finalize();
sqlite3_clo();
下⾯对它们的⽤法进⾏说明:
2.0 打开数据库:
int sqlite3_open(
const char *filename, /* Databa filename (UTF-8) */待打开(创建)的数据库⽂件名
sqlite3 **ppDb /* OUT: SQLite db handle */sqlite3数据库句柄的指针
);
该接⼝打开⼀个数据库⽂件,并与⼀个sqlite3句柄关联。如果该⽂件不存在则创建它。返回值如果是SQLITE_OK则打开成功。
如:sqlite3 *mysqlite3; //定义⼀个数据库句柄,可以理解为⼀个数据库连接
sqlite3_open("D:\\mysqlite\\mysqlite.db",&mysqlite3);
2.1 创建预处理语句对象:
int sqlite3_prepare(
sqlite3 *db, /* Databa handle */ 数据库句柄
const char *zSql, /* SQL statement, UTF-8 encoded */ sql语句
int nByte, /* Maximum length of zSql in bytes. */sql语句长度,设置成-1,则⾃动按字符串计算sql语句长度
sqlite3_stmt **ppStmt, /* OUT: Statement handle */ prepared statement对象
const char **pzTail /* OUT: Pointer to unud portion of zSql */ ⼀般为NULL即可
);
该接⼝把⼀个SQL语句⽂本转换成⼀个预处理语句对象并返回⼀个指向该对象的指针。这个接⼝需要⼀个由先前调⽤sqlite3_open()返回的数据库连接对象指针以及⼀个预处理的SQL语句⽂本字符串为参数。这个API并不实际解析SQL语句,仅仅是为后续的解析⽽对SQL语句进⾏的预处理。也就是说,调⽤sqlite3_prepare()将SQL语句编译为sqlite内部⼀个结构体(sqlite3_stmt),该结构体中包含了将要执⾏的的SQL语句的信息。
如:sqlite3_prepare_v2(mysqlite3,"lect * from friends",-1,&stmt,NULL);
2.2 执⾏SQL语句
int sqlite3_step(sqlite3_stmt*);
该接⼝⽤于解析⼀个由先前通过sqlite3_prepare()接⼝创建的预处理语句,直⾄返回第⼀⾏结果为⽌。通过再次调⽤
sqlite3_step()可以返回下⼀⾏的结果,继续不断
地调⽤sqlite3_step()直⾄整个语句完成为⽌。对于那些并不返回结果的语句(例如:inrt,delete语句等)⼀次调⽤
sqlite3_step()就完成了语句的处理。注意,调⽤sqlite3_step()这时候SQL语句才真正执⾏,⼀次它只返回⼀⾏数据。
返回值:SQLITE_BUSY:数据库被锁,可以等待释放后重新调⽤该函数
SQLITE_DONE:成功
SQLITE_ROW:成功并且有数据返回,每查询到⼀条数据都会返回该值
SQLITE_ERROR:失败
SQLITE_MISUSE:错误的调⽤,⽐如已经返回了SQLITE_DONE或者SQLITE_ERROR后还继续调⽤该函数
如:sqlite3_step(stmt);
人间大爱2.3 对返回的⾏数据中的每⼀列进⾏查询:sqlite3_column_xxx,其中blob,double,int,int64,text,text16表⽰的是要查询的那⼀列的数据类型
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);//其中参数iCol为列号,从0开始,即第⼀列为0
int sqlite3_column_bytes(sqlite3_stmt*, int iCol); //sqlite3_stmt* 为prepared statement对象的指针
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);年初工作会议讲话
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
以上接⼝返回⼀个由sqlite3_step()解析的预处理语句结果集中当前⾏的某⼀列数据。每次执⾏sqlite3_step()都返回⼀个新的结果集中的⼀⾏。可以多次调⽤sqlite3_column_xxx()接⼝返回那⼀⾏中所有列的数据。sqlite3_column_xxx是⼀组⽤于从结果集中查询出各个列项各种数据类型数据的函数接⼝。在这组函数接⼝中,有些接⼝返回结果集的⼤⼩,有些返回结果集的列数。
如:
int ID = sqlite3_column_int( stmt, 0 );
char * IP = sqlite3_column_text(stmt,1 );
char *name = sqlite3_column_text( stmt, 2 );
2.4 销毁预处理语句sqlite3_finalize()
int sqlite3_finalize(sqlite3_stmt *pStmt);
sqlite3_finalize()释放之前调⽤sqlite3_prepare()创建的预处理语句stmt占⽤的内存,该内存是在sqlite3_prepare()时分配的,每⼀个预处理语句都必须调⽤这个接⼝进⾏销毁以避免内存泄漏。
如:sqlite3_finalize(stmt);
2.5 关闭数据库 sqlite3_clo()
int sqlite3_clo(sqlite3*);
该接⼝关闭⼀个由之前调⽤sqlite3_open()创建的数据库连接,所有与该连接相关的预处理语句都必须在关闭连接之前销毁。如:sqlite3_clo(mysqlite3);
下⾯,通过⼀个实例代码来演⽰它们的⽤法:
void Talk() //根据ID号204,查询其IP为多少
{
sqlite3 *mysqlite3; //SQLite 连接对象
烫面戚风
int reopen;
reopen = sqlite3_open("D:\\mysqlite\\mysqlite.db",&mysqlite3);//返回值如果是SQLITE_OK,则打开成功,SQLITE_OK为sqlite3.h中的宏定义
if(reopen != SQLITE_OK ) //#define SQLITE_OK 0 /* Successful result */ {
cout<<"it failed to open mysqlite.db"<<endl;
}el
{
cout<<"it success to open mysqlite.db"<<endl;
}
sqlite3_stmt *stmt;//prepare_statment 对象
char *sql="lect IP from urInfo where ID = 204"; //SQL语句,表⽰查询ID=204所在的那⾏的IP那⼀列的数据
sqlite3_prepare_v2(mysqlite3,sql,-1,&stmt,NULL); //把SQL语句作为第⼆个参数传⼊,第三个参数-1 表⽰⾃动按字符串计算sql语句长度,第五个⼀般为NULL轻雪
int restep = sqlite3_step(stmt)//返回值如果是SQLITE_ROW,表⽰成功并且有数据返回,SQLITE_ROW为sqlite3.h中的宏定义
if(restep == SQLITE_ROW) //#define SQLITE_ROW 100释迦果的功效与作用
{
char *IP= (char *)sqlite3_column_text(stmt,0); //因为这⾥只返回IP那⼀列的值,所以第⼆个参数为0 cout <<
IP<<endl;
}
sqlite3_finalize(stmt);
sqlite3_clo(mysqlite3);
}
通过上⾯的例⼦相信⼤家应该基本学会了SQLITE3的基本⽤法,再来分析上⾯的例⼦,相信⼤家会发现它的不灵活,因为它查询的ID是写死的,如果我想查询任⼀个ID的信息呢?那就需要把ID作为形参传⼊这个函数,这就是接下来要讲的:
(⼆)参数绑定和重新执⾏已编译语句
在上⾯的讨论中,假定每个SQL语句⼀旦准备,然后就执⾏,最后被销毁。然⽽,SQLite3允许相同的预处理语句执⾏多次。这时使⽤以下程序来完成:sqlite3_bind() sqlite3_ret()
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); //sqlite3_bind_ 后⾯跟着的⼤多是绑定的数据类型,有⼆进制对象,整形等
int sqlite3_bind_double(sqlite3_stmt*, int, double); //所有的这些函数第⼆个参数表⽰绑定SQL语句中的第⼏个参数,最左边的SQL参数的索引为1
int sqlite3_bind_int(sqlite3_stmt*, int, int); //第三个参数为绑定到占位符的值,即SQL参数的值
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
自驾游旅游攻略int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);//第四个参数为参数的字节数(注意不是字符数),如果为负,则把参数当作字符串输⼊
int sqlite3_ret(sqlite3_stmt *pStmt); //第⼀个参数是⼀个指向sqlite3_stmt对象的指针
即sqlite3_bind_XXX()函数将对应的参数传⼊,sqlite3_ret()来清除已经绑定的参数。当⼀个准备语句(prepared statement)被执⾏通过⼀次或多次调⽤sqlite3_step (),它也可以调⽤sqlite3_ret ()来重置。之所以调⽤
sqlite3_ret()来重置⽽不是调⽤sqlite3_prepare()来重新创建,是因为可以避免不必要的消耗。通常
我们很少多次执⾏完全相同的SQL语句,更多的时候我们可能需要执⾏⼀个相似的语句,⽐如插⼊多条数据,执⾏的是相似的INSERT语句,只是其中包含的参数不同,这些参数可以在语句被执⾏之前绑定到⼀个变量上,我们只需要不断的改变这个变量的值,然后执⾏相同的准备语句(prepared statement)即可。
在SQLITE中可以使⽤以下⼏种:
NNN
风景微信头像:AAA
$AAA
@AAA
这些参数只是代表了⼀个占位符,我们可以通过调⽤sqlite3_bind()来绑定具体的值到这个占位符上。这⼏个参数的具体⽤法与区别可以参考下⾯这个链接:
下⾯,通过⼀个实例代码来演⽰它们的⽤法:还是上⾯那个图中的数据
void Talk(int id) //根据ID号这个形参,查询其IP为多少
夏吃姜
{
sqlite3 *mysqlite3; //SQLite 连接对象
int reopen;
reopen = sqlite3_open("D:\\mysqlite\\mysqlite.db",&mysqlite3);
if(reopen != SQLITE_OK )
{
cout<<"it failed to open mysqlite.db"<<endl;
}el
{
cout<<"it success to open mysqlite.db"<<endl;
}
sqlite3_stmt *stmt;//prepare_statment 对象
char *sql="lect IP from urInfo where ID = @id"; //这⾥⽤的是@AAA这个占位符,也可以⽤其他的⼏个
sqlite3_prepare_v2(mysqlite3,sql,-1,&stmt,NULL);
sqlite3_bind_int(stmt, 1, id); //把id这个变量绑定到占位符上,我们可以通过函数的形参把具体的值传给id这个变量
int restep = sqlite3_step(stmt);
if(restep == SQLITE_ROW) //查询IP
{
char *IP= (char *)sqlite3_column_text(stmt,0);
cout << IP<<endl;
}
sqlite3_finalize(stmt);
sqlite3_clo(mysqlite3);
}
sqlite3_ret()是来清除已经绑定的参数,⽐较简单,这⾥不多讲它的⽤法了。