您的位置:首页 > 编程语言 > C语言/C++

libzdb c语言的数据库连接池支持库 源码分析

2014-03-30 11:27 363 查看

libzdb c语言的数据库连接池支持库 源码分析

Standard
整个程序可以支持各种数据库,是通过“接口实现的”。

而C语言并没有接口的概念,它是如何实现的呢?

在ConnectionDelegate.h文件里定义了一个结构体,这个结构体是保存一个数据库连接的所有信息和操作方法,这里的方法都是使用函数指针来定义的。

typedef struct Cop_T {
const char *name;
// Event handler class methods
void (*onstop)(void);
// Methods
T (*new)(URL_T url, char **error);
void (*free)(T *C);
void (*setQueryTimeout)(T C, int ms);
void (*setMaxRows)(T C, int max);
int (*ping)(T C);
int (*beginTransaction)(T C);
int (*commit)(T C);
int (*rollback)(T C);
long long int (*lastRowId)(T C);
long long int (*rowsChanged)(T C);
int (*execute)(T C, const char *sql, va_list ap);
ResultSet_T (*executeQuery)(T C, const char *sql, va_list ap);
PreparedStatement_T (*prepareStatement)(T C, const char *sql, va_list ap);
const char *(*getLastError)(T C);
} *Cop_T;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

typedef
struct Cop_T
{

const
char *name;
// Event handler class methods

void
(*onstop)(void);
// Methods

T
(*new)(URL_T
url,
char **error);

void
(*free)(T
*C);

void
(*setQueryTimeout)(T
C,
int ms);
void
(*setMaxRows)(T
C,
int max);

int
(*ping)(T
C);
int
(*beginTransaction)(T
C);

int
(*commit)(T
C);
int
(*rollback)(T
C);

long
long int
(*lastRowId)(T
C);

long
long int
(*rowsChanged)(T
C);

int
(*execute)(T
C,
const char
*sql,
va_list ap);
ResultSet_T
(*executeQuery)(T
C,
const char
*sql,
va_list ap);

PreparedStatement_T
(*prepareStatement)(T
C,
const char
*sql,
va_list ap);
const
char *(*getLastError)(T
C);

} *Cop_T;

而在每种数据库实现时,使用这种结构体定义时,分别赋予了每种数据库对应的函数操作方法,这样就实现了接口的定义。

const struct Cop_T mysqlcops = {
"mysql",
onstop,
MysqlConnection_new,
MysqlConnection_free,
MysqlConnection_setQueryTimeout,
MysqlConnection_setMaxRows,
MysqlConnection_ping,
MysqlConnection_beginTransaction,
MysqlConnection_commit,
MysqlConnection_rollback,
MysqlConnection_lastRowId,
MysqlConnection_rowsChanged,
MysqlConnection_execute,
MysqlConnection_executeQuery,
MysqlConnection_prepareStatement,
MysqlConnection_getLastError
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

const
struct Cop_T
mysqlcops =
{

"mysql",
onstop,

MysqlConnection_new,
MysqlConnection_free,

MysqlConnection_setQueryTimeout,
MysqlConnection_setMaxRows,

MysqlConnection_ping,

MysqlConnection_beginTransaction,

MysqlConnection_commit,

MysqlConnection_rollback,

MysqlConnection_lastRowId,
MysqlConnection_rowsChanged,

MysqlConnection_execute,
MysqlConnection_executeQuery,

MysqlConnection_prepareStatement,
MysqlConnection_getLastError

};

结构体中虽然存储的是数据,但是这个数据如果是指针类型,那么他的作用就不仅仅能够赋值了。这里的“接口”,实质就是对函数指针的灵活运用。

使用方法

//
首先初始化数据库连接池
URL_T url =
URL_new("mysql://localhost/test?user=root&password=swordfish");
//设置连接url
ConnectionPool_T pool = ConnectionPool_new(url); //新建一个连接池结构体,并分配内存
ConnectionPool_start(pool); //初始化连接池(建立连接),调用fillpool
//...
Connection_T con = ConnectionPool_getConnection(pool); //从连接池获取一个连接
ResultSet_T result = Connection_executeQuery(con, "select id, name,
image from employee where salary>%d", anumber); //使用此连接执行查询数据操作
while (ResultSet_next(result))
{
int id = ResultSet_getInt(result, 1);
const char *name = ResultSet_getString(result, 2);
int blobSize;
const void *image = ResultSet_getBlob(result, 3, &blobSize);
//...
}
Connection_close(con); //连接使用完关闭连接
//...
ConnectionPool_free(&pool); //关闭连接池
URL_free(&url);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

//首先初始化数据库连接池

URL_T url
= URL_new("mysql://localhost/test?user=root&password=swordfish");
//设置连接url
ConnectionPool_T
pool =
ConnectionPool_new(url);
//新建一个连接池结构体,并分配内存

ConnectionPool_start(pool);
//初始化连接池(建立连接),调用fillpool
//...

Connection_T con
= ConnectionPool_getConnection(pool);
//从连接池获取一个连接
ResultSet_T
result =
Connection_executeQuery(con,
"select id, name, image from employee where salary>%d",
anumber);
//使用此连接执行查询数据操作

while (ResultSet_next(result))
{

int
id =
ResultSet_getInt(result,
1);
const
char *name
= ResultSet_getString(result,
2);

int
blobSize;
const
void *image
= ResultSet_getBlob(result,
3,
&blobSize);

//...
}

Connection_close(con);
//连接使用完关闭连接
//...

ConnectionPool_free(&pool);
//关闭连接池
URL_free(&url);

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: