当前位置: 首页 > 工具软件 > libzdb > 使用案例 >

libzdb(v3.2.2) 数据库连接池(C/C++)

孙洋
2023-12-01

官网地址:http://www.tildeslash.com/libzdb/#api

以下信息根据官网英文原版翻译

libzdb是一个小型、易于使用的开源数据库连接池库,具有以下功能:

  • 线程安全数据库连接池
  • 连接到多个数据库系统
  • 零运行时配置,使用URL方案连接
  • 支持MySQL、PostgreSQL、SQLite、Oracle、SqlServer

连接URL:

在创建时提供给连接池的URL以标准URL格式指定数据库连接。连接URL的格式定义为:

database://[user:password@][host][:port]/database[?name=value][&name=value]...

属性名user和password始终被识别,并指定如何登录到数据库。其他属性取决于有问题的数据库服务器。用户名和密码也可以在URL的auth部分指定。如果省略端口号,则使用数据库服务器的默认端口号。连接URL中使用的保留字符必须是URL编码 .

MySQL数据库:

下面是如何连接到MySQL数据库服务器的示例:

mysql://localhost:3306/test?user=root&password=swordfish

在本例中,用户名、根目录和密码、剑鱼被指定为URL的属性。另一种方法是使用URL的auth部分指定身份验证信息:

mysql://root:swordfish@localhost:3306/test

参见mysql选项对于可以为mysql连接URL设置的所有属性。

SQLite:

For a SQLite database the connection URL should simply specify a database file, since a SQLite database is just a file in the filesystem. SQLite uses pragma commands for performance tuning and other special purpose database commands. Pragma syntax on the form, name=value can be added as properties to the URL and will be set when the Connection is created. In addition to pragmas, the following properties are supported:

  • heap_limit=value [KB] - Make SQLite auto-release unused memory if memory usage goes above the specified value.

用于连接到SQLite数据库的URL可能如下所示:

sqlite:///var/sqlite/test.db?synchronous=normal&heap_limit=8000&foreign_keys=on

PostgreSQL:

用于连接到PostgreSQL数据库服务器的URL可能如下所示:

postgresql://localhost:5432/test?user=root&password=swordfish

与MySQL URL一样,用户名和密码被指定为URL的属性。同样,可以使用URL的auth部分来指定用户名和密码:

postgresql://root:swordfish@localhost/test?use-ssl=true

在本例中,我们还省略了服务器的端口号,在这种情况下,使用PostgreSQL的默认端口号5432。此外,我们在URL中添加了一个额外的参数,因此到服务器的连接是通过安全SSL连接完成的。

参见postgresql选项对于可以为postgresql连接URL设置的所有属性。

Oracle:

用于连接到Oracle数据库服务器的URL可能如下所示:

oracle://localhost:1521/servicename?user=scott&password=tiger

Oracle使用服务名称而不是数据库名称。上面url中的信息通常在tnsnames.ora配置文件,由环境变量TNS_ADMIN指向。在下面的示例中,我们使用的不是主机、端口和服务名称,而是使用中定义的tnsnametnsnames.ora. 我们还使用URL的auth部分来指定用户名和密码。最后,我们指定要使用SYSDBA角色连接到Oracle。

oracle://sys:secret@/tnsname?sysdba=true

参见oracle选项对于可以为oracle连接URL设置的所有属性。

示例:

要获取MySQL数据库的连接池,可以使用以下代码。PostgreSQL、SQLite和Oracle也可以使用完全相同的代码,只需修改连接URL即可。这里我们连接到本地主机上的数据库测试,并使用默认的5个初始连接启动池。

ConnectionPool, Connection and ResultSet:

URL_T url = URL_new("mysql://localhost/test?user=root&password=swordfish");
ConnectionPool_T pool = ConnectionPool_new(url);
ConnectionPool_start(pool);

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);
     [..]
}

下面是另一个选择并打印生成结果的示例:

ResultSet_T r = Connection_executeQuery(con, "SELECT count(*) FROM users");
printf("Number of users: %s\n", ResultSet_next(r) ? ResultSet_getString(r, 1) : "no users");

准备声明:

PreparedStatement_T p = Connection_prepareStatement(con, 
                        "INSERT INTO employee(name, picture) VALUES(?, ?)");
PreparedStatement_setString(p, 1, "Kamiya Kaoru");
PreparedStatement_setBlob(p, 2, jpeg, jpeg_size);
PreparedStatement_execute(p);

这里,我们使用一个准备好的语句来执行一个返回结果集的查询:

PreparedStatement_T p = Connection_prepareStatement(con, 
                        "SELECT id FROM employee WHERE name LIKE ?"); 
PreparedStatement_setString(p, 1, "%Kaoru%");
ResultSet_T r = PreparedStatement_executeQuery(p);
while (ResultSet_next(r))
       printf("employee.id = %d\n", ResultSet_getInt(r, 1));

C示例:

要在c17项目中使用libzdb,请导入zdbpp.h并使用命名空间zdb :

#include <zdbpp.h>
using namespace zdb;

查询示例

ConnectionPool pool("mysql://192.168.11.100:3306/test?user=root&password=dba");
pool.start();
Connection con = pool.getConnection();
// Use C++ variadic template feature to bind parameter 
ResultSet result = con.executeQuery(
     "select id, name, hired, image from employee where id < ? order by id", 100
);
// Optionally set row prefetch, default is 100
result.setFetchSize(10);
while (result.next()) {
     int id = result.getInt("id");
     const char *name = result.getString("name");
     time_t hired = result.getTimestamp("hired");
     auto [image, size] = result.getBlob("image");
     ...
}

Execute语句

Connection con = pool.getConnection();
// Any execute or executeQuery statement which takes parameters are 
// automatically translated into a prepared statement. Here we also 
// demonstrate how to set a SQL null value by using nullptr
con.execute("update employee set image = ? where id = ?", nullptr, 11);

SQL空值测试

ResultSet result = con.executeQuery("select name, image from employee");
while (result.next()) {
    if (result.isnull("image")) {
        ...
    }
}

通过准备好的语句插入数据

Connection con = pool.getConnection();
PreparedStatement prep = con.prepareStatement(
     "insert into employee (name, hired, image) values(?, ?, ?)"
);
con.beginTransaction();
for (const auto &employee : employees) {
        // Polymorphic bind
        prep.bind(1, employee.name);
        prep.bind(2, employee.hired);
        prep.bind(3, employee.image);
        prep.execute();
}
con.commit();

异常处理

try {
    con = pool.getConnection();
    con.executeQuery("invalid query");
} catch (sql_exception& e) {
    std::cout <<  e.what();
}

源码下载地址:https://download.csdn.net/download/u012156872/12723746,此源码基于libzdb v3.2.2版本编译,编译工具VS2019。

 类似资料: