连接数据库

本节将介绍应用程序如何连接到数据库

打开和关闭连接

Environment类是用于创建Connection对象的工厂类。首先创建一个Environment实例,然后用户使用这个环境实例调用createConnection()方法连接到数据库。

示例2-4创建了一个Environment实例,然后使用username,password和数据库的信息(ip、端口号、数据库名)创建到数据库的连接。

必须使用以下代码示例中所示的terminateConnection()方法在工作会话结束时显式地关闭连接。另外,ACCI Environment应该被明确销毁。

请记住,在连接实例中创建或命名的所有对象都必须在该实例的内部作用域内;在连接终止之前,必须显式销毁这些对象的作用域。

示例2-4 如何创建一个Environment,然后连接到数据库,最后销毁Connection和Environment

Environment *env = Environment::createEnvironment();

Connection *conn = env->createConnection("username", "password", "connectionString");

env->terminateConnection(conn);

Environment::terminateEnvironment(env);

连接池

本节讨论如何使用ACCI的连接池功能。

使用连接池

许多中间层应用程序,能够为数据库连接启用大量线程。由于每个线程存在的时间相对较短,因此为每个线程打开到数据库的连接会降低连接的使用效率,并导致较差的性能。

通过使用连接池特性,您的应用程序可以创建一组对大量线程可用的连接,从而使您能够非常有效地使用数据库资源。

要创建连接池,可以使用createConnectionPool()方法,如示例2-6所示。

示例2-6 createConnectionPool()方法

virtual ConnectionPool* createConnectionPool(

    const string &poolUserName,

    const string &poolPassword,

    const string &connectString ="",

    unsigned int minConn =0,

    unsigned int maxConn =1,

    unsigned int incrConn =1) = 0;

例2-6参数:

  • poolUserName:连接池的所有者
  • poolPassword:已获得访问连接池的权限的密码
  • connectString:指定连接池与之相关的数据库服务器的数据库名称
  • minConn:创建连接池时要打开的最小连接数
  • maxConn:连接池可以维护的最大连接数。如果在连接池中没有调用setErrorOnBusy()方法,当连接池中打开的连接数达到最大,并且所有连接都处于繁忙状态时,ACCI调用的需要连接的方法调用将一直等待
  • incrConn:当所有连接都处于繁忙状态且调用的方法需要连接时,需要打开的连接数。只有当打开的连接总数小于该连接池中可以打开的最大连接数时,才会实现此增量

示例2-7演示了如何创建连接池。

你可以使用setTimeOut()方法对超过指定时间的空闲连接进行超时处理。ACCI定期终止空闲连接,以保持最佳的打开连接数。

没有限制一个环境只能有一个连接池。在一个ACCI环境中可以有多个连接池,这些连接池可以连接到相同或不同的数据库。这对于需要负载平衡的应用程序非常有用。

示例2-7如何创建连接池

const string poolUserName = "username";

const string poolPassword = "password";

const string connectString = "connectionString";

unsigned int maxConn = 5;

unsigned int minConn = 3;

unsigned int incrConn = 2;

    // 创建Environment
Environment *env = Environment::createEnvironment();

ConnectionPool *connPool = env->createConnectionPool(poolUserName, poolPassword, connectString, minConn, maxConn, incrConn);

env->terminateConnectionPool(connPool);

Environment::terminateEnvironment(env);

连接状态获取

方法一:getServerStatus

acci接口中在Connection类中新增了getServerStatus方法,可以获得当前连接的状态,连接可以是从连接池中获得的连接。

getServerStatus返回值有两种情况,分别是:

  • ACCI_SERVER_NOT_CONNECTED :未连接或者连接断开
  • ACCI_SERVER_NORMAL :连接正常

示例如下:

int serverStatus = 0;
serverStatus = conn->getServerStatus();

如果连接状态为ACCI_SERVER_NOT_CONNECTED,则无法进行数据库操作。

值得注意的是getServerStatus方法必须是在一个acci接口对数据库操作失败的情况下,如果是因为网络导致的失败,才能获取到正确的网络状态。

方法二:ping

可以通过Connection类中的ping方法获得连接状态,ping操作会发送一个轻量级的操作给数据库端,如果操作失败(返回值小于0),则代表网络有问题,反之则网络正常。

此时如果ping操作失败,用方法一的getServerStatus方法获取状态,返回值也应该是ACCI_SERVER_NOT_CONNECTED。操作示例如下:

int status = conn->ping();
EXPECT_EQ(status, 0);
if (status < 0)
{
        int serverStatus = 0;
        serverStatus = conn->getServerStatus(); // serverStatus 的值应该为ACCI_SERVER_NOT_CONNECTED
        cout << "connect error" << endl;
}
else
{
        cout << "connect ok" << endl;
}