🌠 作者:@阿亮joy.
🎆专栏:《零基础入门MySQL》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
目录
- 👉mysql connect👈
- 连接库的下载
- 验证是否引入成功
- mysql 接口介绍
- 综合代码
- 👉总结👈
👉mysql connect👈
连接库的下载
学习 MySQL 的命令行,只是让我们熟悉 MySQL 的命令。在实际工作和项目开发中,我们都是使用封装好的库来连接和访问 MySQL 数据库的。
要使用 C 语言连接 MySQL,需要使用 MySQL官网提供的库,大家可以去官网下载。
下载完之后,上传到 Linux 服务器上,然后解压就行了。
[root@VM-12-10-centos mysql-connector]# ll
total 68
drwxrwxr-x 2 Joy Joy 4096 Jul 24 13:54 bin
-rw-r--r-- 1 Joy Joy 17987 Jul 13 2017 COPYING
drwxrwxr-x 2 Joy Joy 4096 Jul 24 13:54 docs
drwxrwxr-x 3 Joy Joy 4096 Jul 24 13:54 include
drwxrwxr-x 2 Joy Joy 4096 Jul 24 13:54 lib
-rw-r--r-- 1 Joy Joy 30906 Jul 13 2017 README
[root@VM-12-10-centos mysql-connector]# ll lib/
total 23916
-rw-r--r-- 1 Joy Joy 15948896 Jul 13 2017 libmysqlclient.a
lrwxrwxrwx 1 Joy Joy 20 Jul 13 2017 libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx 1 Joy Joy 23 Jul 13 2017 libmysqlclient.so.18 -> libmysqlclient.so.18.4.
-rwxr-xr-x 1 Joy Joy 8538815 Jul 13 2017 libmysqlclient.so.18.4.
其中 include 目录下包含了所有的方法声明, lib 目录下包含所有的方法实现(打包成库)。然后再将头文件和库文件拷贝到系统目录下就完成安装了。
但是,我们在安装 MySQL 服务时,就已经把 MySQL 的开发包安装好了,也会自动地将头文件和库文件拷贝到系统目录下。
[root@VM-12-10-centos mysql-connector]# rpm -qa | grep mysql
mysql57-community-release-el7-11.noarch
mysql-community-client-5.7.41-1.el7.x86_64
mysql-community-libs-5.7.41-1.el7.x86_64
mysql-community-common-5.7.41-1.el7.x86_64
mysql-community-server-5.7.41-1.el7.x86_64
mysql-community-devel-5.7.43-1.el7.x86_6 ## 开发包
## 如果发现自己没有开发包,可以使用下面的命令进行下载
yum install -y mysql-community-devel
## 查看系统目录下的头文件和库文件
[root@VM-12-10-centos mysql-connector]# ls /usr/include/mysql/
big_endian.h my_byteorder.h mysql_com.h my_sys.h sql_state.h
binary_log_types.h my_command.h mysql_com_server.h my_thread.h sslopt-case.h
byte_order_generic.h my_compiler.h mysqld_ername.h my_thread_local.h sslopt-longopts.h
byte_order_generic_x86.h my_config.h mysqld_error.h my_xml.h sslopt-vars.h
decimal.h my_config_x86_64.h mysql_embed.h plugin_audit.h thr_cond.h
errmsg.h my_dbug.h mysql.h plugin_ftparser.h thr_mutex.h
keycache.h my_dir.h mysql_time.h plugin_group_replication.h thr_rwlock.h
little_endian.h my_getopt.h mysql_version.h plugin.h typelib.h
m_ctype.h my_global.h mysqlx_ername.h plugin_keyring.h
m_string.h my_list.h mysqlx_error.h plugin_validate_password.h
my_alloc.h mysql mysqlx_version.h sql_common.h
[root@VM-12-10-centos mysql-connector]# ls /usr/lib64/mysql/
libmysqlclient.a libmysqlclient.so.20 libmysqlservices.a plugin
libmysqlclient.so libmysqlclient.so.20.3.28 mecab
验证是否引入成功
通过 mysql_get_client_info 函数,来验证我们的引入是否成功。
#include <iostream>
#include <mysql/mysql.h>
using namespace std;
int main()
{
cout << "MySQL Client Version:" << mysql_get_client_info() << endl;
return 0;
}
因为我们的连接库所在的路径没有导入到系统的环境变量中,所以我们要通过 -L 选项和 -l 选项来告知编译器库文件所在的路径和所要链接的库。
Makefile
# -L:指明库文件的所在路径
# -l:指明所要链接的库
mysqlClient:mysqlClient.cc
g++ $@ $^ -o -std=c++11 -L/lib64/mysql -lmysqlclient
.PHONY:clean
clean:
rm -rf mysqlClient
mysql 接口介绍
初始化 mysql_init
要使用库,必须先进行初始化。mysql_init 函数会给我们返回一个 MYSQL 句柄,我们后续的操作都需要通过这个 MYSQL 句柄来完成。使用方法如下:
MYSQL *m= mysql_init(nullptr);
连接数据库 mysql_real_connect
初始化完毕之后,必须先连接数据库,才能进行后续操作。(mysql网络部分是基于 TCP/IP 的)。
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 clientflag);
// 建立好链接之后,获取英文没有问题,如果获取中文是乱码:
// 设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");
第一个参数 MYSQL 是 C API中一个非常重要的变量(mysql_init 的返回值),里面内容非常丰富,有 port、dbname、charset 等连接基本参数。它也包含了一个叫 st_mysql_methods 的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect 函数中各参数,基本都是顾名思意,不进行过多的介绍。
关闭 mysql 连接 mysql_close
void mysql_close(MYSQL *sock);
使用完数据库后,需要关闭 mysql 连接,否则会造成内存泄露。
下发 mysql 命令 mysql_query
int mysql_query(MYSQL *mysql, const char *q);
第一个参数上面已经介绍过,第二个参数为要执行的 sql 语句,如:“select * from table”。调用成功的返回值为 0,否则为 1。
获取执行结果 mysql_store_result
sql 执行完以后,如果是查询语句,我们当然还要读取数据。如果 update、insert 等语句,那么就看下操作成功与否即可。那我们来看看如何获取查询结果,如果 mysql_query 返回成功,那么我们就通过 mysql_store_result 这个函数来读取结果。原型如下:
MYSQL_RES *mysql_store_result(MYSQL *mysql);
该函数会调用 MYSQL 变量中的 st_mysql_methods 中的 read_rows 函数指针来获取查询的结果。同时该函数会返回 MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数 malloc 了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。 执行完 mysql_store_result 以后,其实数据都已经在 MYSQL_RES 变量中了,下面的 API 基本就是读取 MYSQL_RES 中的数据。
获取结果行数 mysql_num_rows
my_ulonglong mysql_num_rows(MYSQL_RES *res);
获取结果列数 mysql_num_fields
unsigned int mysql_num_fields(MYSQL_RES *res);
获取列名 mysql_fetch_fields
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
如:
int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
int i = 0;
for (; i < fields; i++)
{
cout << field[i].name << " ";
}
cout << endl;
获取结果内容 mysql_fetch_row
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
它会返回一个 MYSQL_ROW 变量,MYSQL_ROW 其实就是 char **,可以当成一个二维数组来使用。
MYSQL_ROW line;
for (int i = 0; i < rows; i++)
{
line = mysql_fetch_row(res);
for (int j = 0; j < fields; j++)
{
cout << line[j] << " ";
}
cout << endl;
}
另外,mysql C API 还支持事务等常用操作,大家自行了解。
综合代码
获取 select 的结果
#include <iostream>
#include <string>
#include <cstdlib>
#include <mysql/mysql.h>
#include <iomanip>
using namespace std;
string User = "Test";
string Host = "127.0.0.1"; // "localhost"
string Password = "123456";
string Database = "my_db";
unsigned int Port = 8888;
int main()
{
// 初始化 MYSQL 对象
MYSQL *m = mysql_init(nullptr);
if (m == nullptr)
{
cerr << "mysql_init error" << endl;
exit(1);
}
// 连接数据库
if (mysql_real_connect(m, Host.c_str(), User.c_str(), Password.c_str(), Database.c_str(), Port, nullptr, 0) == nullptr)
{
cerr << "mysql_real_connect error" << endl;
exit(2);
}
// 将 mysql 连接的字符集设置为 utf8
// 如果没有设置, 有中文将会出现乱码
mysql_set_character_set(m, "utf8");
cout << "mysql_real_connect success" << endl;
// SQL 可以从网络中来,那样就可以将用户的数据存储起来
// 增删改的 SQL 语句:执行完就可以了
// 而查的 SQL 语句:执行完还有读取结果
string insertSql = "insert into emp values (2, '张三', 8888)";
string deleteSql = "delete from emp where id=2";
string updateSql = "update emp set sal=9999 where name='张三'";
string selectSql = "select * from emp";
int n = mysql_query(m, selectSql.c_str());
// 查看执行结果: 0 表示执行成功, 1 表示执行失败
if (n == 0)
{
// 获取结果并对结果进行解析
MYSQL_RES* res = mysql_store_result(m);
if(res == nullptr) exit(3);
int rows = mysql_num_rows(res);
int fields = mysql_num_fields(res);
MYSQL_FIELD* fieldName = mysql_fetch_fields(res);
for(int j = 0; j < fields; ++j)
{
// 格式控制
cout << std::setw(10) << std::left;
cout << fieldName[j].name;
}
cout << endl;
MYSQL_ROW line;
for(int i = 0; i < rows; ++i)
{
// 按行获取结果内容, 获取完会自动移动到下一行
line = mysql_fetch_row(res);
for(int j = 0; j < fields; ++j)
{
cout << std::setw(10) << std::left;
cout << line[j];
}
cout << endl;
}
// 释放内存
mysql_free_result(res);
}
// 关闭 mysql 连接
mysql_close(m);
return 0;
}
简易版 mysql 客户端的实现
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <mysql/mysql.h>
using namespace std;
string User = "Test";
string Host = "127.0.0.1"; // "localhost"
string Password = "123456";
string Database = "my_db";
unsigned int Port = 8888;
int main()
{
// 初始化 MYSQL 对象
MYSQL *m = mysql_init(nullptr);
if (m == nullptr)
{
cerr << "mysql_init error" << endl;
exit(1);
}
// 连接数据库
if (mysql_real_connect(m, Host.c_str(), User.c_str(), Password.c_str(), Database.c_str(), Port, nullptr, 0) == nullptr)
{
cerr << "mysql_real_connect error" << endl;
exit(2);
}
// 将 mysql 连接的字符集设置为 utf8
// 如果没有设置, 有中文将会出现乱码
mysql_set_character_set(m, "utf8");
cout << "mysql_real_connect success" << endl << endl;
char sql[1024];
while (true)
{
cout << "mysql> ";
fgets(sql, sizeof sql, stdin);
sql[strlen(sql) - 1] = '\0'; // 去掉 '\n'
int n = mysql_query(m, sql);
// 查看执行结果: 0 表示执行成功, 1 表示执行失败
if (n == 0)
{
if (strcasestr(sql, "select"))
{
// 获取结果并对结果进行解析
MYSQL_RES *res = mysql_store_result(m);
if (res == nullptr)
exit(3);
int rows = mysql_num_rows(res);
int fields = mysql_num_fields(res);
MYSQL_FIELD *fieldName = mysql_fetch_fields(res);
for (int j = 0; j < fields; ++j)
{
// 格式控制
cout << std::setw(10) << std::left;
cout << fieldName[j].name;
}
cout << endl;
MYSQL_ROW line;
for (int i = 0; i < rows; ++i)
{
// 按行获取结果内容, 获取完会自动移动到下一行
line = mysql_fetch_row(res);
for (int j = 0; j < fields; ++j)
{
cout << std::setw(10) << std::left;
cout << line[j];
}
cout << endl;
}
cout << endl;
// 释放内存
mysql_free_result(res);
}
else
{
printf("execute %s success\n\n", sql);
}
}
else
{
printf("execute %s fail\n\n", sql);
}
}
// 关闭 mysql 连接
mysql_close(m);
return 0;
}
👉总结👈
本篇博客主要讲解了 mysql 连接库的下载和安装、mysql 接口介绍以及实现了简易版的 mysql 客户端等等。以上就是本篇博客的全部内容,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家啦!💖💝❣️