c语言下的通用数据库接口(之sqlite消化,模拟c#,java的反射)
2014-05-13 20:48
627 查看
在java/C#中都有类的反射,而C下是不存在的。
java/C#中可以把表设计成类,而C下只能设计成结构体形式。
在java中有hibernate来操作数据库,但是在C下面怎么设计好呢?
现在,我想出了一个点子,以下使用sqlite
先创建一个结构体,表示一张数据库表的结构。
typedef struct User {
int id;
char *name;
char *password;
} User;
创建表的语句:
CREATE TABLE 'User' ('id' INTEGER PRIMARY KEY AUTOINCREMENT,'name' varchar(100),'password' varchar(100),'workNumber' varchar(100))
数据库的操作有select ,insert ,delete ,update,而insert,delete,update都是让数据库去操作,但select是有返回数据的。
所以,对于insert,delete,update我采用
[cpp]
view plaincopyprint?
int sql_exec(char *format,...) {
char sql[1024];
va_list args;
char *errmsg=NULL;
int rc;
va_start(args, format);
vsprintf(sql,format,args);
va_end(args);
rc=sqlite3_exec(g_mdb,sql,NULL,NULL,&errmsg);
if(rc!=SQLITE_OK){
printf("%s,%s,%s\n",__FUNCTION__,errmsg,sql);
sqlite3_free(errmsg);
return SQLITE_ERROR;
}
return SQLITE_OK;
}
[cpp]
view plaincopyprint?
#define SELECT_(_columns,_table,_where) "select "_columns" from "#_table" WHERE "##_where
#define INSERT_INTO_(_table,_columns,_values) "insert into "#_table" ("_columns") values ("_values")"
#define UPDATE_(_table,_set,_where) "UPDATE "#_table" SET "_set" WHERE "##_where
#define DELETE_FROM(_table,_where) "DELETE FROM "#_table" WHERE "##_where
#define insert_table(format,...) sql_exec(format,__VA_ARGS__)
#define update_table(format,...) sql_exec(format,__VA_ARGS__)
#define delete_table(format,...) sql_exec(format,__VA_ARGS__)
最终调用(insert):
insert_table(INSERT_INTO_(User,"id,name,password","%d,'%s','%s'"),us.id,us.name,us.password);
而对于select ,返回的是一个列表数据:
[cpp]
view plaincopyprint?
struct select_list {
void *value;
struct select_list *next;
};
typedef void select_value_free(void *value);
struct select_list *select_list_new(){
struct select_list *h=(struct select_list*)malloc(sizeof(struct select_list));
memset(h,0,sizeof(struct select_list));
return h;
}
4000
void select_list_free(struct select_list *list,select_value_free value_free){
struct select_list *next;
if(list==NULL){
return ;
}
if(list->value){
value_free(list->value);
}
if(list) {
next=list->next;
free(list);
}
select_list_free(next,value_free);
}
select_list *home;
select_table((void**)&home,SELECT_("id",User,"name='%s' and password='%s'"),us.name,us.password);
if(home!=NULL){
for(next=home;next;next=next->next){
User *item=((User*)next->value);
printf("%d,%s,%s\n",item->id,item->name,item->password);
}
select_list_free(home,user_free);
}
//关键是在select_table
通过sqlite3_prepare查找出sqlite3_stmt,遍历stmt,取出当前操作的表名,与定义的结构体user比较,如果等于,则创建User,把查询的数据给User,再把这个User加入链表value就可以了。
[cpp]
view plaincopyprint?
void *select_value_item_user(sqlite3_stmt *stmt){
int i;
int count;
User *item=(User*)malloc(sizeof(User));
memset(item,0,sizeof(User));
count=sqlite3_column_count(stmt);
for(i=0;i<count;i++){
if(0==strcmp(sqlite3_column_name(stmt,i),"id")){
item->id=sqlite3_column_int(stmt,i);
}
if(0==strcmp(sqlite3_column_name(stmt,i),"name")){
char_cpy(&item->name,(const
char *)sqlite3_column_text(stmt,i));
}
}
return item;
}
[cpp]
view plaincopyprint?
int select_table(void **result,char *pszFormat,...) {
sqlite3_stmt * stmt=NULL;
const char *table_name=NULL;
int count=0;
char sql[1024];
va_list args;
struct select_list *next=NULL;
struct select_list *home=NULL;
va_start(args, pszFormat);
vsprintf(sql,pszFormat,args);
va_end(args);
printf("%s\n",sql);
*result=NULL;
if(sqlite3_prepare(g_mdb,sql,-1,&stmt,NULL)==SQLITE_OK){
while( sqlite3_step(stmt)==SQLITE_ROW){
/************************************************************************/
/* */
/************************************************************************/
table_name=sqlite3_column_table_name(stmt,0);
if(table_name) {
if(strcmp(table_name,STR(User))==0){
//添加到list就可以了
next=select_list_new();
next->value=select_value_item_user(stmt);
next->next=NULL;
if(*result==NULL){
*result=next;
} else {
home->next=next;
}
home=next;
}
} else {
{
int column_count=sqlite3_column_count(stmt);
int i=0;
for(i=0;i<column_count;i++){
if(sqlite3_column_type(stmt,i)==SQLITE_INTEGER) {
//printf("%s,%d\n",sqlite3_column_name(stmt,i),sqlite3_column_int(stmt,i));
*result=(void*)sqlite3_column_int(stmt,i);
}
}
}
}
count++;
}
} else {
count=-1;
//save errmsg...
}
sqlite3_finalize(stmt);
return count;
}
这只是针对单一表的查询操作,可以加入count(*)功能。
int count;
select_table((void**)&count,SELECT_("count(*)",User,"1=1"));
对于其它的表,你只要创建一个相当于User的结构体就可以了,再添加一个 select_value_item_user 功能数据库值与此绑定功能的函数,再在select中选择这个函数就可,
当然,可以采用C 下的 HashMap 来把 表名(结构体名)与 绑定函数 做一个映像,这样方便一点,但我的表只有几个所以就不用做了
java/C#中可以把表设计成类,而C下只能设计成结构体形式。
在java中有hibernate来操作数据库,但是在C下面怎么设计好呢?
现在,我想出了一个点子,以下使用sqlite
先创建一个结构体,表示一张数据库表的结构。
typedef struct User {
int id;
char *name;
char *password;
} User;
创建表的语句:
CREATE TABLE 'User' ('id' INTEGER PRIMARY KEY AUTOINCREMENT,'name' varchar(100),'password' varchar(100),'workNumber' varchar(100))
数据库的操作有select ,insert ,delete ,update,而insert,delete,update都是让数据库去操作,但select是有返回数据的。
所以,对于insert,delete,update我采用
[cpp]
view plaincopyprint?
int sql_exec(char *format,...) {
char sql[1024];
va_list args;
char *errmsg=NULL;
int rc;
va_start(args, format);
vsprintf(sql,format,args);
va_end(args);
rc=sqlite3_exec(g_mdb,sql,NULL,NULL,&errmsg);
if(rc!=SQLITE_OK){
printf("%s,%s,%s\n",__FUNCTION__,errmsg,sql);
sqlite3_free(errmsg);
return SQLITE_ERROR;
}
return SQLITE_OK;
}
int sql_exec(char *format,...) { char sql[1024]; va_list args; char *errmsg=NULL; int rc; va_start(args, format); vsprintf(sql,format,args); va_end(args); rc=sqlite3_exec(g_mdb,sql,NULL,NULL,&errmsg); if(rc!=SQLITE_OK){ printf("%s,%s,%s\n",__FUNCTION__,errmsg,sql); sqlite3_free(errmsg); return SQLITE_ERROR; } return SQLITE_OK; }对数据库的操作我定义成
[cpp]
view plaincopyprint?
#define SELECT_(_columns,_table,_where) "select "_columns" from "#_table" WHERE "##_where
#define INSERT_INTO_(_table,_columns,_values) "insert into "#_table" ("_columns") values ("_values")"
#define UPDATE_(_table,_set,_where) "UPDATE "#_table" SET "_set" WHERE "##_where
#define DELETE_FROM(_table,_where) "DELETE FROM "#_table" WHERE "##_where
#define SELECT_(_columns,_table,_where) "select "_columns" from "#_table" WHERE "##_where #define INSERT_INTO_(_table,_columns,_values) "insert into "#_table" ("_columns") values ("_values")" #define UPDATE_(_table,_set,_where) "UPDATE "#_table" SET "_set" WHERE "##_where #define DELETE_FROM(_table,_where) "DELETE FROM "#_table" WHERE "##_where
#define insert_table(format,...) sql_exec(format,__VA_ARGS__)
#define update_table(format,...) sql_exec(format,__VA_ARGS__)
#define delete_table(format,...) sql_exec(format,__VA_ARGS__)
最终调用(insert):
insert_table(INSERT_INTO_(User,"id,name,password","%d,'%s','%s'"),us.id,us.name,us.password);
而对于select ,返回的是一个列表数据:
[cpp]
view plaincopyprint?
struct select_list {
void *value;
struct select_list *next;
};
typedef void select_value_free(void *value);
struct select_list *select_list_new(){
struct select_list *h=(struct select_list*)malloc(sizeof(struct select_list));
memset(h,0,sizeof(struct select_list));
return h;
}
4000
void select_list_free(struct select_list *list,select_value_free value_free){
struct select_list *next;
if(list==NULL){
return ;
}
if(list->value){
value_free(list->value);
}
if(list) {
next=list->next;
free(list);
}
select_list_free(next,value_free);
}
struct select_list { void *value; struct select_list *next; }; typedef void select_value_free(void *value); struct select_list *select_list_new(){ struct select_list *h=(struct select_list*)malloc(sizeof(struct select_list)); memset(h,0,sizeof(struct select_list)); return h; } void select_list_free(struct select_list *list,select_value_free value_free){ struct select_list *next; if(list==NULL){ return ; } if(list->value){ value_free(list->value); } if(list) { next=list->next; free(list); } select_list_free(next,value_free); }
select_list *home;
select_table((void**)&home,SELECT_("id",User,"name='%s' and password='%s'"),us.name,us.password);
if(home!=NULL){
for(next=home;next;next=next->next){
User *item=((User*)next->value);
printf("%d,%s,%s\n",item->id,item->name,item->password);
}
select_list_free(home,user_free);
}
//关键是在select_table
通过sqlite3_prepare查找出sqlite3_stmt,遍历stmt,取出当前操作的表名,与定义的结构体user比较,如果等于,则创建User,把查询的数据给User,再把这个User加入链表value就可以了。
[cpp]
view plaincopyprint?
void *select_value_item_user(sqlite3_stmt *stmt){
int i;
int count;
User *item=(User*)malloc(sizeof(User));
memset(item,0,sizeof(User));
count=sqlite3_column_count(stmt);
for(i=0;i<count;i++){
if(0==strcmp(sqlite3_column_name(stmt,i),"id")){
item->id=sqlite3_column_int(stmt,i);
}
if(0==strcmp(sqlite3_column_name(stmt,i),"name")){
char_cpy(&item->name,(const
char *)sqlite3_column_text(stmt,i));
}
}
return item;
}
void *select_value_item_user(sqlite3_stmt *stmt){ int i; int count; User *item=(User*)malloc(sizeof(User)); memset(item,0,sizeof(User)); count=sqlite3_column_count(stmt); for(i=0;i<count;i++){ if(0==strcmp(sqlite3_column_name(stmt,i),"id")){ item->id=sqlite3_column_int(stmt,i); } if(0==strcmp(sqlite3_column_name(stmt,i),"name")){ char_cpy(&item->name,(const char *)sqlite3_column_text(stmt,i)); } } return item; }
[cpp]
view plaincopyprint?
int select_table(void **result,char *pszFormat,...) {
sqlite3_stmt * stmt=NULL;
const char *table_name=NULL;
int count=0;
char sql[1024];
va_list args;
struct select_list *next=NULL;
struct select_list *home=NULL;
va_start(args, pszFormat);
vsprintf(sql,pszFormat,args);
va_end(args);
printf("%s\n",sql);
*result=NULL;
if(sqlite3_prepare(g_mdb,sql,-1,&stmt,NULL)==SQLITE_OK){
while( sqlite3_step(stmt)==SQLITE_ROW){
/************************************************************************/
/* */
/************************************************************************/
table_name=sqlite3_column_table_name(stmt,0);
if(table_name) {
if(strcmp(table_name,STR(User))==0){
//添加到list就可以了
next=select_list_new();
next->value=select_value_item_user(stmt);
next->next=NULL;
if(*result==NULL){
*result=next;
} else {
home->next=next;
}
home=next;
}
} else {
{
int column_count=sqlite3_column_count(stmt);
int i=0;
for(i=0;i<column_count;i++){
if(sqlite3_column_type(stmt,i)==SQLITE_INTEGER) {
//printf("%s,%d\n",sqlite3_column_name(stmt,i),sqlite3_column_int(stmt,i));
*result=(void*)sqlite3_column_int(stmt,i);
}
}
}
}
count++;
}
} else {
count=-1;
//save errmsg...
}
sqlite3_finalize(stmt);
return count;
}
int select_table(void **result,char *pszFormat,...) { sqlite3_stmt * stmt=NULL; const char *table_name=NULL; int count=0; char sql[1024]; va_list args; struct select_list *next=NULL; struct select_list *home=NULL; va_start(args, pszFormat); vsprintf(sql,pszFormat,args); va_end(args); printf("%s\n",sql); *result=NULL; if(sqlite3_prepare(g_mdb,sql,-1,&stmt,NULL)==SQLITE_OK){ while( sqlite3_step(stmt)==SQLITE_ROW){ /************************************************************************/ /* */ /************************************************************************/ table_name=sqlite3_column_table_name(stmt,0); if(table_name) { if(strcmp(table_name,STR(User))==0){ //添加到list就可以了 next=select_list_new(); next->value=select_value_item_user(stmt); next->next=NULL; if(*result==NULL){ *result=next; } else { home->next=next; } home=next; } } else { { int column_count=sqlite3_column_count(stmt); int i=0; for(i=0;i<column_count;i++){ if(sqlite3_column_type(stmt,i)==SQLITE_INTEGER) { //printf("%s,%d\n",sqlite3_column_name(stmt,i),sqlite3_column_int(stmt,i)); *result=(void*)sqlite3_column_int(stmt,i); } } } } count++; } } else { count=-1; //save errmsg... } sqlite3_finalize(stmt); return count; }
这只是针对单一表的查询操作,可以加入count(*)功能。
int count;
select_table((void**)&count,SELECT_("count(*)",User,"1=1"));
对于其它的表,你只要创建一个相当于User的结构体就可以了,再添加一个 select_value_item_user 功能数据库值与此绑定功能的函数,再在select中选择这个函数就可,
当然,可以采用C 下的 HashMap 来把 表名(结构体名)与 绑定函数 做一个映像,这样方便一点,但我的表只有几个所以就不用做了
相关文章推荐
- c语言下的通用数据库接口(之sqlite消化,模拟c#,java的反射)
- c语言下的通用数据库接口(之sqlite消化,模拟c#,java的反射)
- 安卓Android单表通用数据库、万能数据库的设计,(sqlite,java反射,泛型),使用非常方便
- sqlite3数据库c语言常用接口应用实例
- 利用java反射创建通用的数据库查询方法
- C语言模拟java、c#使用try catch
- java中dao层的通用层,通过反射机制,操作数据库的增删改,适用的范围是不包含属性类
- 一个通用数据库操作组件DBUtil(c#)、支持SqlServer、Oracle、Mysql、Access、SQLITE
- 【Java学习】使用泛型和反射 创建通用的数据库查询方法
- 用Java模拟网卡、声卡继承PIC接口,实现网卡、声卡能与主板连接
- 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测
- Effective Java 学习笔记(第53条:接口优先于反射机制)
- C# 利用SQLite对.DB和.logdb加密和解密和SQLite创建数据库
- 使用反射机制将纯Java对象放入数据库中
- C#利用反射+特性实现简单的实体映射数据库操作类
- sqlite3数据库C语言简单操作基础之数据的增删改(二)
- 用c语言动态操作sqlite3数据库v1.0
- .Net/C#: 利用反射编写通用的 rss 2.0 的 reader
- java 反射写的 通用DAO 类
- sqlite学习笔记7:C语言中使用sqlite之打开数据库