MySQL学习(6)-C++中使用MySQL(2)


0. 前言

为什么上一篇文章鸽了很久才发出来,而且内容没啥干货?

除了最近比较忙之外,还有一个大原因:环境配置把我给卡住了……
在这里插入图片描述
上篇文章讲到要使用C++ Connector,需要有MSVC编译器支持,而且MySQL版本越高,需要的编译器版本也越高:
在这里插入图片描述
我赶紧看了看我的情况:
在这里插入图片描述
8.0.27版本的MySQL需要的至少是MSVC2017(或者MSVC2019),而我只有VS2015,另外又想在Qt中使用,所以要Qt中安装MSVC2017或者MSVC2019编译器

但又不想再装一个VS了,于是找教程一步一步弄。

没想到,这个事情竟然这么多坑!很多的教程,真的是不明白到底是哪里没跟上……

但好在搞来搞去还是摸出来一条路子,在笔者的这篇博客中做了介绍:

Qt 添加MSVC2017编译器(2022年保姆级教程,不安装完整VS)

如果还没有配置好环境,那么建议先配置完了再往下看~


可是,配置好以后,我就声明了个变量,啥还没干就报错

    	try {
            Session sess("127.0.0.1", 33060, "root", "root");
        } catch (const std::exception& e) {
            std::cerr << e.what() << '\n';
        }
CDK Error: Failed string conversion

一开始笔者以为是编译器没安装对,于是把MSVC 2015、MSVC 2017、MSVC 2019都试一试,语句有时也改一改,换成Session的其它构造函数,出的错五花八门

bad allocation
string too long
CDK Error: string conversion error
CDK Error: unexpected message
······

越来越懵笔🖊,跑去官方论坛上扫楼,发现别人也会有类似的问题:

Run Time error: CDK Error: Failed string conversion

mysql-connector-cpp-8.0.20 CDK Error: Failed string conversion

CDK Error: unexpected message

connector 8 Session exception

似乎都没能解决我的问题的样子,于是下了个完整Visual Studio(还是没能逃过这一劫😭😭😭),想着单步调试能救救我,确实有发现一些信息,但对于解决问题基本毫无用处……
在这里插入图片描述

再进到rapidjson里面就看不懂了……

折腾来去,还是不行,又怀疑起版本来,中途甚至跑到这里下了一个8.0.15版本回来,使用MSVC 2015来调试,依旧不管用……
在这里插入图片描述

人已经要疯了😨😨😨,但不愧是我:战术后仰–>冷静下来–>稍加思索–>下定决心之后,决定不把这玩意儿搞出来就倒立洗头,而且配置要是Qt + MSVC 2017 + MySQL 8.0.27

然后又看官方手册,又官方论坛扫楼,一天看到这么一条(其实这条之前看过了😭):

在这里插入图片描述

你是不是使用 debug模式编译的?

将信将疑试了一下release模式,跑了以下代码:

	try {
        Session sess("localhost", 33060, "root", "root");

        auto list = sess.getSchemas();

        for(auto l : list)
        {
            cout<<l.getName() << endl;
        }
    }
    catch (const Error &err)
    {
        cout <<"ERROR: " <<err <<endl;
    }
    catch (std::exception &ex)
    {
        cout <<"STD EXCEPTION: " <<ex.what() <<endl;
    }
    catch (const char *ex)
    {
        cout <<"EXCEPTION: " <<ex <<endl;
    }

运行结果成功打印了服务器上现有的数据库(与控制台语句show DATABASES;一致):
在这里插入图片描述

不说了,人已经麻了。
在这里插入图片描述

发泄得差不多了,含泪进入正题😭。

本文代码主要参考官方文档:X DevAPI User Guide

也可以下载PDF离线看:x-devapi-userguide-en.a4.pdf


系列文章回顾:
MySQL学习(1)-Windows环境安装和配置
MySQL学习(2)-基本概念、数据类型和简单语句
MySQL学习(3)-表格的“改”和“查”
MySQL学习(4)-批量执行SQL语句及导入记录文件
MySQL学习(5)-C++中使用MySQL(1)


1. 工程配置

1.1 基本情况

系列文章采用的MySQL版本为8.0.27,使用的APIMySQL X DevAPI,采用官方的Connector C++提供的头文件和库文件(位于安装目录下的Connector C++ 8.0文件夹内)。

采用的操作系统为Windows 10IDEQt Creator 4.11.1编译器版本MSVC 2017 64bit,编译类型为release

❗️❗️❗️切记,编译类型为Release❗️❗️❗️

项目类型
操作系统Windows 10
MySQL Connector C++版本8.0.27
使用APIX DevAPI
IDEQt Creator 4.11.1
编译器MSVC 2017 64bit
编译类型❗️ Release

1.2 配置

根据官方文档(5.1 Building Connector/C++ Applications: General Considerations),
在这里插入图片描述
要使用X DevAPI,需要:

  1. 添加头文件目录和库文件,Qt工程需要在pro文件中添加如下代码:

    #添加库查找目录,添加lib文件
    LIBS += -L"C:\Program Files\MySQL\Connector C++ 8.0\lib64\vs14" -lmysqlcppconn8
    #添加头文件查找目录
    INCLUDEPATH += "C:\Program Files\MySQL\Connector C++ 8.0\include"
    
    

    如果是Visual Studio开发,则需要在项目上右键–>属性,找到C/C++ -->常规–>附加包含目录,添加上方的include目录;找到链接器–>常规–>附加库目录,添加上方的lib64/vs14目录;找到链接器–>输入–>附加依赖项,添加mysqlcppconn8.lib文件。

    也可以将文件复制到工程目录下,笔者更习惯使用安装目录下的文件这种方式。

  2. lib64目录下的mysqlcppconn8-2-vs14.dll文件复制到生成exe的目录下,此处需要复制该dll到相对源码的路径:..\build-TestMySQL1-Desktop_Qt_5_14_2_MSVC2017_64bit-Release\release

  3. 包含头文件:

    #include <mysqlx/xdevapi.h>
    
  4. 将编译器选择为MSVC 2017 64bitrelease模式:
    在这里插入图片描述

1.3 验证

可以简单使用以下语句测试以下,看是否能在控制台打印出MySQL服务器上所有的数据库(DATABASE):

// main.cpp

#include "mysqlx/xdevapi.h"
#include <iostream>

using namespace mysqlx;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{

    try {
    //	4个参数依次为:服务器地址,X Plugin端口,用户名,密码
        Session sess("localhost", 33060, "root", "root");

        auto list = sess.getSchemas();

        for(auto l : list)
        {
            cout<<l.getName() << endl;
        }
    }
    catch (const Error &err)
    {
        cout <<"ERROR: " <<err <<endl;
    }
    catch (std::exception &ex)
    {
        cout <<"STD EXCEPTION: " <<ex.what() <<endl;
    }
    catch (const char *ex)
    {
        cout <<"EXCEPTION: " <<ex <<endl;
    }

	system("pause");
	return 0;
}

2. 正式学习X DevAPI

2.1 与控制台概念对应的类

将官方文档一路看过来,发现不一定要跟着它一步步来,可以直接看各种类的功能。下图是官方文档中的类图:
在这里插入图片描述
由于我们已经学过控制台对MySQL的操作,可以将上图简单理解为下表:

控制台中的概念API中的类
ClientSession
DATABASESchema
TABLETable
Collection

前三个比较好理解就不再多说,对于Collection,官方的解释是:相同类型的Document被组合在一起,储存在数据库中即为CollectionX DevAPI使用Collection对象存储、获取Document

在这里插入图片描述
看完了这个解释,笔者依旧不太清楚,暂时留着这个问题,看今后的学习中是否能更清晰一些。

另外,根据在控制台上,目前已经学习的操作中,能够操作Session与服务器建立连接,然后拿到各种数据库Schema,再拿到数据库中的Table,对其中的记录进行操作就足够了。

接下来我们一起来看看这些个基本操作吧~

2.2 热身代码

都是些很简单的内容,就不多展开了,直接上代码:

// main.cpp

#include "mysqlx/xdevapi.h"
#include <iostream>

using namespace mysqlx;

using std::cout;
using std::endl;

int main()
{
    try {
//        连接到服务器
       Session sess("localhost", 33060, "root", "root");

//        创建一个叫 test 的数据库,如果已经存在,则获取该数据库
       Schema db = sess.createSchema("test", true);

       Table tbl = db.getTable("students");
       if(!tbl.existsInDatabase())
       {
           cout<<endl<<"表格不存在,创建中……"<<endl;
           sess.sql("USE test;").execute();
           sess.sql("CREATE TABLE students( name VARCHAR(10), age INT, score INT);").execute();
       }

       tbl = db.getTable("students");

//        打印所有数据
       cout<<"\n修改前:"<<endl;
       RowResult res = tbl.select("*").execute();
       for(auto r:res)
       {
           for(unsigned i = 0; i < res.getColumnCount(); ++i)
               cout<<r[i] << '\t';
           cout<<endl;
       }

       cout<<"\n修改中……"<<endl;

       tbl.insert("name", "age", "score").values("Bob", "15", "90").execute();
       tbl.insert("name", "age", "score").values("Peter", "15", "99").execute();
       tbl.insert("name", "age", "score").values("Mary", "13", "100").execute();

       cout<<"\n修改后:"<<endl;
       res = tbl.select("*").execute();
       for(auto r:res)
       {
           for(unsigned i = 0; i < res.getColumnCount(); ++i)
               cout<<r[i] << '\t';
           cout<<endl;
       }

       cout<<"\n删除表格……"<<endl;
       sess.sql("USE test;").execute();
       sess.sql("DROP TABLE students;").execute();
       sess.dropSchema("test");

   }
   catch (const Error &err)
   {
       cout <<"ERROR: " <<err <<endl;
   }
   catch (std::exception &ex)
   {
       cout <<"STD EXCEPTION: " <<ex.what() <<endl;
   }
   catch (const char *ex)
   {
       cout <<"EXCEPTION: " <<ex <<endl;
   }
}



代码的输出结果:
在这里插入图片描述
稍微总结一下API的用法:

  1. Session类似于客户端,用来连接MySQL服务器的,而且创建对象后,参数正确就能直接连上服务器不需要调用其它函数

    比较方便的创建对象方法是: Session se(host, port, user, password);

  2. Schema类似于数据库(DATABASE),通过Session::getSchema(name)获取数据库对象,也可以createSchema()、dropSchema()创建、删除数据库对象;
  3. Table表格,通过Schema::getTable(name)获取表格对象,X DevAPI没有提供表格的创建和删除接口,但可以通过下一条实现;
  4. 从上述源码来看,大部分对表格记录的操作,都需要接上execute()函数才会被执行;事实上,如果语句的返回类型Executable对象,则需要调用其execute()函数以执行;
  5. 可以通过Session::sql(sqlStatement)来执行SQL语句,这提供了极大的灵活性,不过似乎对大家的SQL语法基础提出了挑战

本文就先学到这里~感觉也够大家操作一会儿的了👻


3. 总结

  1. 使用X DevAPI,需要包含Connector的头文件,链接对应lib文件,并将dll文件复制到exe目录下;
  2. 如果是默认安装的Connector C++,需要采用release模式编译;
  3. X DevAPI的几个类:Session、Schema、Table分别可以和控制台的客户端、DATABASETABLE对应上
  4. 可以通过API函数创建、删除数据库createSchema(name)dropSchema(name)),但没有函数直接创建、删除表格;
  5. Session::sql()函数可以生成SQL语句,再调用Executable::execute()函数执行语句;

如有错误欢迎指正,共同进步~


今天你学废了吗?

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值