1. 什么是连接池
在使用数据库的过程中,每次进行连接都需要建立一次连接,这样就会比较耗费性能,尤其在高并发的情况下更加明显。为了解决这个问题,引入了连接池的概念。
连接池是一组已经初始化的连接对象集合,供程序员重复使用,以避免频繁创建连接对象,减轻数据库服务器的负担,提高对数据库操作的性能。
2. C语言连接MSSQL数据库
2.1 Windows环境下连接MSSQL数据库
在Windows环境下连接MSSQL数据库可以使用ODBC接口,需要先在Windows系统中配置ODBC数据源,具体的步骤如下:
打开“控制面板”,选择“管理工具”,打开“ODBC数据源(64位)”
选择“系统DSN”,点击“添加”
选择SQL Server Native Client 11.0驱动,点击“完成”
在“设置SQL Server Native Client 11.0 DSN 配置”中填写MSSQL服务器名称、相应的数据库名称、MSSQL用户名称和密码,点击“下一步”
选择“默认设置”,点击“完成”
当配置完成后,就可以使用ODBC接口连接MSSQL数据库。下面给出一个使用ODBC连接MSSQL数据库的示例:
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
int main(void)
{
SQLHENV henv; // 环境句柄
SQLHDBC hdbc; // 连接句柄
SQLHSTMT hstmt; // 语句句柄
// 分配环境句柄
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// 设置环境句柄属性,实现ODBC 3.0的效果
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
// 分配连接句柄
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// 连接数据库
SQLDriverConnect(hdbc, NULL, (unsigned char*) "DSN=myDSNName", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
// 执行SQL语句
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
SQLExecDirect(hstmt, (unsigned char*) "SELECT * FROM mytable", SQL_NTS);
// 释放资源
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
2.2 Linux环境下连接MSSQL数据库
在Linux环境下连接MSSQL数据库可以使用FreeTDS接口,需要先安装FreeTDS的相关包。
下面给出一个使用FreeTDS连接MSSQL数据库的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <sybfront.h>
#include <sybdb.h>
#define DB_SERVER "mydbserver"
#define DB_PORT "1433"
#define DB_NAME "mydbname"
#define DB_USER "mydbuser"
#define DB_PASS "mydbpassword"
int main(int argc, char *argv[])
{
DBPROCESS *dbproc;
LOGINREC *login;
char buf[1024];
RETCODE erc;
int sofar,retcode,row,col;
if (dbinit() == FAIL)
exit(ERREXIT);
login = dblogin();
DBSETLUSER(login,DB_USER);
DBSETLPWD(login,DB_PASS);
DBSETLCHARSET(login,"iso_1");
DBSETLHOST(login,DB_SERVER);
DBSETLPORT(login,atoi(DB_PORT));
dbproc = dbopen(login, DB_SERVER);
if (dbproc == NULL)
{
dbexit();
return -1;
}
erc = dbuse(dbproc, DB_NAME);
if(erc == FAIL)
{
dbclose(dbproc);
dbexit();
return -1;
}
sprintf(buf, "SELECT * FROM mytable");
erc = dbfcmd(dbproc, buf);
if(erc == FAIL)
{
dbclose(dbproc);
dbexit();
return -1;
}
erc = dbsqlexec(dbproc);
if(erc == FAIL)
{
dbclose(dbproc);
dbexit();
return -1;
}
retcode = DBMORECMD(dbproc);
while((retcode != NO_MORE_RESULTS) || (erc == NO_MORE_RESULTS))
{
erc = dbsqlok(dbproc);
if(erc == FAIL)
{
dbclose(dbproc);
dbexit();
return -1;
}
sofar = 0;
while((erc = dbresults(dbproc)) != NO_MORE_RESULTS)
{
if(erc == FAIL)
{
dbclose(dbproc);
dbexit();
return -1;
}
while((row = dbnextrow(dbproc)) != NO_MORE_ROWS)
{
if(row == REG_ROW)
{
printf("Data:\n");
for(col=1;col <= dbnumcols(dbproc);col++)
{
printf("%s\t", dbcolname(dbproc,col));
}
printf("\n");
for(col=1;col <= dbnumcols(dbproc);col++)
{
printf("%s\t", dbcurcol(dbproc,col));
}
printf("\n");
}
else if (row == BUF_FULL)
{
printf("Buffer Full\n");
dbnextrow(dbproc);
}
else
{
// Nothing
}
}
}
retcode = DBMORECMD(dbproc);
}
dbclose(dbproc);
dbexit();
return 0;
}
3. 使用连接池连接MSSQL数据库
连接池的实现可以使用第三方库,比如C3P0、Apache Commons DBCP等。下面以C3P0为例说明如何使用连接池来连接MSSQL数据库。
首先需要在项目中导入C3P0的相关包,在代码中通过如下方式创建连接池:
// 数据库连接池
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 初始化连接池
static
{
try
{
// 配置数据库信息
dataSource.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataSource.setJdbcUrl("jdbc:sqlserver://localhost:1433;databaseName=mydbname");
dataSource.setUser("mydbuser");
dataSource.setPassword("mydbpassword");
dataSource.setInitialPoolSize(5);
dataSource.setMaxPoolSize(20);
dataSource.setMinPoolSize(5);
}
catch (Exception e)
{
e.printStackTrace();
}
}
// 获取数据库连接
public static Connection getConnection() throws SQLException
{
return dataSource.getConnection();
}
通过连接池获取的连接不用关闭,连接池会自动管理连接的释放。
4. 使用连接池的好处
使用连接池可以有效地提高数据库访问性能,降低系统资源占用率,具体好处如下:
减小数据库连接启动造成的额外开销,提高数据库访问的速度和效率;
多个客户端共享一个连接池,可以减少系统开销,提高应用程序负载量;
连接池能够有效地控制连接的数量,避免超过系统承载能力而导致的资源浪费和系统崩溃;
连接池能够监控连接的使用情况,当连接不可用时能够及时释放,保证连接的可靠性。
5. 总结
连接池可以有效地提高数据库访问性能,降低系统资源占用率,连接池的实现有多种方式,可以依据系统需要进行选择。使用连接池还需要注意一些问题,比如连接池的大小、最大连接时间等。