目录

​前言​

​Connector C++ 使用​

​创建项目和配置​

​代码编写​

​使用中会遇到的问题​

​1.返回的结果中文乱码问题:​

​2,插入数据时出现Incorrect string value: '\xC0\xAD\xC0\xAD' for column 'user_name' at row 1,数据库无法识别的字符串错误​

​3、使用C++获取系统时间并存进Mysql中DateTime类型的字段​




前言

一、依赖:MySQL Connector/C++需要安装配置boost库

MySQL Connector/C++需要安装配置boost库,boost库安装编译​

二、简介

应用程序要想访问数据库,必须使用数据库提供的编程接口。目前业界广泛被使用的API标准有ODBC和JDBC。

ODBC是由微软提出的访问关系型数据库的C程序接口。

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。

MySQL实现了三种Connector用于C/C++ 客户端程序来访问MySQL服务器:Connector/ODBC, Connector/C++(JDBC)以及Connector/C(libmysqlclient)。

MySQL C++ Driver的实现基于JDBC规范

MySQL Connector/C++是由Sun Microsystems开发的MySQL连接器。它提供了基于OO的编程接口与数据库驱动来操作MySQL服务器。

与许多其他现存的C++接口实现不同,Connector/C++遵循了JDBC规范。也就是说,Connector/C++ Driver的API主要是基于Java语言的JDBC接口。JDBC是java语言与各种数据库连接的标准工业接口。

Connector/C++实现了大部分JDBC规范。如果C++程序的开发者很熟悉JDBC编程,将很快的入门。

Connector C++ 使用

 

参考:静态库和动态库使用方法​

3.4 静态库和动态库:

​动态库与静态库优缺点比较​

接着根据我们的需要,执行后续步骤:

如果用静态库,可能比较麻烦,因为静态库需要和编译器版本相匹配,因此需要手动编译一份,所以此次选择动态库。

动态库:创建项目和配置

 

1、新建一个空项目

2、将D:\Program Files\MySQL\Connector C++ 1.1.3\include添加到项目的包含目录中(根据具体路径而定)

【mySQL】C++操作mySql数据库(Mysql connector c++)_sql

 

3、将D:\boost\boost_1_55_0添加到项目的包含目录中(根据具体路径而定)

【mySQL】C++操作mySql数据库(Mysql connector c++)_数据库_02

 

4、将D:\Program Files\MySQL\Connector C++ 1.1.3\lib\opt添加到项目的库目录中(根据具体路径而定)

【mySQL】C++操作mySql数据库(Mysql connector c++)_数据库_03

 

5、添加mysqlcppconn.lib至附加依赖项中 

【mySQL】C++操作mySql数据库(Mysql connector c++)_mysql_04

 

6、如果使用的mysql是64位的,还需要将项目的解决方案平台由win32改成x64

【mySQL】C++操作mySql数据库(Mysql connector c++)_mysql_05

7、将D:\Program Files\MySQL\Connector C++ 1.1.3\lib\opt(根据具体路径而定)下的mysqlcppconn.dll复制到项目中去,和.cpp,.h文件位于同一路径下

      将D:\Program Files\MySQL\MySQL Server 5.6\lib(根据具体路径而定)下的libmysql.dll复制到项目中去,和.cpp,.h文件位于同一路径下

 

 

至此,相关配置全部完成

代码编写

 

6、程序引入头文件

#include "jdbc/mysql_connection.h"
#include "jdbc/mysql_driver.h"
#include "jdbc/cppconn/statement.h"

7、连接数据库

   //初始化驱动
sql::mysql::MySQL_Driver *driver = NULL;
sql::Connection *con = NULL;
driver = sql::mysql::get_mysql_driver_instance();
if (driver == NULL)
{
cout << "driver is null" << endl;
}
con = driver->connect("tcp://localhost:3306", "root", "root");
if (con == NULL)
{
cout << "conn is null" << endl;
}
cout << "connect suceess" << endl;

8、程序使用mysql版本为mysql-5.6.24-win32,完整的代码如下:

#include "iostream"
#include "jdbc/mysql_connection.h"
#include "jdbc/mysql_driver.h"
#include "jdbc/cppconn/statement.h"
#include "jdbc/cppconn/prepared_statement.h"

using namespace std;
using namespace sql;
int main()
{
//初始化驱动
sql::mysql::MySQL_Driver *driver = NULL;
sql::Connection *conn = NULL;
driver = sql::mysql::get_mysql_driver_instance();
if (driver == NULL)
{
cout << "driver is null" << endl;
}
//连接
//con = driver->connect("tcp://localhost:3306", "root", "root");
conn = driver->connect("tcp://localhost:3306/ourcms", "root", "root");
if (conn == NULL)
{
cout << "conn is null" << endl;
}
cout << "connect suceess" << endl;
//查询
int flag = 0;
sql::Statement *stmt = conn->createStatement();
sql::ResultSet *res;
res = stmt->executeQuery("SELECT * FROM cms_device");
while (res->next())
{
cout << res->getInt("id") << endl;
cout << res->getString("phone").c_str() << endl;
cout << res->getString("imsi").c_str() << endl;
}
//插入
conn->setAutoCommit(0);//关闭自动提交
PreparedStatement *prep_stmt;
int updatecount = 0;
res->first();
flag = 0;
while (res->next())
{
if (strcmp(res->getString("imsi").c_str(), "460010010000100") == 0)
{
flag = 1;
break;
}
}
if (flag == 0) {
prep_stmt = conn->prepareStatement("INSERT INTO cms_device (id,phone,imsi) VALUES (111,?,?)");
prep_stmt->setString(1, "15043214321");
prep_stmt->setString(2, "460010010000100");
updatecount = prep_stmt->executeUpdate();
}
Savepoint *savept;
savept = conn->setSavepoint("SAVEPT1");
res->first();
flag = 0;
while (res->next())
{
if (strcmp(res->getString("imsi").c_str(), "460010010000101") == 0)
{
flag = 1;
break;
}
}
if (flag == 0) {
prep_stmt = conn->prepareStatement("INSERT INTO cms_device (phone,imsi) VALUES (?,?)");
prep_stmt->setString(1, "15043214321");
prep_stmt->setString(2, "460010010000101");
updatecount = prep_stmt->executeUpdate();
}
conn->rollback(savept);
conn->releaseSavepoint(savept);
conn->commit();
//更新
conn->setAutoCommit(1);//打开自动提交
prep_stmt = conn->prepareStatement("update cms_device set phone=? where phone=?");
prep_stmt->setString(1, "15011111111");
prep_stmt->setString(2, "15043214321");
updatecount = prep_stmt->executeUpdate();
}


程序代码

main.cpp

#include <iostream>
#include <map>
#include <string>
#include <memory>
#include "mysql_driver.h"
#include "mysql_connection.h"
#include "cppconn/driver.h"
#include "cppconn/statement.h"
#include "cppconn/prepared_statement.h"
#include "cppconn/metadata.h"
#include "cppconn/exception.h"

using namespace std;
using namespace sql;

int main()
{
sql::mysql::MySQL_Driver *driver = 0;
sql::Connection *conn = 0;

try
{
driver = sql::mysql::get_mysql_driver_instance();
conn = driver->connect("tcp://localhost:3306/booktik", "root", "123456");
cout << "连接成功" << endl;
}
catch (...)
{
cout << "连接失败" << endl;
}
sql::Statement* stat = conn->createStatement();
stat->execute("set names 'gbk'");
ResultSet *res;
res = stat->executeQuery("SELECT * FROM BOOK");
while (res->next())
{
cout << "BOOKNAME:" << res->getString("bookname") << endl;
cout << " SIZE:" << res->getString("size") << endl;
}
if (conn != 0)
{
delete conn;
}
system("pause");
}

运行结果

【mySQL】C++操作mySql数据库(Mysql connector c++)_数据库_06

 

使用中会遇到的问题

 

1.返回的结果中文乱码问题:

    安装好了boost库和Mysql connector c++ 1.1.3库后,我们配置好工程的属性,就能使用通过sql::Connection::createStatement(),方法创建的sql::Statement*对象,对数据库进行操作,但是如果你数据库中的编码是utf8或者其他支持中文的编码,那么你必需要在执行sql查询语句之前,执行这么一句代码:m_sqlStatement->execute("set names 'gbk'");这里的m_sqlStatement是一个sql::Statement*对象。这样你在执行查询语句,例如:m_sqlStatement->executeQuery("select * from userinfo_tbl"),就不会出现中文乱码了。

2,插入数据时出现Incorrect string value: '\xC0\xAD\xC0\xAD' for column 'user_name' at row 1,数据库无法识别的字符串错误

    原因和上面差不多,是程序中对数据库进行操作的对象中使用的字符编码和数据库中的字符编码不一致所导致的,可以想象一下,我们编程时是通过Mysql connector c++ 1.1.3库中提供的对象对数据库进行操作,对数据库的一切操作都是由这些我们实例化出来的对象来完成,但是如果我们创建的对象的字符编码和数据库的编码不一样,那么数据库就无法识别对象想要存到数据库中的字符到底是啥,由于无法识别,数据库自然不会让你插入进去。解决方法和上面一样,在执行插入语句之前,创建一个sql::Statement*对象,执行m_sqlStatement->execute("set names 'gbk'"),这里的m_sqlStatement是一个sql::Statement*对象。无论是使用sql::PreparedStatement*还是使用sql::Statement*对数据库进行操作,基本都要执行这么一句,设置对象使用的编码。可能你们会奇怪为什么不是把编码设置成utf8而是设置成gbk,这个我也不知道,但是我试过了,数据库编码为utf8时,我执行了m_sqlStatement->execute("set names 'utf8'")代替上面的,但是还是会有乱码,只有设置成gbk时才不会乱码,至于为什么我也不太清楚,总之,先用起来再说。

3、使用C++获取系统时间并存进Mysql中DateTime类型的字段

无论是C++库函数还是Mysql connector c++ 1.1.3库中都没有提供DateTime这个数据类型,那么想要将Mysql中的DateTime类型读进C++的类型中,就必须要转换类型,最方便的方法是将DateTime装换成“2018-07-15 22:11:54”这样格式的字符串,存的时候按照字符串的格式存储,取得时候也按照字符串的格式取,具体代码如下:

从查询结果集中取出DateTime的数据:

rlt = statement->executeQuery("select * from userinfo_tbl");//statement是sql::Statement*类型对象
while (rlt->next())
{
std::cout << " user_name:" << rlt->getString("user_name");
std::cout << " user_pwd:" << rlt->getString("user_pwd");
std::cout << " user_email:" << rlt->getString("user_email");
std::cout << " user_update:" << rlt->getString("user_update") << std::endl; //user_update字段是DateTime类型的字段,

}

输出格式如下:

c++获取系统时间存进Mysql中 DateTime类型字段

做法如下:

try
{
CTime nowtime = CTime::GetCurrentTime();//获取系统当前时间#include<atltime.h>
CString tstr = nowtime.Format("%Y-%m-%d %H:%M:%S");//格式化时间,将时间格式化成和数据库中格式一样的字符串
std::cout << tstr << std::endl;
sql::PreparedStatement* preStatement = jdbc.getPreStatement("INSERT INTO userinfo_tbl VALUES('拉拉','147258','dhfj@qq.com',?)");
preStatement->setString(1, tstr.GetString());
preStatement->executeUpdate();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}

这样就能获取系统系统间并将时间存进数据库了。

以上说法纯粹个人摸索理解出来的,有理解不正常或者其他纰漏之处还请大家海涵,用这个套工具开发服务器的人应该不多,遇到问题也是让人蛋疼,分享一下个人经验,还望能帮到有需要之人。

————————————————

查询数据

#include <iostream>
#include "mysql_driver.h"
#include "mysql_connection.h"
#include "cppconn/driver.h"
#include "cppconn/statement.h"
#include "cppconn/prepared_statement.h"
#include "cppconn/metadata.h"
#include "cppconn/exception.h"

int main() {
const char* user = "root";
const char* passwd = "";
const char* host = "tcp://localhost:3306";
const char* database = "test";
try {
sql::mysql::MySQL_Driver* driver =
sql::mysql::get_mysql_driver_instance();
sql::Connection* conn = driver->connect(host, user, passwd);
conn->setSchema(database);
std::cout << "status: " << conn->isClosed() << std::endl;
sql::Statement *stmt = conn->createStatement();
sql::ResultSet *res = stmt->executeQuery("select 1;");
while (res->next()) {
std::cout << res->getInt(1) << std::endl;
}

res = stmt->executeQuery("select * from pet;");
while (res->next()) {
std::cout << res->getString(1) << ",";
std::cout << res->getString(2) << ",";
std::cout << res->getString(3) << ",";
std::cout << res->getInt(4) << ",";
std::cout << res->getString(5) << ",";
std::cout << res->getString(6) << std::endl;
}

delete res;
delete stmt;
delete conn;
} catch (sql::SQLException& e) {
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << std::endl;
std::cout << "# ERR: " << e.what();
std::cout << " (MySQL error code: " << e.getErrorCode();
std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
}
return 0;
}

#include <iostream>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <mysql_driver.h>
using namespace sql;
using namespace std;

class BookInfor {
public:
string name;
string writer;
string img;
string price;
};


class Mysql {
public:
mysql::MySQL_Driver *driver;
Connection *con;
Statement *state;
ResultSet *result;
PreparedStatement *prep_stmt;

Mysql()//构造函数
{
driver = sql::mysql::get_mysql_driver_instance();
// 建立链接
con = driver->connect("tcp://127.0.0.1:3307", "root", "root");
state = con->createStatement();
state->execute("use book_infor");
}

void query()//查询
{
// 查询
result = state->executeQuery("select * from book");
// 输出查询
while (result->next())
{
int id = result->getInt("id");
//string img = result->getString("bookname");
cout << id << endl;
}

}

int insert(BookInfor book)//插入
{
bool retstatus = state->execute("INSERT INTO book (bookname,imgpath) VALUES ('Napier', 'New Zealand')");
if (!retstatus)
{
return state->getUpdateCount();
}
else
{
return 0;
}
}

int prepare_insert(BookInfor book)
{
prep_stmt = con->prepareStatement("INSERT INTO book (name,img,price,writer) VALUES (?,?,?,?)");
prep_stmt->setString(1, book.name);
prep_stmt->setString(2, book.img);
prep_stmt->setString(3, book.price);
prep_stmt->setString(4, book.writer);
bool updatecount = prep_stmt->executeUpdate();
if (!updatecount)
{
return state->getUpdateCount();
}
else
{
return 0;
}
}

~Mysql()//析构函数
{
delete state;
delete con;
}



};

/*
int main()
{
BookInfor book;
book.img = "dd";
book.writer = "dd";
book.name = "dd";
book.price = "dd";
Mysql m;
m.prepare_insert(book);
}
*/