什么是MySQL++?
MySQL++是对MySQL CAPI的再次封装,其目的是使处理SQL像处理STL容器一样顺手,既然是处理STL容器,就是利用容器,迭代器来处理SQL语句和结果集。
下载MySQL++
安装前要准备三样东西:
1.MySQL数据库
2.MySQL CAPI
3.MySQL++
安装数据库
教程略
安装MySQL CAPI
正常来讲,安装MySQL的时候应该是可以选几套api的(如果我没记错),如果单独下载MySQL CAPI,可以去官网,下载下来是这个东西:
这里面有两个重要文件,头文件目录include和链接库文件lib。
MySQL CAPI是可以直接使用的,但是操作比较繁琐,但是可以自己写个类进行封装,下面给个示例:
MySQL——CAPI.h
代码里注释有中文乱码,待会解释,这里不解释capi语句的含义。
#pragma once
#include <winsock.h>
#include<iostream>
#include<mysql.h>
#include<string>
#include<vector>
using namespace std;
using table = vector<vector<string>>;
class MYSQL_CAPI
{
private:
//string host, user, password, databass, port;
MYSQL mysql_id;
public:
MYSQL_CAPI();
~MYSQL_CAPI();
//�������ݿ�
void connect(string host, string user, string password, string database, int port);
//���������
friend ostream& operator<< (ostream& os, table mytable);
//ִ��sql���
table execSql(string sql);
};
ostream& operator<< (ostream& os, table mytable);
MySQL——CAPI.cpp
#include "MYSQL_CAPI.h"
MYSQL_CAPI::MYSQL_CAPI()
{
//�����ʼ��
if (mysql_init(&mysql_id) != NULL) {
cout << "mysql_init() success" << endl;
}
else {
throw "mysql_init() failed";
}
//���ݿ��ʼ��
if (mysql_library_init(0, nullptr, nullptr) == 0) {
cout << "mysql_library_init() success" << endl;
}
else {
throw "mysql_library_init() failed";
}
}
MYSQL_CAPI::~MYSQL_CAPI()
{
//�رշ�����������
mysql_close(&mysql_id);
//��ֹʹ��mysql��
mysql_library_end();
}
void MYSQL_CAPI::connect(string host, string user, string password, string database, int port)
{
if (!mysql_real_connect(&mysql_id, host.c_str(), user.c_str(), password.c_str(), database.c_str(), port, nullptr, 0)) {
throw "mysql_real_connect() failed";
}
else {
cout << "mysql_real_connect() success" << endl;
}
}
table MYSQL_CAPI::execSql(string sql)
{
//ִ��sql���
mysql_real_query(&mysql_id, sql.data(),sql.size());
//��ȡid��Ϣ����ȡ����
int error_no = mysql_errno(&mysql_id);
string error_message = mysql_error(&mysql_id);
if (error_no != 0) {
throw "error_message:" + error_message;
}
table table_result;//������
//����Ƿ��з���ֵ
MYSQL_RES *result = mysql_store_result(&mysql_id);
if (result == nullptr) {
return table();
}
//�з���ֵ���õ��������,����
int col = mysql_num_fields(result);
int row = mysql_num_rows(result);
int i = 0;
while (i < row) {
auto row_result = mysql_fetch_row(result);
table_result.push_back(vector<string>());//��ʼ������
for (int j = 0; j < col; j++) {
table_result.back().push_back(row_result[j]);
}
i++;
}
return table_result;
}
ostream& operator<<(ostream& os, table table_result)
{
for (auto& row : table_result) {
for (auto& col : row) {
os << col << "\t";
}
os << endl;
}
return os;
}
main.cpp
#include"MYSQL_CAPI.h"
int main()
{
while (true) {
try {
MYSQL_CAPI mysql1;
string host = "localhost";
string user = "root";
string password = "123456";
string database = "test";
int port = 3306;
mysql1.connect(host, user, password, database, port);
string sql;
cout << "mySQL>";
getline(cin, sql);
while (sql != "exit") {
table mytable = mysql1.execSql(sql);
cout << "---------------------" << endl;
cout << mytable;
cout << "---------------------" << endl;
getline(cin, sql);
}
}
catch (string e) {
cout << e << endl;
}
}
return 0;
}
执行效果:
下载MySQL++
也是去官网,下载下来是这个东西:
里面最重要的是lib文件,和这三个项目文件。
配置环境
MySQL++是基于MySQL CAPI的,而不是MySQL connector C++
1.找到MySQL++文件夹里,vs2008目录下的工程文件mysql++.sln
2.使用visual studio 2019 运行,更新,会运行报错找不到mysql.h
3.配置MySQL C 的环境变量
4.打开的项目中,第一个运行的是mysqlpp,所以我们只需要配置mysqlpp的环境
所有找不到的东西,都去 MySQL c api 文件里去找,去链接。
5.编译,运行,在同文件夹debug目录下,生成lib和dll文件:
这两个库是使用MySQL++的时候需要的,为了方便使用,我们把它俩加到环境变量里,可以单独拿到一个文件夹,好看一些,我这里不拿了,直接包含Debug文件:
6.新建测试工程:
包含这两个,正常来讲,mysql++的那个文件夹写成include会好看一些,但是不知道为什么,它是以lib文件命名的。
添加附加依赖项:mysqlpp_d.lib
7.正常到这里,你的MySQL++就配置完成了。
给个例子:
MySQL++官网给了两种操作SQL结果集的方式:
1.使用SSQL结构
就是写一个结构体,然后定义一个结构体容器,官方例子:
vector<stock> v;
query << "SELECT * FROM stock";
query.storein(v);
for (vector<stock>::iterator it = v.begin(); it != v.end(); ++it) {
cout << "Price: " << it->price << endl;
}
2.使用STL
官方例子:
vector<mysqlpp::Row> v;
query << "SELECT * FROM stock";
query.storein(v);
for (vector<mysqlpp::Row>::iterator it = v.begin(); it != v.end(); ++it) {
cout << "Price: " << it->at("price") << endl;
}
我个人是倾向于使用MySQL++提供的类操作,也就是第二种。
给个示例:
#include<mysql++.h>
#include<string>
#include<iostream>
#include<wchar.h>
using namespace std;
using namespace mysqlpp;
int main()
{
// 建立连接
string database, host, password, user;
database = "material";
host = "localhost";
password = "123456";
user = "root";
unsigned int port = 3306;
Connection connect(false);
// connect.set_option(new SetCharsetNameOption("utf8"));
if (connect.connect(database.c_str(), host.c_str(), user.c_str(), password.c_str(), port))
{
cout << "connect succeed." << endl;
}
//
Query query = connect.query();
vector<Row> row;
query << "SELECT * FROM p";
query.storein(row);
int i = 0;
for(vector<Row>::iterator it = row.begin(); it != row.end(); it++)
{
cout << it->at(0) << " ";
cout << it->at(1) << " ";
cout << it->at(2) << " ";
cout << it->at(3) << endl;
}
cout << "中文" << endl;
getchar();
return 0;
}
解释突然出现的中文乱码
为什么是突然出现,我以前使用visual studio 2019 的时候,从来没有出现中文乱码的情况,vs的控制台字符集本就是Unicode,对中文兼容性很高。
但是今天操作数据库,竟然中文乱码了…
再加上以前写过的CAPI也没有乱码,所以第一时间想的是,是不是数据库设置问题,查看了字段类型和字符集,以及在MySQL控制台输出测试,都是正常的。
那么我就自然想到是不是MySQL++的问题,简单看一下源码,查看变量,没发现什么不妥,由于MySQL++封装MySQL CAPI,我又怀疑是不是CAPI的问题,但是一看我写的CAPI的例子,就又否定了,因为CAPI封装度并不高,没有改变字符。
然后我就普通cout一下中文,发现竟然是乱码…
安装utf8插件,不行。
更改字符集为多字符集和继承父类,不行。
最后得到结果:
Windows10里面的这个设置问题,勾上之后,乱码解决,但是以前的中文确变成了乱码,从来没有改过这个设置,不知道是不是win10更新的原因。
这个方法会导致以前的中文乱码,并且,会导致一些其他程序的中文乱码,即使是很少数,所以最好不用测试版。