文章目录
- 1.访问数据库
 - 2.vscode-c-api客户端
 - 方法一:重新安装相关数据
 - 方法二:直接使用之间安装mysql的附加数据
 - 查看mysql文档方式
 - 使用c-mysql-api库访问mysqld
 - 代码
 - 理解mysql_res
 
- 3.图形化界面
 
1.访问数据库
命令行式客户端向mysqld下达指令
 网页版
 图形化界面
 语言级别的库/包
mysql的基础,我们之前已经学过,后面我们只关心使用。要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载。我们使用C接口库来进行连接。要正确使用,我们需要做一些准备工作:
- 保证mysql服务有效
 - 在官网上下载合适自己平台的mysql connect库,以备后用。其中include 包含所有的方法声明,lib 包含所有的方法实现(打包成库)。
 - 要使用库,必须先进行初始化!
 - 初始化完毕之后,必须先链接数据库,在进行后续操作。(mysql网络部分是基于TCP/IP的)。第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有
port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量
里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
mysql_real_connect函数中各参数,基本都是顾名思意。 
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);
 
- 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 中的数据。 
2.vscode-c-api客户端
方法一:重新安装相关数据


 
 
安装成功样例

方法二:直接使用之间安装mysql的附加数据
之前我们在安装mysql时 sudo yum install -y mysql-community-server 通过yum源安装mysql社区服务器 实际上他不止帮我们安装了服务器 还安装了客户端和各种开发包(devl)
 
 
 
理应你下载了mysql,就应该有上面的,如果没有:
sudo yum install -y mysql-devel

 
gcc/g++默认只会连接c/c++的库 要想链接系统中的其他库 /lib64/mysql or /usr/lib64/mysql 需要主动-l选项+库名(去前缀和后缀)且-L+库路径
 
 
如果编译报错 需要将上面的库加到系统库路径 使得在编译时 编译器能找到库【怎么加 看链接那一篇】

之前将动静态库时还要加-I选项 这里怎么不用?:我们的代码包含了<mysql/mysql.h>,编译时会去/usr/include找mysql/mysql.h, 如果写成<mysql.h> 则需要下面指令

查看mysql文档方式

 
 
使用c-mysql-api库访问mysqld
MySQL类型结构体
typedef struct st_mysql
{
  NET		net;			/* Communication parameters */
  unsigned char	*connector_fd;		/* ConnectorFd for SSL */
  char		*host,*user,*passwd,*unix_socket,*server_version,*host_info;
  char          *info, *db;
  struct charset_info_st *charset;
  MYSQL_FIELD	*fields;
  MEM_ROOT	field_alloc;
  my_ulonglong affected_rows;
  my_ulonglong insert_id;		/* id if insert on table with NEXTNR */
  my_ulonglong extra_info;		/* Not used */
  unsigned long thread_id;		/* Id for connection in server */
  unsigned long packet_length;
  unsigned int	port;
  unsigned long client_flag,server_capabilities;
  unsigned int	protocol_version;
  unsigned int	field_count;
  unsigned int 	server_status;
  unsigned int  server_language;
  unsigned int	warning_count;
  struct st_mysql_options options;
  enum mysql_status status;
  my_bool	free_me;		/* If free in mysql_close */
  my_bool	reconnect;		/* set to 1 if automatic reconnect */
  /* session-wide random string */
  char	        scramble[SCRAMBLE_LENGTH+1];
  my_bool unused1;
  void *unused2, *unused3, *unused4, *unused5;
  LIST  *stmts;                     /* list of all statements */
  const struct st_mysql_methods *methods;
  void *thd;
  /*
    Points to boolean flag in MYSQL_RES  or MYSQL_STMT. We set this flag 
    from mysql_stmt_close if close had to cancel result set of this object.
  */
  my_bool *unbuffered_fetch_owner;
  /* needed for embedded server - no net buffer to store the 'info' */
  char *info_buffer;
  void *extension;
} MYSQL;
 

 
mysql_real_connect 函数概述
mysql_real_connect 是 MySQL C API 中的一个重要函数,用于建立与 MySQL 数据库服务器的连接。它提供了丰富的参数以支持不同的连接方式和认证机制。
参数
 MYSQL *mysql: 指向 MYSQL 结构的指针,该结构在调用 mysql_real_connect 之前应通过 mysql_init 或 mysql_init_character_set 初始化。
 const char *host: 数据库服务器的地址。可以是主机名或IP地址。如果为 NULL 或 “localhost”,则尝试通过 UNIX 套接字连接(如果可用)。
 const char *user: 连接数据库时使用的用户名。
 const char *passwd: 用户的密码。如果为 NULL,则假定不使用密码。
 const char *db: 要连接的数据库名。如果为 NULL,则先连接到 MySQL 服务器,稍后再选择数据库。
 unsigned int port: MySQL 服务器的端口号。默认为 3306。
 const char *unix_socket: UNIX 套接字的路径名(仅当 host 是 NULL 或 “localhost” 时使用)。如果为 NULL,则使用默认值。
 unsigned long clientflag: 客户端标志的位或组合,用于修改 mysql_real_connect 的行为。例如,MYSQL_CLIENT_COMPRESS 启用压缩,MYSQL_CLIENT_SSL 启用 SSL 加密等。
 返回值
 如果连接成功,mysql_real_connect 返回 mysql 参数的指针(即传入的 MYSQL 结构指针)。
 如果连接失败,返回 NULL。此时,可以使用 mysql_error(mysql) 函数获取错误信息。
 函数功能
 mysql_real_connect 函数的主要功能是尝试根据提供的参数建立与 MySQL 数据库服务器的连接。如果连接成功,它配置并返回 MYSQL 结构以供后续数据库操作使用。如果连接失败,它返回 NULL 并设置错误状态,以便通过 mysql_error 函数获取错误详情。
底层原理
 在底层,mysql_real_connect 会执行以下步骤来建立连接:
解析参数:解析传入的参数,包括主机名、端口、用户名、密码等。
 建立网络连接:根据提供的主机名和端口号(或 UNIX 套接字路径),使用 TCP/IP 或 UNIX 套接字建立与 MySQL 服务器的网络连接。
 认证:向 MySQL 服务器发送认证请求,包括用户名和密码(如果提供)。MySQL 服务器会验证这些信息,并返回认证结果。
 选择数据库(如果指定):如果提供了数据库名,则向 MySQL 服务器发送请求以选择该数据库。
 配置会话:根据 clientflag 参数配置会话选项,如启用压缩、SSL 加密等。
 返回结果:如果所有步骤都成功完成,则返回 MYSQL 结构指针以供后续使用;如果失败,则返回 NULL 并设置错误状态。
 mysql_real_connect 是 MySQL C API 中建立数据库连接的核心函数,它提供了灵活的配置选项以支持不同的使用场景。
证明链接成功

 
 
query接口
mysql_query 函数是 MySQL C API 中的一个重要函数,用于在已经建立的数据库连接上执行 SQL 语句。这个函数接收两个参数:一个是指向 MYSQL 结构的指针(代表已经打开的数据库连接),另一个是包含要执行的 SQL 语句的字符串。
函数原型
c
int mysql_query(MYSQL *mysql, const char *q);
 
参数
 MYSQL *mysql: 指向已经通过 mysql_real_connect 或其他类似函数成功建立的数据库连接的 MYSQL 结构体的指针。
 const char *q: 一个以 null 结尾的字符串,包含了要执行的 SQL 语句。
 返回值
 如果 SQL 语句执行成功,mysql_query 返回 0。
 如果执行失败,返回非 0 值。此时,可以通过 mysql_error(mysql) 函数获取详细的错误信息。
 使用示例
c
#include <mysql.h>  
#include <stdio.h>  
  
int main() {  
    MYSQL *conn;  
    MYSQL_RES *res;  
    MYSQL_ROW row;  
  
    conn = mysql_init(NULL);  
    if (conn == NULL) {  
        fprintf(stderr, "%s\n", mysql_error(conn));  
        return 1;  
    }  
  
    if (mysql_real_connect(conn, "host", "user", "password", "database", 0, NULL, 0) == NULL) {  
        fprintf(stderr, "%s\n", mysql_error(conn));  
        mysql_close(conn);  
        return 1;  
    }  
  
    if (mysql_query(conn, "SELECT * FROM table_name")) {  
        fprintf(stderr, "%s\n", mysql_error(conn));  
        mysql_close(conn);  
        return 1;  
    }  
  
    res = mysql_use_result(conn);  
    while ((row = mysql_fetch_row(res)) != NULL) {  
        printf("%s\n", row[0]); // 假设第一列是字符串类型  
    }  
    mysql_free_result(res);  
  
    mysql_close(conn);  
    return 0;  
}
 
注意事项
 在调用 mysql_query 之前,必须确保已经通过 mysql_real_connect 或其他函数成功建立了数据库连接。
 mysql_query 适用于执行任何 SQL 语句,包括查询(SELECT)、更新(UPDATE)、删除(DELETE)和插入(INSERT)等。
 对于返回结果集的查询(如 SELECT),通常需要使用 mysql_use_result 或 mysql_store_result 来处理结果。
 在处理完结果集后,应使用 mysql_free_result 释放结果集占用的资源。
 始终检查 mysql_query 的返回值以确认 SQL 语句是否成功执行,并在出错时通过 mysql_error 获取错误信息。
 在完成数据库操作后,应使用 mysql_close 关闭数据库连接以释放相关资源。
复习指针
#include <stdio.h>  
  
void changePointer(int **ptr) {  
    *ptr = malloc(sizeof(int)); // 分配新的内存,并改变ptr指向的指针的指向  
    **ptr = 10; // 修改新分配的内存中的值  
}  
  
int main() {  
    int *p = NULL;  
    changePointer(&p); // 传递p的地址,即二级指针  
    printf("%d\n", *p); // 输出10  
    free(p); // 释放内存  
    return 0;  
}
 
代码
#include <iostream>
#include <mysql/mysql.h>
// 端口错误或mysqld未启动都会导致连接失败
// ctrl+d:事务流结束 有些平台如windows是ctrl+c
// const std::string host ="localhost";
const std::string host = "127.0.0.1";
const std::string user = "lhr";
const std::string passwd = "lhr.547521";
const std::string db = "c_cpp_test";
const unsigned int port = 3306;
int main()
{
    printf("mysql client Version: %s\n\n", mysql_get_client_info());
    // 句柄:fd/file*/c++文件流对象
    MYSQL *_mysql = mysql_init(nullptr);
    if (nullptr == _mysql)
    {
        fprintf(stderr, "%s\n", mysql_error(_mysql));
        return 1;
    }
    if (mysql_real_connect(_mysql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        fprintf(stderr, "%s\n", mysql_error(_mysql));
        mysql_close(_mysql);
        return 1;
    }
    // 建立好链接之后 获取英文没有问题 获取中文是乱码
    // 需要设置链接的默认字符集是utf8 客户端原始默认是latin1
    // 而我们设置了mysqld的默认字符集是utf8 编码解码不一致!
    mysql_set_character_set(_mysql, "utf8");
    // std::string sql ="update user set name='jimmy' where id=2";
    // std::string sql = "insert into user (name, age, phone) values('张三',19,'654321987687')";
    // std::string sql="delete from user where id=1";
    std::string sql = "select * from user";
    // std::string sql="select name,age from user where id=1";
    int value = mysql_query(_mysql, sql.c_str());
    if (value == 0)
        std::cout << "Query OK" << std::endl;
    else
    {
        fprintf(stderr, "%s\n", mysql_error(_mysql));
        mysql_close(_mysql);
        return 1;
    }
    MYSQL_RES *res = mysql_store_result(_mysql);
    if (nullptr == res)
    {
        fprintf(stderr, "%s\n", mysql_error(_mysql));
        mysql_close(_mysql);
        return 1;
    }
    my_ulonglong rows = mysql_num_rows(res);
    unsigned int cols = mysql_num_fields(res);
    MYSQL_FIELD *fields = mysql_fetch_fields(res);
    std::cout << std::endl;
    std::cout << "select database(): " << fields[0].db << std::endl;
    std::cout << "select table(): " << fields[0].table << std::endl;
    std::cout << std::endl;
    for (int i = 0; i < cols; i++)
        std::cout << fields[i].name << " ";
    std::cout << std::endl;
    ///* return data as array of strings */
    // typedef char **MYSQL_ROW;
    MYSQL_ROW line;
    for (int i = 0; i < rows; i++)
    {
        line = mysql_fetch_row(res);
        for (int j = 0; j < cols; j++)
            std::cout << line[j] << " ";
        std::cout << std::endl;
    }
    /*
    std::string sql;
    while (true)
    {
        std::cout << "MySOL>>>";
        if (!std::getline(std::cin, sql) || sql == "quit")
        {
            std::cout << "bye bye" << std::endl;
            break;
        }
        int n = mysql_query(_mysql, sql.c_str());
        if (n == 0)
            std::cout << sql << "success:" << n << std::endl;
        else
            mysql_close(_mysql);
    }
    std::cout << "connect susccess" << std::endl;
    */
    mysql_free_result(res);
    mysql_close(_mysql);
    return 0;
}
 
理解mysql_res
mysql将所有的数据,读取出来的时候全部都当做字符串
图片来源

3.图形化界面
具体如何安装使用,网上有很多资料,这里不再赘述。



















