mysql connector c++ 使用_封装MySQL Connector C++以modern c++形式更加简单的操作mysql。

测试代码:

sql_warpper sql_("tcp://127.0.0.1:3306", "root", "407043", "gamed");

bool ret_ = false;

ret_ = sql_.create("create table test (id_ double, name_ varchar(64), password_ varchar(64)); ");

ret_ = sql_.insert("insert into test values(5.12056683, \"humorly\", \"chen123\");");

ret_ = sql_.insert("insert into test values(5.12056684, \"humorly\", \"chen123\");");

ret_ = sql_.insert("insert into test values(5.12056685, \"humorly\", \"chen123\");");

ret_ = sql_.remove("delete from test where id_ = 5.12056684;");

ret_ = sql_.update("update game.test set id_ = 5.55555555 where id_ = 5.12056683;");

// 待搜索的字段信息

std::tuple<:string std::string> params_("id_", "name_", "password_");

std::vector<:tuple std::string>> user_content_;

ret_ = sql_.select("SELECT * FROM test", user_content_, params_);

std::cout << "content:" << std::endl;

for (auto & val : user_content_)

{

std::cout << "id_ = " << std::get<0>(val) << ", ";

std::cout << "name_ = " << std::get<1>(val) << ", ";

std::cout << "password_ = " << std::get<2>(val) << std::endl;

}

return 0;

封装过程:

使用mysql等数据库在查询时无法避免一个问题,在作select操作时,经常要调用mysql对象中的getInt、getString、getByte、getDouble...,并且要将mysql中的sql::ResultSet对象公开(或以接口提供),其中mysql提供的cppconn也没有很好的解决方案。这里做了一番思考,为何不把对象的查询字段做一个tuple封装,传递给查询接口对应的”字段名称“。再做一个tuple传递结果字段的对应类型,并将查询到的“字段值”存储到其中。该过程中对tuple进行展开让编译器去调用getInt、getString、getByte、getDouble...等,代码设计如下:

1:设计一个获取字段值的tuple,必须与select操作需要的字段值对应,用来将其中的“字段名称”传递给getInt等方法作为参数,例如设计搜索表user_content中的"id_", "name_", "password_"(其中id_值类型为int,其他为varchar(string)); 则有展开字段模板:

std::tuple<:string std::string> params_("id_", "name_", "password_");

2:设计一个接收结果的tuple,用来接收表中搜索到的字段类型结果:

std::vector<:tuple std::string>> user_content_;

3:将select语句、content_、parm_传递到展开接口separation中:

bool select(const std::string & command, std::vector<__dest_type> & dest, __set parm)

{

try {

pstmt_ = con_->prepareStatement(command.c_str());

res_ = pstmt_->executeQuery();

res_->afterLast();

while (res_->previous())

{

// 这里进行参数展开

// 将res传入其中,待稍后参数展开时get对应的字段值

separation<__dest_type sql::resultset __set __type params...>(dest, res_, parm);

}

delete res_;

delete pstmt_;

}

catch (sql::SQLException &e) {

std::string str_logger_("sql error by create select -> code is " +

std::to_string(e.getErrorCode()) + " & describe is " + std::string(e.what()));

wstd::log_writer::log_store(str_logger_, __FILE_LINE__);

return false;

}

return true;

}

4:展开过程解释:

std::vector<__dest_type> & separation(std::vector<__dest_type> & dest, __value_type * src, __set parm)

{

__dest_type tu_;

// 获取字段列表parm待展开的参数数目

constexpr int size_ = sizeof...(params);

// 对参数进行递归展开

get_class<0, size_>::template get<__dest_type __value_type __set t params...>(tu_, src, parm);

dest.push_back(tu_);

return dest;

}

5:逐字段赋值过程

template

struct get_class

{

template

inline static void get(__dest & dest, __src * src, __set parm)

{

constexpr integer_type index_ = N + 1;

// 对tuple中的第N个元素赋值

// 右侧通过偏特化dest中的模板参数调用对应的get value方法

std::get(dest) = get_value_type::template get_value(src, std::get(parm).c_str());

// 递归下一字段

get_class::template get<__dest __src __set params...>(dest, src, parm);

}

};

// 递归到末元素时只赋值无需继续递归

// 末元素即为N = M,即偏特化M,M

template

struct get_class

{

template

inline static void get(__dest & dest, __src * src, __set parm)

{

// 末元素赋值

std::get(dest) = get_value_type::template get_value(src, std::get(parm).c_str());

}

};

6:偏特化get value过程:

template

struct get_value_type

{

inline static auto get_value(__dest_type * val, __parm parm) {}

};

// bigint

template

struct get_value_type

{

inline static auto get_value(__dest_type * val, __parm parm) -> decltype(val->getInt64(parm))

{

return val->getInt64(parm);

}

};

// varchar

template

struct get_value_type<:string __dest_type __parm>

{

inline static std::string get_value(__dest_type * val, __parm parm)

{

return val->getString(parm).c_str();

}

};

// 其他类型在这里照例补充偏特化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值