数据库连接池:相对于redis这种数据库中间件,redis消耗内存比较多。具备一定的缓存能力,和业务抽象能力,数据库连接池适合于单机系统性能的提升和DB业务的抽象解耦。
c/c++工程师常用的数据库连接池:
其中jdbc是最初是java版本的中间件,但是由于性能优异,方便操作,衍生出了c++版本。
libzdb是用c语言开发的数据库连接池。支持c、c++、object-c,是一个线程安全的数据库连接池。目前支持的数据库有:
使用方便简洁,url资源寻址方式。使用开源证书:
The library is licensed under a Free Open Source Software License.
libzdb3.1和之前的版本,使用gcc-4.8就可以编译通过。
libzdb3.2,在2019年3月份发布,主要是在3.1的基础上,增加了一个c++的模板"zdbpp.h",依据c++的语言风格封装了原理的功能,别的地方相差不大。 由于写这个接口文件的大神,用的是比较新的语法c++17(就这个有点坑),而centos7 的用户不像ubuntu一样,g++的版本比较低,一般都是4.8的,对于centos的用户来说不是很友好,本来我想把c++17改造成c++11,改了几个后发现太费时间,在下低于c++17不是很熟悉。
姑且先用g++8来编译吧。
sudo yum install centos-release-scl
sudo yum install devtoolset-8
scl enable devtoolset-8 bash
yum install sqlite sqlite-devel -y
[centos@1 build]$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
[centos@1 build]$
./configure
make
make install
默认的安装位置为:
库:
[centos@1 build]$ ll /usr/local/lib/libzdb.*
-rw-r--r--. 1 root root 546462 Oct 20 01:56 /usr/local/lib/libzdb.a
-rwxr-xr-x. 1 root root 933 Oct 20 01:56 /usr/local/lib/libzdb.la
lrwxrwxrwx. 1 root root 16 Oct 20 01:56 /usr/local/lib/libzdb.so -> libzdb.so.12.0.0
lrwxrwxrwx. 1 root root 16 Oct 20 01:56 /usr/local/lib/libzdb.so.12 -> libzdb.so.12.0.0
-rwxr-xr-x. 1 root root 313112 Oct 20 01:56 /usr/local/lib/libzdb.so.12.0.0
[centos@1 build]$
头文件:
[centos@1 build]$ ll /usr/local/include/zdb/
total 120
-rw-r--r--. 1 root root 11735 Oct 20 01:56 Connection.h
-rw-r--r--. 1 root root 17560 Oct 20 01:56 ConnectionPool.h
-rw-r--r--. 1 root root 10722 Oct 20 01:56 Exception.h
-rw-r--r--. 1 root root 10644 Oct 20 01:56 PreparedStatement.h
-rw-r--r--. 1 root root 23318 Oct 20 01:56 ResultSet.h
-rw-r--r--. 1 root root 1223 Oct 20 01:56 SQLException.h
-rw-r--r--. 1 root root 3005 Oct 20 01:56 Thread.h
-rw-r--r--. 1 root root 7019 Oct 20 01:56 URL.h
-rw-r--r--. 1 root root 1577 Oct 20 01:56 zdb.h
-rw-r--r--. 1 root root 16488 Oct 20 01:56 zdbpp.h
[centos@1 build]$
// main.cc
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <list>
#include <map>
#include <array>
#include <future>
#include <cassert>
#include <stdio.h>
#include <zdb.h>
using namespace std;
void db_test(void)
{
auto url = URL_new("sqlite:///tmp/order.db");
auto pool = ConnectionPool_new(url);
ConnectionPool_start(pool);
auto con = ConnectionPool_getConnection(pool);
TRY {
Connection_execute(con, "create table if not exists file_order(filename varchar(255), file_hash varchar(255), created_at timestamp)");
auto p = Connection_prepareStatement(con, "insert into file_order values (?, ?, ?)");
const char * bleach[] = {
"阿凡达.mp4",
"刘亦菲.jpeg",
"file1.txt",
"海阔天空.mp3",
"红豆.mp3",
"刘若英-后来.mp3",
"王宝强.html",
0
};
const char * file_hash[] = {
"4a66bd2a61a56433c2e3d7d3f5b013de825db2ec",
"5d58db7c3b1399dd4209cc8905dcc1b34522ae32",
"55ae75d991c770d8f3ef0cbfde12700b27e10cf9",
"c413489f5d54c782094bc7e1523c6d3ddab85c61",
"584f107b377f71d02ce558e56782ca12352bf655",
"b0b8da8677439a6b175196e4278185f0634bef96",
"1120155ccb665fb0ce14043dcf592b654e15c58c",
0
};
for (time_t i = 0, t = time(0); bleach[i] && file_hash[i]; i++) {
PreparedStatement_setString(p, 1, bleach[i]);
PreparedStatement_setString(p, 2, file_hash[i]);
PreparedStatement_setTimestamp(p, 3, t + i);
PreparedStatement_execute(p);
}
auto r = Connection_executeQuery(con,
"select filename, file_hash, datetime(created_at, 'unixepoch', 'localtime') from file_order");
while (ResultSet_next(r))
printf("%-22s\t %-22s\t %s\n", ResultSet_getString(r, 1), ResultSet_getString(r, 2), ResultSet_getString(r, 3));
//Connection_execute(con, "drop table bleach;");
}
CATCH(SQLException) {
printf("SQLException -- %s\n", Exception_frame.message);
}
FINALLY {
Connection_close(con);
}
END_TRY;
ConnectionPool_free(&pool);
URL_free(&url);
}
int main(int argc, char * *argv)
{
db_test();
return 0;
}
虽然libzdb是c++17编译,但是编译依赖libzdb的应用时,可以用c++11。
g++ main.cc -lzdb -lpthread -std=c++11 -I /usr/local/include/zdb/
运行a.out:
[centos@1 build]$ ./a.out
./a.out: error while loading shared libraries: libzdb.so.12: cannot open shared object file: No such file or directory
[centos@1 build]$
是因为/usr/local/lib 不是系统的默认链接加载路径,解决办法有三个:
1、在libzdb 编译时指定默认安装路径 ./configure --prefix=/usr/
2、临时改变ld路径export
[centos@1 ~]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
[centos@1 ~]$ echo $LD_LIBRARY_PATH
:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/usr/local/lib/
[centos@1 ~]$
3、第二个方法只能临时修改,想要避免麻烦,则修改系统配置文件
vim /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
source /etc/profile
[centos@1 build]$ ./a.out
阿凡达.mp4 4a66bd2a61a56433c2e3d7d3f5b013de825db2ec 2019-10-20 05:54:17
刘亦菲.jpeg 5d58db7c3b1399dd4209cc8905dcc1b34522ae32 2019-10-20 05:54:18
file1.txt 55ae75d991c770d8f3ef0cbfde12700b27e10cf9 2019-10-20 05:54:19
海阔天空.mp3 c413489f5d54c782094bc7e1523c6d3ddab85c61 2019-10-20 05:54:20
红豆.mp3 584f107b377f71d02ce558e56782ca12352bf655 2019-10-20 05:54:21
刘若英-后来.mp3 b0b8da8677439a6b175196e4278185f0634bef96 2019-10-20 05:54:22
王宝强.html 1120155ccb665fb0ce14043dcf592b654e15c58c 2019-10-20 05:54:23
[centos@1 build]$
直接用sqlite命令打开数据库查看:
sqlite> .mode column
sqlite> .tables
file_order
sqlite> select * from file_order;
阿凡达.mp4 4a66bd2a61a56433c2e3d7d3f5b013de825db2ec 1571550857
刘亦菲.jpe 5d58db7c3b1399dd4209cc8905dcc1b34522ae32 1571550858
file1.txt 55ae75d991c770d8f3ef0cbfde12700b27e10cf9 1571550859
海阔天空. c413489f5d54c782094bc7e1523c6d3ddab85c61 1571550860
红豆.mp3 584f107b377f71d02ce558e56782ca12352bf655 1571550861
刘若英-后 b0b8da8677439a6b175196e4278185f0634bef96 1571550862
王宝强.htm 1120155ccb665fb0ce14043dcf592b654e15c58c 1571550863
sqlite>