MySQL Connection
连接数据库的客户端除了命令行式的还有图形化界面版本,网页版本,当然也包括语言级别的库或者是包,能够帮助我们直接连接数据库;
一、语言连接库下载
方式一:不建议使用,需要自己配置环境变量,或者将库文件和头文件添加到系统路径之下;
使用语言连接数据库需要注意安装相关的开发库;
网址:https://www.mysql.com/,然后去downloads选中MySQL Community Downloads;
下载连接库Connector/C++ 8.0,找到对应的版本;
方式二:进行安装yum源,然后在进行下载并安装连接库;
sudo yum install -y mysql-devel
二、使用C/C++访问数据库
2.1MySQL库中的常用数据结构
MYSQL:这个结构主要用于数据库的连接;
MYSQL_RES:这个结构主要用于保存读取结果,以行为单位,用于MYSQL的查询结果转储;
MYSQL_ROW:这个结构主要用于获取转储中的一行数据记录,是一个二维数组;
MYSQL_FIELD:这个结构主要用于获取转储中的相关列属性,是一个结构化的数据类型;
2.2MySQL常用接口
1.使用MySQL必须先进行初始化,初始化一些数据结构;
MYSQL *mysql_init(MYSQL *mysql);
//MYSQL*就相当于C语言中的FILE*和系统的fd文件描述符,用来描述MySQL客户端相关的资源;也可以称之为句柄
2.使用MySQL前需要进行连接MySQL;
MYSQL *
mysql_real_connect(MYSQL *mysql,
const char *host,
const char *user,
const char *passwd,
const char *db,
unsigned int port,
const char *unix_socket,
unsigned long client_flag);
3.修改MySQL字符集
需要注意连接之后的编码集默认是latin1;
int mysql_set_character_set(MYSQL *mysql,
const char *csname);
4.向MySQL中发送SQL语句;
对于增删改,只需要执行sql即可,但是select需要进行后续操作,将数据提交到上层;
还需要注意字符集,防止乱码;
int mysql_query(MYSQL *mysql,
const char *stmt_str)//0表示成功,非零表示失败;
5.当不使用了,需要关闭MYSQL*句柄;
void mysql_close(MYSQL*mysql);
2.3C/C++查询的处理细节
当查询完成之后,会将查询结果存放到句柄当中;此时就需要将查询结果提取出来,从句柄当中格式化提取到MYSQL_RES中,进行转储,便于进行二次处理;
MYSQL_RES *mysql_store_result(MYSQL *mysql);
//需要注意的是,该函数会malloc一段空间,所以一定要记得进行free,否则就会造成内存泄露;
void mysql_free_result(MYSQL_RES *result);//使用此函数进行释放内存空间;
MySQL中存储的表结构,实际上是存储了两种内容,一种是列属性名,一种是数据内容;当提取表中的记录时,就不会考虑约束了,而是i直接提取出来字符串;
可以将MYSQL_RES结构看作一个char** array[]的结构,其中的一个数组会被当作一行记录,每一条记录由不同的列构成,不同的列是一个字符串;这样既可以按照行读取,也可以按照列进行读取;
为了便于遍历,需要获取行数和列数,就需要用到以下接口实现;
unsigned int mysql_num_fields(MYSQL_RES *result);//返回列数
my_ulonglong mysql_num_rows(MYSQL_RES *result);//返回行数,此时的行数表示的是数据内容,不包括列名称;
直接获取一行的结果;再重复使用下列函数的过程当中,会自动遍历到下一行;
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);//返回值本质上就是一个char**也就是一个二维数组;
获取列名使用如下接口;
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)//一次性获取所有的列;
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)//一个一个的获取,并每次使用会自动下后一个迭代;
示例
#include <iostream>
#include <mysql/mysql.h>
#include <unistd.h>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;
const string host = "localhost";
const string user = "user_for_C";
const string password = "dyh15343510133.";
const string database = "for_comm_user_C";
const unsigned int port = 8080;
int main()
{
// MYSQL对象初始化
MYSQL *my = mysql_init(nullptr);
if (my == nullptr)
{
cerr << "init mysql error" << endl;
return 1;
}
// 连接MYSQL
if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), database.c_str(), port, nullptr, 0) == nullptr)
{
cerr << "connect mysql error" << endl;
return 2;
}
cout << "connect mysql success" << endl;
if (mysql_set_character_set(my, "utf8"))
{
cerr << "设置字符集失败" << endl;
return 3;
}
// 发送SQL语句
string sql = "select * from user";
if (mysql_query(my, sql.c_str()))
{
cerr << "query error" << endl;
}
else
{
cout << "query success" << endl;
}
// 获取查询结果
MYSQL_RES *myres = mysql_store_result(my);
if (nullptr == myres)
{
cerr << "mysql_store_result error" << endl;
return 4;
}
int rows = mysql_num_rows(myres);
int columns = mysql_num_fields(myres);
cout << "行数:" << rows << ",列数:" << columns << endl;
// 表的属性
MYSQL_FIELD *fields = mysql_fetch_fields(myres);
for (int i = 0; i < columns; i++)
{
cout << fields[i].name << "\t\t";
}
cout << endl;
// 表的内容
for (int i = 0; i < rows; i++)
{
MYSQL_ROW row = mysql_fetch_row(myres);
for (int j = 0; j < columns; j++)
{
cout << row[j] << "\t\t";
}
cout << endl;
}
// string sql;
// while (true)
// {
// cout << "mysql>>>";
// if (!std::getline(cin, sql) || sql == "quit")
// {
// cout << "Bye" << endl;
// break;
// }
// int n = mysql_query(my, sql.c_str());
// if (n == 0)
// {
// cout << sql << " success: " << n << endl;
// }
// else
// {
// cerr << sql << " error: " << n << endl;
// }
// }
// 释放结果集
mysql_free_result(myres);
// MYSQL对象关闭
mysql_close(my);
return 0;
}
三、图形化界面连接数据库
如Navicat就是使用体验较好的一个图形化界面,但是是一个收费的方案;还有一款是MySQL Workbench,是官方提供的一种图形化界面方案,是一种免费的方案;