关系型数据库-sqlite3(c/c++的API接口)

数据库对c/c++的API接口

DB数据库本质只是一些用户的数据 通过DBMS去管理用户数据 而DBMS是通过SQL语句去控制的 之前我们都是在终端上输入SQL语句
接下来我们需要学会如何在代码中去控制DBMS

sqlite3的API接口的核心部分:

	两大对象 
	八大函数

两大对象

	数据库连接对象(表示你要操作哪个数据库) 
		
		数据库连接句柄/相当于数据库的文件描述符
		sqlite3 * 代表你打开的按个sqlite3的数据库文件(test.db)
		后续对数据库的操作都需要使用到该对象 
		
		
	SQL语句对象  
	
		就是一条准备好的SQL语句	
		操作数据库的标准语言就是SQL语句 在这里就是使用准备好的SQL语句对象去操作数据库连接对象表示的数据库

八大函数
在函数中操作sqlite3数据库的流程:

		1.打开数据库 建立连接 
			
			sqlite3_open(); 
			打开或者创建一个sqlite3数据库 返回一个数据库的连接对象 (sqlite3 *2.操作数据库 
			
			sqlite3_prepare_*() //准备好一个SQL语句	
			
			sqlite3_bind_*() //函数族 绑定参数 
			
			sqlite3_step() ;//执行准备好的SQL语句
			
			sqlite3_column() ;//输出查询到的数据库的数据 
			
			sqlite3_finalize() ; //是否资源 销毁SQL语句对象 
			
			sqlite3_exec() ; 
			
		3. 关闭数据库 
		
			sqlite3_close() ;//关闭数据库连接对象

具体的API函数解析:

	(1)打开一个sqlite3的数据库连接对象 
		
		SQLITE_API int sqlite3_open
		(
		  const char *filename,   //你要打开的数据库的路径名
		  sqlite3 **ppDb         //二级指针 用来保存打开的数据库连接对象
		);
					
		sqlite3* 用来表示你打开的那个sqlite3的数据库文件(test.db) 后续对数据库的所有操作都是通过该文件。 

		返回值: 
				成功返回SQLITE_OK 
				失败返回其他值
				
				
	(2)关闭数据库连接对象  
	
		SQLITE_API int sqlite3_close(sqlite3*); 
		
		参数表示你要关闭哪个打开的数据库连接对象 
		
	
	(3)准备好一个SQL语句对象 
	
		使用sqlite3_stmt这个结构来描述一个准备好的SQL语句对象
		我们的应用都是通过SQL语句对象去发送SQL指令 
		
			SQLITE_API int sqlite3_prepare_v2
			(
			  sqlite3 *db,            /* Database handle */
			  const char *zSql,       /* SQL statement, UTF-8 encoded */
			  int nByte,              /* Maximum length of zSql in bytes. */
			  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
			  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
			);
						
			函数功能: 把一个字符串类型的SQL语句命令转换成可以使用的语句对象类型sqlite3_stmt
			
			参数列表: 
					db: 数据库连接对象  表示你得语句将要作用在哪一个数据库上 
					
					zSql: 你要执行的SQL语句的字符串格式  
						
					nByte:SQL语句的长度 或者是 你要编译到zSql字符串的哪一个位置 		
						   原始的数据库字符串zSql有可能包含多条SQL语句
						   
							>0  编译到zSql指向的sql语句的前nBytes个字节 
							
							<0  编译到zSql指向的sql语句的第一个'\0'为止 
							
							=0  什么都不编译
		
					ppStmt:二级指针 用来保存编译好后的SQL语句对象  		
		
					pzTail :指向原始SQL语句字符串zSql中未使用的部分 一般给0 或者NULL
		
			返回值: 
					成功返回SQLITE_OK 
					失败返回其他值
		
		
	(4) 执行准备好的SQL语句对象 

			SQLITE_API int sqlite3_step(sqlite3_stmt*);	
			
			成功返回SOLITE_DONE 
			失败返回其他值
		
			参数就是你要执行的SQL语句对象
		
		
	(5) 释放语句对象资源  

			SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);

一般情况下 先编译sql语句再执行sql语句 但是编译的过程需要销毁资源 如果需要插入1000条记录
需要编译1000次 然后执行1000次 --》效率太低
那么我们可以在使用类似的sql语句时,先编译一次语句,只改变参数/变量,执行1000次

参数怎么表示?

"insert into class1 values(参数名, 参数名, 参数名, 参数名);"
		:xxx  就是一个sql语句中的参数  xxx一般就是一个变量 
		@xxx 
		$xxx 
		
		int num;
		char name[256]={
    
    0};
		float score;
		int tel;
		char sql[]="insert into class1 values(:num , :name, :score, :tel);" //占位符
		对该sql语句只需要编译一次即可 每次运行之前都需要对四个参数进行绑定(为他赋值)

绑定参数相关函数

		(1)获取参数在原始sql语句中的下标/索引 
				
				SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt* pstmt, const char *zName);
		
					参数: 
							pstmt: sql语句对象的指针 
							
							zname: 参数名 
						
					返回值: 
							返回该参数在sql语句中的下标  
							如果没有该参数就返回0

		(2)给该参数绑定值(不同的参数根据他的类型调用下面不同的函数进行绑定)
			
				SQLITE_API int sqlite3_bind_int(sqlite3_stmt* pstmt, int index , int value);
				参数: 
						第一个参数: sql语句对象的指针 
						第二个参数: 该参数在sql语句对象中的索引/下标 
						第三个参数: 要给参数绑定的值
						
				
				SQLITE_API int sqlite3_bind_text(sqlite3_stmt*pstmt,int index,const char* value,int len,void(*func)(void*));
			
				参数: 
						第一个参数: sql语句对象的指针 
						第二个参数: 该参数该sql语句对象中的下标
						第三个参数: 要给这个参数绑定的那一个字符串的首地址 
						第四个参数: 第三个参数表示的字符串的长度 防止越界 
						第五个参数: 函数指针 指向一个函数 该函数用于释放values指向的字符串的空间 如果不需要就填NULL 

代码实现:

#include <stdio.h>
#include <string.h> 
#include <sqlite3.h>

//编译的时候需要加上 -lsqlite3
int main(int argc,char * argv[])
{
    
    
    //创建一个数据库连接对象的指针
    sqlite3 *pdb;

    //打开一个数据库连接对象
    int ret=sqlite3_open(argv[1],&pdb);
    if(ret!=SQLITE_OK)
    {
    
    
        perror("sqlit3_open error\n");
        return -1;
    }

    //创建一个sql语句对象的指针
    sqlite3_stmt * pstmt;
    const char * sql = "insert into student values(@id,@name,@score);";

     ret = sqlite3_prepare_v2(pdb,sql,-1,&pstmt,NULL);
    if(ret != SQLITE_OK)
    {
    
    
        perror("sqlite3_prepare_v2 error");
        sqlite3_close(pdb);
        return -1;
    }

    while (1)
    {
    
    
        int id;
        char name[256]={
    
    0};
        float score;

        scanf("%d%s%f",&id,name,&score);
        getchar();
		//绑定参数/变量 
        int index[3];
        index[0]=sqlite3_bind_parameter_index(pstmt,"@id");
        index[1]=sqlite3_bind_parameter_index(pstmt,"@name");
        index[2]=sqlite3_bind_parameter_index(pstmt,"@score");

        sqlite3_bind_int(pstmt,index[0],id);
        sqlite3_bind_text(pstmt,index[1],name,strlen(name),NULL);
        sqlite3_bind_int(pstmt,index[2],score);

        ret=sqlite3_step(pstmt);
        if(ret!=SQLITE_DONE)
        {
    
    
            perror("sqlite3_step error\n");
            return -1;
        }

        sqlite3_reset(pstmt);
        
    }
    sqlite3_finalize(pstmt);

    sqlite3_close(pdb);
    
}

一步查询执行操作函数 sqlite3_exec

sqlite3_exec内部封装了三个函数[sqlite3_prepare_v2 sqlite3_step sqlite3_finalize]
	他是一个万能函数 它可以让应用程序执行多个SQL语句 而不需要使用sqlite3中其他的大量的接口函数 
	
	SQLITE_API int sqlite3_exec
	(
	  sqlite3*,                                  /* An open database */
	  const char *sql,                           /* SQL to be evaluated */
	  int (*callback)(void*,int,char**,char**),  /* Callback function */
	  void *,                                    /* 1st argument to callback */
	  char **errmsg                              /* Error msg written here */
	);
		
	函数功能: 指定一条指定的sql语句 
	
	参数列表: 
			 第一个参数: 一个打开的数据库连接对象
	         第二个参数: 是你要准备执行的sql语句 
	         第三个参数: 回调函数: 当执行sqlite3_exec后 有可能会执行此回调函数 
						  填NULL 就表示你不需要执行回调函数
						  什么时候需要回调函数? 当你做SELECT时 就需要回调函数。 
						  那么SELECT时候的回调函数是干嘛? 就是把你select查询的结果输出出来 
						  select产生多少条结果 回调函数就会执行多少次。
						  
			 第四个参数: 你需要传递到回调函数中的信息 类似于pthread-create中给线程函数传参 
						  如果你不需要传递任何消息 就填NULL 如果多个消息 请自行封装成结构体
						  
			 第五个参数: 二级指针 保存一级指针的地址  保存执行的出错的信息  
						  一旦出错 则将错误信息写入[sqlite3_malloc]分配的空间中 并且让第5个参数保存分配的空间的地址 
						  为了避免内存泄露 应用程序在处理完错误信息之后 需要调用sqlite3_free释放掉第五个参数指向的内容空间

使用sqlite3_exec函数实现数据库查询功能

//编译的时候需要加上 -lsqlite3
#include <stdio.h>
#include <string.h> 
#include <sqlite3.h>

int flag=0;

int callback(void *arg,int ncols,char *col_value[],char*col_name[])
{
    
    
    int i;
    if(flag==0)
    {
    
    
        for(i=0;i<ncols;i++)
        {
    
    
            printf("%s\t\t",col_name[i]);
        }
        flag=1;
    }
    printf("\n");

    for(i=0;i<ncols;i++)
    {
    
    
        printf("%s\t\t",col_value[i]);
    }
    putchar('\n');
    return 0;
}

int main(int argc,char * argv[])
{
    
    
    //创建一个连接对象
    sqlite3 * pbd;

    //打开连接对象
    int ret=sqlite3_open(argv[1],&pbd);
    if(ret!=SQLITE_OK)
    {
    
    
        perror("sqlite3_open error\n");
        return -1;
    }
    
    const char * sql="select * from student;";
    
    char * errmsg=NULL;
    ret=sqlite3_exec(pbd,sql,callback,NULL,&errmsg);
    if(ret!=SQLITE_OK)
    {
    
    
        printf("error:%s\n",errmsg);
        return -1;
    }
    //关闭连接
    sqlite3_close(pbd);
    return 0;
}
回调函数详解: 
		
		int (*callback)(void* arg,int x,char** a,char** b)
		
		第一个参数: 是一个指针 可以传入用户自己的数据
	
		第二个参数: 是执行select语句后 查询到的结果的列数 
		
		第三个参数: 是一个指向字符串的指针数据 就是结果数据每一列的信息 
		
		第四个参数: 是一个指向字符串的指针数据 就是结果数据每一列的表头的信息 
		
		select产生多少条结果 回调函数就会被调用多少次

猜你喜欢

转载自blog.csdn.net/weixin_46836491/article/details/127141129