ODBC:连接与连接池

在使用C++访问数据库时一定会使用到连接与连接池,下面就以MS SQL Server为例,介绍一下如何使用它们。

目录

一、连接字符串是怎样定义的?

二、如何使用连接字符串?

三、连接中需要设置哪些属性?

四、如何获取连接的属性值?

五、如何设置连接池

六、如何从连接池中取出连接,如何释放连接池中的连接?


一、连接字符串是怎样定义的?

下面通过一个例子,说明连接字符串要如何配置:

Driver={ODBC Driver 17 for SQL Server};Address=tcp:127.0.0.1,1433;Server=\\TestServer;Database=testDB;Uid=guest;Pwd=12345678;language=Simplified Chinese;

  •  Driver——表示所使用的驱动名称。本机可使用的驱动可以在“ODBC数据源” - > “驱动程序”中找到所有可用驱动程序。如果不想自己手动输入,也可以在“ODBC数据源” - > “文件DNS”点击“添加”,选中想要使用的驱动,点击“高级”,就可以看到可以复制的驱动名称。
  • Address——表示要连接的数据库网络地址。一般包格式:
     Address=[protocol:]Address[,port |\pipe\pipename]
     协议可以是 tcp (TCP/IP)、 lpc (共享内存)或 np (命名管道)
  • Server——表示数据库实例名。一般包格式:
     Server=[protocol:]Server[,port]
     协议可以是 tcp (TCP/IP)、 lpc (共享内存)或 np (命名管道)
  • Database——表示数据库名
  • Uid——表示登录用户名
  • Pwd——表示登录用户密码
  • Language——表示数据库服务器使用的语言(可选)

 其中Address的内容可以和到Server中。

二、如何使用连接字符串?

SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;

SQLRETURN retcode;

# 分配环境句柄
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
# 使用环境句柄设置驱动版本号
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
# 分配连接句柄
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
# 设置连接登录超时
retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);

SQLWCHAR outstr[1024];
SQLSMALLINT outstrlen;
retcode = SQLDriverConnect(hdbc, NULL, (SQLWCHAR*)
L"Driver={ODBC Driver 17 for SQL Server};Server=127.0.0.1,1433\\TestServer;Database=testDB;Uid=sa;Pwd=12345678;", 
SQL_NTS, outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_NOPROMPT);

SQLDriverConnect函数的定义如下:

SQLRETURN SQLDriverConnect(  
     SQLHDBC         ConnectionHandle,  
     SQLHWND         WindowHandle,  
     SQLCHAR *       InConnectionString,  
     SQLSMALLINT     StringLength1,  
     SQLCHAR *       OutConnectionString,  
     SQLSMALLINT     BufferLength,  
     SQLSMALLINT *   StringLength2Ptr,  
     SQLUSMALLINT    DriverCompletion);

InConnectionString——表示连接字符串。如果StringLength1的值为SQL_NTS,则InConnectionString必须以'\0'结尾,否则,StringLength1要指定InConnectionString的长度。

OutConnectionString——表示InConnectionString被解析完成后最终生成的连接字符串。

BufferLength——表示用于存放OutConnectionString的缓冲区大小。

StringLength2Ptr——表示最终生成的OutConnectionString的长度。

三、连接中需要设置哪些属性?

设置连接属性的函数如下:

SQLRETURN SQLSetConnectAttr(  
     SQLHDBC       ConnectionHandle,  
     SQLINTEGER    Attribute,  
     SQLPOINTER    ValuePtr,  
     SQLINTEGER    StringLength);

常用连接属性、属性类型、可选属性参数:

SQL_ATTR_CONNECTION_TIMEOUT   An SQLUINTEGER value
SQL_ATTR_LOGIN_TIMEOUT                An SQLUINTEGER value
SQL_ATTR_PACKET_SIZE                     An SQLUINTEGER value
SQL_ATTR_ACCESS_MODE                  An SQLUINTEGER value. if a data source is read-only or read-write.
    SQL_MODE_READ_ONLY
    SQL_MODE_READ_WRITE    default
SQL_ATTR_AUTOCOMMIT                     A SQLUINTEGER value
    SQL_AUTOCOMMIT_ON   default
    SQL_AUTOCOMMIT_OFF
SQL_ATTR_TXN_ISOLATION                 A 32-bit bitmask
    SQL_TXN_READ_UNCOMMITTED
    SQL_TXN_READ_COMMITTED
    SQL_TXN_REPEATABLE_READ
    SQL_TXN_SERIALIZABLE
SQL_ATTR_CONNECTION_DEAD          A read-only SQLUINTEGER value
    SQL_CD_TRUE
    SQL_CD_FALSE

这些属性的具体说明及其它属性的说明,请查阅参考文档。

四、如何获取连接的属性值?

可以通过SQLGetConnectAttr 函数获取连接的属性值,下面举例说明:

SQLUINTEGER getAutoCommit(SQLHDBC hdbc) {
  SQLUINTEGER autoCommit;
  SQLRETURN retCode = SQLGetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)&autoCommit, sizeof(autoCommit), NULL);
  
  return autoCommit;
};


SQLUINTEGER getTxnIsolation(SQLHDBC hdbc) {
  SQLUINTEGER txnIsolation;
  SQLRETURN retCode = SQLGetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)&txnIsolation, sizeof(txnIsolation), NULL);

  return txnIsolation;
};

五、如何设置连接池

设置连接池需要用到的环境属性及其可选的值:

SQL_ATTR_CONNECTION_POOLING
    SQL_CP_ONE_PER_HENV
    SQL_CP_ONE_PER_DRIVER
    SQL_CP_DEFAULT  = SQL_CP_OFF
    SQL_CP_OFF

SQL_CP_ONE_PER_HENV——表示每个环境对应一个池。这个池中可以有不同驱动的连接
SQL_CP_ONE_PER_DRIVER——表示每个驱动对应一个池。这个池中可以有从不同环境中创建的连接,只要驱动相同就会放到一个池中。

SQLHENV   henv  = SQL_NULL_HENV;
SQLRETURN retCode;

retCode = SQLSetEnvAttr(SQL_NULL_HANDLE, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER*)SQL_CP_ONE_PER_HENV, 0);

retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

注意,连接池属性必须在环境句柄创建前设置。

六、如何从连接池中取出连接,如何释放连接池中的连接?

 从连接池中取出连接的方式跟创建单个连接的方式相同,都是先设置连接属性再创建连接(有些连接属性可能在创建连接后设置)

SQLHDBC   hdbc = SQL_NULL_HDBC;
SQLRETURN retCode;

retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

retCode = SQLSetConnectAttr(hdbc, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER)5, 0);
retCode = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
retCode = SQLSetConnectAttr(hdbc, SQL_ATTR_ACCESS_MODE, (SQLPOINTER)accessMode, 0);
retCode = SQLSetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)txnIsolationLevel, 0);
retCode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)autoCommit, 0);

SQLWCHAR outConnStr[1024];
SQLSMALLINT outConnLen;
retCode = SQLDriverConnect(hdbc, NULL, (SQLWCHAR*)connStr.c_str(), SQL_NTS, outConnStr, sizeof(outConnStr), &outConnLen, SQL_DRIVER_NOPROMPT);

 释放连接池中的连接跟释放单个连接使用的API相同,不同之处在于相同API背后实现的机制不同:连接池中的连接释放后会返回连接池,后续可再取出使用,而单个连接释放后是断开连接。

if (hdbc != SQL_NULL_HDBC) {
  SQLDisconnect(hdbc);
  SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  hdbc = SQL_NULL_HDBC;
}

 

参考

将连接字符串关键字用于 SQL Server Native Client
SQLDriverConnect 函数
SQLSetConnectAttr 函数

ODBC连接池配置:

Pooling in the Microsoft Data Access Components
关于连接池环境如何创建,请查阅“SQLAllocHandle 函数”
关于连接池的配置参数的介绍,请查阅“SQLSetEnvAttr 函数”
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值