C++soci第三方库

soci第三方库的安装与环境配置

git clone https://github.com/SOCI/soci.git
cd soci
mkdir build
cd build
cmake ..
make
sudo make install

安装好之后需要手动链接库-lsoci_core -lsoci_mysql -lmysqlclient

运行之后遇到报错 error while loading shared libraries: libsoci_core.so.4.1: cannot open shared object file: No such file or directory的解决方案: 运行命令:find /usr/lib /usr/local/lib -name "libsoci_core.so*”,会返回文件所在位置:

/usr/local/lib/libsoci_core.so.4.1.0
/usr/local/lib/libsoci_core.so.4.1
/usr/local/lib/libsoci_core.so

找到缺损文件的对应版本(我的缺省版本是4.1),复制路径执行

echo "{path}" | sudo tee /etc/ld.so.conf.d/soci.conf
sudo ldconfig

将{path}替换为find命令的输出路径,之后运行sudo ldconfig更新库缓存,报错就解决了

soci的使用方法之数据插入 

引入头文件

#include <iostream>
#include "soci/soci.h"
#include "soci/soci-platform.h"

初始化session

soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
// 如果要连接远程数据库,添加host和port字段 host=remote_host port=3306

第一个参数为使用的后端数据库类型,第二个参数为数据库连接参数,可以指定的参数包括host port dbname user passowrd等,以空格分隔

insert插入表

std::string userid = "111";
std::string listid = "2222";
std::string listname = "33333";
sql << "insert into music_list values(:userid, :listid, :listname)", 
				soci::use(userid), soci::use(listid), soci::use(listname);
  • 补充(需要注意的事项):

①通过流的方式传递sql语句,用use语法传递参数;

②其中Person(first_name, last_name)为数据库table名和column名,values(:first_name, :last_name)里的为参数的占位符,这里可以随便书写;

③需要注意的是use函数里的参数的生命周期,切记不能将函数返回值作为use函数的参数

查询mysql执行结果:

long long id;
int affected_rows = sql.get_last_insert_id("Person", id);
cout << "Query OK, " << affected_rows << " row(s) affected" << endl;

get_last_insert_id函数可以获取自增长主键(通常是 AUTO_INCREMENT)相关的插入操作所产生的 ID,它可以用于获取新插入行的唯一标识符,以便在应用程序中跟踪或与其他表建立关联。这在涉及具有自增主键的表时尤其常见。SOCI 库在处理不同数据库时,按需提供了不同的实现。

  • 完整示例:
#include <iostream>
#include "soci/soci.h"
#include "soci/soci-platform.h"
using namespace std;
int main() {
	try {
		soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
		// 如果要连接远程数据库,添加host和port字段:host=remote_host;port=3306;
		string userid = "111";
		string listid = "2222";
		string listname = "33333";
		sql << "insert into music_list values(:userid, :listid, :listname)", 
						soci::use(userid), soci::use(listid), soci::use(listname);
		long long id;
		int affected_rows = sql.get_last_insert_id("music_list ", id);
		cout << "Query OK, " << affected_rows << " row(s) affected" << endl;
	} catch (const soci::soci_error& e) {
        cout << "Database error: " << e.what() << endl;
        return -1; 
    } catch (const std::exception& e) {
        cout << "Standard exception: " << e.what() << endl;
        return -1;
    }
	return 0;
}

soci使用方法之查询select

可以使用类似流的接口从行对象中提取数据,其中每个提取的变量应该具有对应于其在链中的位置的匹配类型:

soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
		string list_ID = "1111";
		string song_id = "222222";
		soci::row r;
    sql << "SELECT music_name,author_name,album_name FROM list_content WHERE list_ID=:list_ID AND song_id=:song_id",
          into(r), soci::use(list_ID), soci::use(song_id);

但是请注意,此接口与标准的std::istream类不兼容,并且一次只能提取单行——出于“安全”原因,保留行边界,并且有必要为每个连续的行显式地执行提取操作。

string musicname, singer, album;
		r >> musicname >> singer >> album;
		cout << "musicname: " << musicname << "\\tsinger: " << singer << "\\talbum: " << album << endl;

上述方法对于只针对查询出一条结果,如果查询结果有多条呢?就需要使用下面的方法:

对于只有一个字段的多条结果集:

string list_ID = "17243903906429226";
		soci::rowset<string> rs = (sql.prepare << "SELECT music_name FROM list_content WHERE list_ID=:list_ID", 
															soci::use(list_ID));
		for (soci::rowset<string>::const_iterator it = rs.begin(); it != rs.end(); ++it) {
        	cout << *it << endl;
		}

对于一条语句有多个字段的结果集

string list_ID = "17243903906429226";
soci::rowset<soci::row> rs = (sql.prepare << "SELECT music_name,author_name,album_name FROM list_content WHERE list_ID=:list_ID", 
														soci::use(list_ID));
for (soci::rowset<soci::row>::const_iterator it = rs.begin(); it != rs.end(); ++it) {
    soci::row const& row = *it;
    cout << "music_name: " << row.get<string>(0)
       	<< "\\t\\t\\t\\tauthor_name: " << row.get<string>(1)
       	<< "\\t\\t\\t\\talbum_name: " << row.get<string>(2)
				<< endl;
		}

注意:当只有一条结果集的时候,rs里的类型是string、int或其他,如果有多个结果的时候,类型为soci::row ,对于只有一个字段的结果集,也可以使用下面的方法,兼容性更高。

  • 完整示例:
int select() {
	try {
		soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
		/*
		// 只有一条结果
		string list_ID = "17243903906429226";
		string song_id = "222222";
		soci::row r;
        sql << "SELECT music_name,author_name,album_name FROM list_content WHERE list_ID=:list_ID",
            into(r), soci::use(list_ID);
        if (!sql.got_data()) {
            std::cout << "No record found." << std::endl;
            return 0;
        }
		string musicname, singer, album;
		r >> musicname >> singer >> album;
		cout << "musicname: " << musicname << "\\tsinger: " << singer << "\\talbum: " << album << endl;
		*/
		
		/*
		//结果集只有一个字段
		string list_ID = "17243903906429226";
		soci::rowset<string> rs = (sql.prepare << "SELECT music_name FROM list_content WHERE list_ID=:list_ID", soci::use(list_ID));
		for (soci::rowset<string>::const_iterator it = rs.begin(); it != rs.end(); ++it) {
        	cout << *it << endl;
		}
		*/

		/*
		// 结果集有多个字段
		string list_ID = "17243903906429226";
		soci::rowset<soci::row> rs = (sql.prepare << "SELECT music_name,author_name,album_name FROM list_content WHERE list_ID=:list_ID", soci::use(list_ID));
		for (soci::rowset<soci::row>::const_iterator it = rs.begin(); it != rs.end(); ++it) {
    		soci::row const& row = *it;
    		cout << "music_name: " << row.get<string>(0)
            	<< "\\t\\t\\t\\tauthor_name: " << row.get<string>(1)
            	<< "\\t\\t\\t\\talbum_name: " << row.get<string>(2)
				<< endl;
		}
		*/
	} catch (const soci::soci_error& e) {
        cout << "Database error: " << e.what() << endl;
        return -1; 
    } catch (const std::exception& e) {
        cout << "Standard exception: " << e.what() << endl;
        return -1;
    }
	return 0;
}

soci使用方法之删除delete

有时候我们需要关注delete操作是否真的删除了数据,mysql本身也会返回操作影响的行数,可以采用如下方法获取:

soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
string list_ID = "1111";
soci::statement stmt = (sql.prepare << "DELETE FROM list_content WHERE list_ID=:name", soci::use(list_ID));
stmt.execute(true);
long long affected_rows = stmt.get_affected_rows();
std::cout << "Affected rows is " << affected_rows << "." << std::endl;

soci使用方法之更新update

在stmt执行之后,使用stmt.get_affected_rows();语句可以获取操作影响的行数

soci::session sql("mysql", "dbname=music user=wxx password=Wangxinxue666666");
string list_ID = "17243903906497807";
string id = "1111";
string first = "hello";
string last = "world";
soci::statement stmt = (sql.prepare << "update list_content set music_name=:first, author_name=:last where list_ID=:id", 
					    					soci::use(first), soci::use(last), soci::use(id));
stmt.execute(true);
long long affected_rows = stmt.get_affected_rows();
std::cout << "Affected rows is " << affected_rows << "." << std::endl;	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值