C++ 通用数据库操作之SOCI

简介

SOCI是用C ++编写的数据库访问库,使人将SQL查询嵌入常规C ++代码中,而完全位于标准C ++中。

这个想法是为C ++程序员提供一种以最自然,最直观的方式访问SQL数据库的方法。如果您发现现有库太难满足您的需求或分散注意力,那么SOCI可能是一个不错的选择。

当前支持的后端:

一、连接测试

1#include <iostream> 2#include <exception> 3#include <soci/soci.h> 4#include <soci/mysql/soci-mysql.h> 5 6void connectTest() 7{ 8 try 9 { 10 soci::session sql(soci::mysql, "host=127.0.0.1 dbname=mydb user=root password='123456'"); 11 12 soci::rowset<soci::row> rs = (sql.prepare << "select Id, username,age FROM student"); 13 for (auto it = rs.begin(); it != rs.end(); ++it) 14 { 15 const soci::row& row = *it; 16 std::cout << "id:" << row.get<uint>("Id") << " username:" << row.get<std::string>("username") 17 << " age:" << row.get<int>("age") << std::endl; 18 } 19 } 20 catch(soci::soci_error & e) 21 { 22 std::cout << e.what() << std::endl; 23 } 24}

二、查询

1、单行查询

 

1soci::row itRet; 2(sqlSession << strSql),into(itRet); 3if (!sqlSession.got_data()4    return; 5auto val = itRet.get<std::string>(0);

2、多行查询

1soci::rowset<soci::row> rslt = (sqlSession.prepare << strSql); 2for (auto& itRet : rslt) 3{ 4}

3、多行查询存放到列表

1void queryTest() 2{ 3     try 4    { 5       soci::session sqlSession(soci::mysql, "host=127.0.0.1 dbname=mydb user=root password='123456'");      6       std::vector<std::string> vecStudent(100); 7       std::vector<int> vecAge(100); 8       sqlSession << "select username,age FROM student", soci::into(vecStudent), soci::into(vecAge); 9      10    } 11    catch(soci::soci_error & e) 12    { 13        std::cout << e.what() << std::endl; 14    } 15}

4、多行全表数据查询

1soci::row itRet; 2soci::statement st = ((sqlSession.prepare <<  strSQL),soci::into(itRet)); 3st.execute(); 4 5//获取字段信息 6std::vector<std::string> vecFieldList; 7for (std::size_t i = 0; i != itRet.size(); ++i) 8{ 9     const soci::column_properties & props =  itRet.get_properties(i); 10     std::string strField = props.get_name(); 11     vecFieldList.push_back(strField); 12} 13 14while (st.fetch()) 15{ 16    for (auto i = 0; i < itRet.size(); i++) 17    { 18        std::string strValue = GetFieldValue(itRet, i); 19    } 20}

三、更新、插入、删除

1、简易操作

1auto username = "admin"; 2auto age = 10; 3sqlSession << "insert into student(username, age) values(:username, :age)", use(username), use(age);

2、获取影响行数

1statement st = (sqlSession.prepare << "delete from student where id=:id", use(id)); 2st.execute(true); 3int affected_rows = st.get_affected_rows();

四、多线程下连接池

1int g_pool_size = 5; 2soci::connection_pool g_pool(g_pool_size); 3void init_pool() 4{ 5 for (int i = 0; i < g_pool_size; ++i) 6 { 7 session& sql = g_pool.at(i); 8 sql.open(soci::mysql, "host=127.0.0.1 dbname=mydb user=root password='123456'"); 9 } 10} 11soci::session sql(g_pool); 12sqlSession << "insert into student(username, age) values(:username, :age)", soci::use(username), soci::use(age);

五、泛型加载,统一转换成字符型

1std::string GetFieldValue(const soci::row& itRet, int pos) 2{ 3 const soci::column_properties & props = itRet.get_properties(pos); 4 if (itRet.get_indicator(pos) == soci::i_null) 5 { 6 return ""; 7 } 8 switch (props.get_data_type()) 9 { 10 case soci::dt_string: 11 return itRet.get<std::string>(pos); 12 break; 13 case soci::dt_double: 14 return std::to_string(itRet.get<double>(pos)); 15 break; 16 case soci::dt_integer: 17 return std::to_string(itRet.get<int>(pos)); 18 break; 19 case soci::dt_long_long: 20 return std::to_string(itRet.get<long long>(pos)); 21 break; 22 case soci::dt_unsigned_long_long: 23 return std::to_string(itRet.get<unsigned long long>(pos)); 24 break; 25 case soci::dt_date: 26 std::tm when = itRet.get<std::tm>(pos); 27 return asctime(&when); 28 break; 29 } 30 return std::string(); 31} 32 33soci::rowset<soci::row> rs = (sqlSession.prepare << "select Id, username,age FROM student"); 34for (auto& it : rs) 35{ 36 std::cout << "username:" << GetFieldValue(it, 0) << " age:" << GetFieldValue(it, 1) << std::endl; 37}

六、简化数据读取,防止空数据导致异常

1template<typename T, typename V> 2void GetFieldValue(const soci::row& itRet, T at, V& val) 3{ 4 val = itRet.get<V>(at, val); 5} 6template<typename V> 7void GetFieldValue(const soci::row& itRet, int pos, V& val) 8{ 9 val = itRet.get<V>(pos, val); 10} 11template<typename V> 12void GetFieldValue(const soci::row& itRet, const char* field, V& val) 13{ 14 val = itRet.get<V>(field, val); 15} 16 17soci::rowset<soci::row> rs = (sqlSession.prepare << "select Id, username,age FROM student"); 18for (auto& it : rs) 19{ 20 std::stirng name; 21 int age = -1; 22 GetFieldValue(it, 0, name); 23 GetFieldValue(it, 1, age); 24 std::cout << "username:" << name << " age:" << age << std::endl; 25}

七、ORM

1struct Person 2{ 3 int id; 4 std::string firstName; 5 std::string lastName; 6 std::string gender; 7}; 8 9 10namespace soci 11{ 12 template<> 13 struct type_conversion<Person> 14 { 15 typedef values base_type; 16 17 18 static void from_base(values const & v, indicator /* ind */, Person & p) 19 { 20 p.id = v.get<int>("ID"); 21 p.firstName = v.get<std::string>("FIRST_NAME"); 22 p.lastName = v.get<std::string>("LAST_NAME"); 23 24 25 // p.gender will be set to the default value "unknown" 26 // when the column is null: 27 p.gender = v.get<std::string>("GENDER", "unknown"); 28 29 30 // alternatively, the indicator can be tested directly: 31 // if (v.indicator("GENDER") == i_null) 32 // { 33 // p.gender = "unknown"; 34 // } 35 // else 36 // { 37 // p.gender = v.get<std::string>("GENDER"); 38 // } 39 } 40 41 42 static void to_base(const Person & p, values & v, indicator & ind) 43 { 44 v.set("ID", p.id); 45 v.set("FIRST_NAME", p.firstName); 46 v.set("LAST_NAME", p.lastName); 47 v.set("GENDER", p.gender, p.gender.empty() ? i_null : i_ok); 48 ind = i_ok; 49 } 50 }; 51} 52 53session sql(oracle, "service=db1 user=scott password=tiger"); 54 55Person p; 56p.id = 1; 57p.lastName = "Smith"; 58p.firstName = "Pat"; 59sql << "insert into person(id, first_name, last_name) " 60 "values(:ID, :FIRST_NAME, :LAST_NAME)", use(p); 61 62Person p1; 63sql << "select * from person", into(p1); 64assert(p1.id == 1); 65assert(p1.firstName + p.lastName == "PatSmith"); 66assert(p1.gender == "unknown"); 67 68p.firstName = "Patricia"; 69sql << "update person set first_name = :FIRST_NAME " 70 "where id = :ID", use(p);
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''