【基于sqlite3库源码实现增删改查 linux_C语言】

utl_database_open

  1. 创建并打卡数据库DB文件
	pthread_mutex_lock(&db->mutex);
	int rc;
	if(db->bOpen == 1)
	{
		printf("%s already open\n", db->path);
		pthread_mutex_unlock(&db->mutex);
		return UTL_DB_ERROR_IN_USE;
	}

	/* Open database */
	rc = sqlite3_open(db->path, &db->database);
	/*
	功能	打开或创建数据库文件,返回句柄
	参数	const char* dbname :数据库文件名, 为NULL时在RAM创建内存数据库
	sqlite3* *db :数据库指针句柄
	返回值	成功 :SQLITE_OK
	失败 :ERROR_msg
	*/
	if(rc)
	{
		printf("Can't open database: %s\n", sqlite3_errmsg(db->database));
		pthread_mutex_unlock(&db->mutex);
		return UTL_DB_ERROR_EXEC_FAILED;
	}
	else
	{
		printf("Open database successfully\n");
	}
	db->bOpen = 1;
	pthread_mutex_unlock(&db->mutex);

	return UTL_DB_OK;

_build_studentdet_db

  1. 创建数据库table
  2. 注意事项:存大数据时可用UTL_DB_DATA_TYPE_BLOB变量(具体看注释)
char sql[512] = {0};
//detected table
memset(&studentTable, 0, sizeof(studentTable));
strcpy(studentTable.tableName, "studentTable");
studentTable.pCallback = student_dct_callback;
studentTable.bExist = 0;
studentTable.columnCnt = StudentDCT_TABLE_COLUMN_MAX;
studentTable.recordCnt = 0;
studentTable.recordList = NULL;
//下面开始对表添加信息选项
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_ID].columnName, "ID");
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_ID].columnAttr, "PRIMARY KEY AUTOINCREMENT");
//PRIMARY KEY 主键,不可为空,不可重复
//AUTOINCREMENT意味着阻止SQLite回收主键值,保证主键严格按顺序增长
studentTable.column[StudentDCT_TABLE_COLUMN_ID].columnType = UTL_DB_DATA_TYPE_INTEGER;
//变量类型
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_STUDENTNAME].columnName, "studentName");
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_STUDENTNAME].columnAttr, "NOT NULL");
//不可为空
studentTable.column[StudentDCT_TABLE_COLUMN_STUDENTNAME].columnType = UTL_DB_DATA_TYPE_VARCHAR_255;
//变量类型
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_AGE].columnName, "age");
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_AGE].columnAttr, "NOT NULL");
//不可为空
studentTable.column[StudentDCT_TABLE_COLUMN_AGE].columnType = UTL_DB_DATA_TYPE_TINYINT;
//变量类型
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_GENDER].columnName, "gender");
strcpy(studentTable.column[StudentDCT_TABLE_COLUMN_GENDER].columnAttr, "NOT NULL");
studentTable.column[StudentDCT_TABLE_COLUMN_GENDER].columnType = UTL_DB_DATA_TYPE_CHARACTER_20;

/*
注意当需要存大数据时用这种变量类型UTL_DB_DATA_TYPE_BLOB
strcpy(faceDctTable.column[FACEDCT_TABLE_COLUMN_FACEVECTOR].columnName, "faceVector");
strcpy(faceDctTable.column[FACEDCT_TABLE_COLUMN_FACEVECTOR].columnAttr, "NOT NULL");
faceDctTable.column[FACEDCT_TABLE_COLUMN_FACEVECTOR].columnType = UTL_DB_DATA_TYPE_BLOB;
*/

if(studentTable.bExist == 0 && studentDB.bOpen == 1)
{
	printf("utl_database_create_table studentTable\n");
	//utl_database_check_table(&studentDB, &studentTable);
	utl_database_create_table(&studentDB, &studentTable);

	sprintf(sql, "CREATE INDEX if not exists idIndex ON %s(%s,%s,%s,%s);",
		studentTable.tableName,
		studentTable.column[StudentDCT_TABLE_COLUMN_ID].columnName,
		studentTable.column[StudentDCT_TABLE_COLUMN_STUDENTNAME].columnName,
		studentTable.column[StudentDCT_TABLE_COLUMN_AGE].columnName,
		studentTable.column[StudentDCT_TABLE_COLUMN_GENDER].columnName);
	utl_database_exec(&studentDB, &studentTable, sql);
	/*创建索引
	未创建索引从60万条数据中搜索出满足条件的40条数据用时大约为1300 ms
	使用组合索引从60万条数据搜索出满足条件的40条数据用时大约为20 ms
	但是给表创建索引以后会影响存储数据的速度
	未创建组合索引的原始表,循环存储20万条数据,大概用时15
	而创建索引以后,存储20万条数据用时为25
	可以看出在表中创建索引有利也有弊,需要根据具体情况进行选择是否创建索引
	具体参考:https://blog.csdn.net/u010312436/article/details/51848671
	*/

}

sprintf(sql, "SELECT COUNT(0) FROM %s;", studentTable.tableName);
utl_database_exec(&studentDB, &studentTable, sql);

_insert_studentdct_record

  1. 插入对象至数据库
  2. 存大数据要用到sqlite3_bind_blob函数(具体看注释)
if(!studentDB.bOpen)
	{
		printf("database is not open\n");
		return -1;
	}

	// ID | studentName | age | gender| 
	sprintf(sql, "INSERT INTO %s(%s,%s,%s) VALUES('%s', %d, '%s');", studentTable.tableName,
				studentTable.column[StudentDCT_TABLE_COLUMN_STUDENTNAME].columnName, studentTable.column[StudentDCT_TABLE_COLUMN_AGE].columnName,
				studentTable.column[StudentDCT_TABLE_COLUMN_GENDER].columnName,
				studentName,age,gender);
	//printf("sql:%s\n", sql);
	result = sqlite3_prepare_v2(studentDB.database, sql, strlen(sql), &stmt, NULL);
	/*
	功能:将SQL语句文本转化为申明对象,返回对象指针
	参数描述:
	sqlite3* db                    :数据库文件句柄
	const char* zSQL        :SQL语句
	int nByte                       :SQL字节数,< 0表示取到第一个\0终止符
	sqlite3_stmt* *ppStmt :预编译语句句柄
	const char* *pzTail       :指向SQL语句中未使用的部分
	*/
	if (result != SQLITE_OK)
	{
		printf("%s: sqlite3_prepare_v2 failed for %d\n", __FUNCTION__, result);
		return -1;
	}

    //sqlite3_bind_blob(stmt,1, vector, vectorSize, NULL);	//1代表第一个?  当需要存大数据时用
	// 参数1:sqlte_stmt*
	// 参数2:“?”的索引,从1开始
	// 参数3:二进制数据的起始指针
	// 参数4:二进制数据的长度
	// 参数5:析构回调函数,一般默认为空
	result = sqlite3_step(stmt);                        //将数据写入数据库中
	/*
	功能:执行预编译后的SQL对象
	参数:
	sqlite3_stmt *pStmt :预编译语句句柄
	返回值:
	成功: SQLITE_OK |  SQLITE_DONE
	阻塞: SQLITE_BUSY
	运行错误:SQLITE_ERROR
	查询成功:SQLITE_ROW
	*/
	if (result == SQLITE_DONE)
	{
	    //printf("insert %s to %s ok\n", fileName, faceDctTable.tableName);
		ret = 0;
	}
	else
	{
	    printf("insert  to %s failed for %d\n", studentTable.tableName, result);
	}

	sqlite3_finalize(stmt);
	/*
	功能:销毁预编译对象
	一般配合sqlite3_prepare_v2使用
	*/


	insertID = sqlite3_last_insert_rowid(studentDB.database);
	//功能:返回最近的插入操作的主键值

data_proc_entry

  1. 遍历数据库
    ret = _select_record_start(sql, &stmt);
if(ret == 0)
{
	while(ret == 0)
	{
		ret = _select_student_record_get_row(stmt, &ID, studentName, &age, gender);
		if(ret == 0)
		{
			printf("studentName=%s,age=%d,gender=%s\n", studentName,age,gender);
		}
	}
	_select_record_finalize(stmt);
}

数据库源码下载点这~~(有sqlite3压缩包、数据库操作源码)

编译静态库命令:
./configure --enable-static --prefix=/home/lxr/database/ CC=“gcc -m32”
$ make && make install

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I&You

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值