【MySQL】访问mysqld的方式{命令行客户端/vscode-c-api客户端/图形化界面:mysql/navicat}

1.访问数据库

命令行式客户端向mysqld下达指令
网页版
图形化界面
语言级别的库/包

mysql的基础,我们之前已经学过,后面我们只关心使用。要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载。我们使用C接口库来进行连接。要正确使用,我们需要做一些准备工作:

  1. 保证mysql服务有效
  2. 在官网上下载合适自己平台的mysql connect库,以备后用。其中include 包含所有的方法声明,lib 包含所有的方法实现(打包成库)。
  3. 要使用库,必须先进行初始化!
  4. 初始化完毕之后,必须先链接数据库,在进行后续操作。(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);
  1. sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操
    作成功与否即可。我们来看看如何获取查询结果: 如果mysql_query返回成功,那么我们就通过
    mysql_store_result这个函数来读取结果。原型如下:MYSQL_RES *mysql_store_result(MYSQL *mysql);
  2. 该函数会调用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.图形化界面

具体如何安装使用,网上有很多资料,这里不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿猿收手吧!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值