当前位置: 首页 > ai >正文

【MySQL】C语言访问数据库

C语言访问数据库

  • 一. Linux 安装 MySQL 动静态库
  • 二. 使用MySQL数据库
    • 1. 创建MySQL对象
    • 2. 连接MySQL数据库
    • 3. 释放MySQL对象
    • 4. SQL 语句操作
      • 1. 插入操作
      • 2. 修改操作
      • 3. 删除操作
      • 4. 查询操作

准备工作

use mysql;
select user, host from user;# 创建本地连接的用户
create user 'connector'@'localhost' identified by '123456';select user, host from user;

在这里插入图片描述

# 创建conn数据库
create database conn;# 创建student表
create table student(id int primary key auto_increment,name varchar(20) not null,age int not null,telephone varchar(32) unique
);# 插入数据
insert student (name, age, telephone) values ('张三', 18, 111);
insert student (name, age, telephone) values ('李四', 19, 222);# 将conn数据库下的所有表的权限授权给本地登入的connector用户
grant all on conn.* to 'connector'@'localhost';

在这里插入图片描述

一. Linux 安装 MySQL 动静态库

# Ubantu
apt-get install libmysqlclient-dev

安装后,头文件通常位于/usr/include/mysql/,库文件位于/usr/lib/x86_64-linux-gnu/

在这里插入图片描述

下面先通过调用mysql_get_client_info来判断库是否引入成功,该函数的作用就是获取客户端的版本信息。

#include <iostream>
#include <mysql/mysql.h>int main()
{// 获取客户端的版本信息std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;return 0;
}

为了方便后续重复编译源文件,可以在项目目录下创建一个Makefile,内容如下:

test:test.ccg++ -o $@ $^ -std=c++11 -lmysqlclient.PHONY:clean
clean:rm -rf test

在这里插入图片描述

二. 使用MySQL数据库

1. 创建MySQL对象

MYSQL* mysql_init(MYSQL *mysql);

说明:

  • 该函数用来分配或者初始化一个MySQL对象,用于连接MySQL服务器。
  • 如果传入的参数是NULL,那么mysql_init将自动为你分配一个MySQL对象并返回。
  • 如果传入的参数是一个地址,那么mysql_init将在该地址处帮你完成初始化。

2. 连接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 clientflag);

参数说明:

  • mysql:表示在连接数据库前,调用mysql_init函数创建的MySQL对象。
  • host:表示需要连接的MySQL服务器的IP地址,"127.0.0.1"表示连接本地MySQL服务器。
  • user:表示连接MySQL服务器时,所使用用户的用户名。
  • passwd:表示连接MySQL服务器时,所使用用户的密码。
  • db:表示连接MySQL服务器后,需要使用的数据库。
  • port:表示连接的MySQL服务器,所对应的端口号。
  • unix_socket:表示连接时应该使用的套接字或命名管道,通常设置为NULL
  • clientflag:可以设置为多个标志位的组合,表示允许特定的功能,通常设置为0

返回值说明:

  • 如果连接数据库成功,则返回一个MySQL对象,该对象与第一个参数的值相同。
  • 如果连接数据库失败,则返回NULL

3. 释放MySQL对象

void mysql_close(MYSQL *sock);

说明:

  • 该函数的参数,就是连接数据库前调用mysql_init创建的MySQL对象。
  • 如果传入的MySQL对象是mysql_init自动创建的,那么调用mysql_close时就会释放这个对象。

连接示例

#include <iostream>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 3306;int main()
{MYSQL* mysql = mysql_init(nullptr);if(mysql == nullptr){std::cerr << "mysql_init error" << std::endl;return 1;}if(mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "mysql_real_connect error" << std::endl;return 2; }std::cout << "连接 mysql 成功" << std::endl;std::cout << "执行SQL语句..." << std::endl;mysql_close(mysql);std::cout << "关闭 mysql 连接" << std::endl;return 0;
}

在这里插入图片描述

4. SQL 语句操作

int	mysql_query(MYSQL *mysql, const char *q);

参数说明:

  • mysql:表示在连接数据库前,调用mysql_init函数创建的MySQL对象。
  • q:示向MySQL服务器下发的SQL请求,SQL最后可以不带分号。

返回值说明:

  • 返回值为0表示SQL执行成功,否则表示SQL执行失败。

设置编码格式

在连接数据库之后,需要统一客户端和服务器的编码格式,避免在数据交互过程中出现乱码

int mysql_set_character_set(MYSQL *mysql, const char *csname);

参数说明:

  • mysql:表示在连接数据库前,调用mysql_init函数创建的MySQL对象。
  • csname:表示要设置的编码格式,如"utf8"

返回值说明:

  • 返回值为0表示设置成功,否则表示设置失败。

测试表介绍

下面在与MySQL数据库交互时,访问的都是 conn 数据库,该数据库下有一个 student 表,表中有三条记录,如下:

在这里插入图片描述

1. 插入操作

#include <iostream>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 3306;int main()
{MYSQL *mysql = mysql_init(nullptr);if (mysql == nullptr){std::cerr << "mysql_init error" << std::endl;return 1;}if (mysql_real_connect(mysql, host.c_str(), user.c_str(),passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "mysql_real_connect error" << std::endl;return 2;}mysql_set_character_set(mysql, "utf8");std::string sql = "insert student (name, age, telephone) values ('王五', 20, 333)";if (mysql_query(mysql, sql.c_str()) != 0){std::cout << "插入数据失败!" << std::endl;return 3;}mysql_close(mysql);return 0;
}

在这里插入图片描述

2. 修改操作

#include <iostream>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 3306;int main()
{MYSQL *mysql = mysql_init(nullptr);if (mysql == nullptr){std::cerr << "mysql_init error" << std::endl;return 1;}if (mysql_real_connect(mysql, host.c_str(), user.c_str(),passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "mysql_real_connect error" << std::endl;return 2;}mysql_set_character_set(mysql, "utf8");std::string sql = "update student set age = 99 where id = 3";if (mysql_query(mysql, sql.c_str()) != 0){std::cout << "修改数据失败!" << std::endl;return 3;}mysql_close(mysql);return 0;
}

在这里插入图片描述

3. 删除操作

#include <iostream>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 3306;int main()
{MYSQL *mysql = mysql_init(nullptr);if (mysql == nullptr){std::cerr << "mysql_init error" << std::endl;return 1;}if (mysql_real_connect(mysql, host.c_str(), user.c_str(),passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "mysql_real_connect error" << std::endl;return 2;}mysql_set_character_set(mysql, "utf8");std::string sql = "delete from student where id = 3";if (mysql_query(mysql, sql.c_str()) != 0){std::cout << "删除数据失败!" << std::endl;return 3;}mysql_close(mysql);return 0;
}

在这里插入图片描述

4. 查询操作

  • 对数据库中的数据进行增删改操作时,都只需要调用mysql_query向服务器下发对应的SQL请求。
  • 而对数据库中的数据进行查询操作时,除了需要调用mysql_query向服务器下发对应的查询SQL,还需要获取查询结果。
// 获取查询结果
MYSQL_RES* mysql_store_result(MYSQL *mysql);// 释放查询结果
void mysql_free_result(MYSQL_RES *result);

注意:MYSQL_RES变量的内存空间是malloc出来的,因此在使用完后需要调用free函数进行释放,否则会造成内存泄露,MySQL提供了mysql_free_result函数释放内存。

// 获取查询结果的行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);// 获取查询结果的列数
unsigned int mysql_num_fields(MYSQL_RES *res);// 获取查询结果的列名
MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *res);// 获取查询结果
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

说明:

  • mysql_num_rows函数将会从指定的MYSQL_RES对象中,获取查询结果的行数。
  • mysql_num_fields函数将会从指定的MYSQL_RES对象中,获取查询结果的列数。
  • mysql_fetch_fields函数将会从指定的MYSQL_RES对象中,获取查询结果的列属性。
  • mysql_fetch_row函数将会从指定的MYSQL_RES对象中,获取查询结果中的一行数据。

MYSQL_ROW对象中保存着一行数据,这一行数据中可能包含多个字符串,对应就是这行数据中的多个列信息,本质是 typedef char **MYSQL_ROW,其遍历打印类似代码以下:

#include <iostream>int main() 
{char* languages[] = {"C", "C++", "Java", "Python"};char** langPtr = languages;for (int i = 0; i < 4; i++) {std::cout << langPtr[i] << std::endl;}return 0;
}

查询示例

#include <iostream>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 3306;int main()
{// 1.创建MySQL对象MYSQL *mysql = mysql_init(nullptr);if (mysql == nullptr){std::cerr << "mysql_init error" << std::endl;return 1;}// 2.连接MySQL数据库if (mysql_real_connect(mysql, host.c_str(), user.c_str(),passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "mysql_real_connect error" << std::endl;return 2;}// 3.设置编码格式mysql_set_character_set(mysql, "utf8");// 4.执行查询语句std::string sql = "select * from student";if (mysql_query(mysql, sql.c_str()) != 0){std::cout << "查询数据失败!" << std::endl;return 3;}// 5.获取查询结果MYSQL_RES *res = mysql_store_result(mysql);if (res == nullptr){std::cerr << "mysql_store_result error" << std::endl;return 4;}// 6.获取行列数my_ulonglong rows = mysql_num_rows(res);my_ulonglong cols = mysql_num_fields(res);std::cout << "行:" << rows << std::endl;std::cout << "列:" << cols << std::endl;// 7.打印列名MYSQL_FIELD *fields = mysql_fetch_fields(res);for (int i = 0; i < cols; i++){std::cout << fields[i].name << "\t";}std::cout << std::endl;// 8.打印查询结果for (int i = 0; i < rows; i++){MYSQL_ROW row = mysql_fetch_row(res);for (int j = 0; j < cols; j++){std::cout << row[j] << "\t";}std::cout << "\n";}// 9.释放res和关闭MySQL数据库mysql_free_result(res);mysql_close(mysql);return 0;
}

在这里插入图片描述

http://www.xdnf.cn/news/4370.html

相关文章:

  • 第5讲、Transformer 编码器(Encoder)处理过程详解
  • 世界无人机大会将至,大势智慧以“AI+实景三维”赋能低空经济
  • 从创意到变现:独立创造者的破局之路——解码《Make:独立创造者手册》
  • PyCharm连接WSL2搭建的Python开发环境
  • Kepware 连接Modbus TCP/IP
  • 上海雏鸟科技再赴越南,助力10518架无人机刷新吉尼斯记录
  • MySQL优化-MySQL常见的锁机制
  • 报表的那些事:四部演进史——架构视角下的技术跃迁与实战思考
  • 高防ip是怎么做到分布式防御的
  • 如何用命令行判断一个exe是不是c#wpf开发的
  • win11指定Microsoft Print To PDF的输出路径(电子书djvu转pdf输出路径)
  • dify 部署后docker 配置文件修改
  • docker host模式问题
  • 使用Milvus向量数据库构建具有长期记忆的对话机器人
  • Flowchart 流程图的基本用法
  • 基于OpenTelemetry的分布式链路追踪Trace‌实现(PHP篇)
  • androidStudio里gradle过滤冲突资源文件
  • 【解决方案】CloudFront VPC Origins 实践流程深入解析 —— 安全高效架构的实战之道
  • Android 如何理解 Java JNI 中的引用与 Java 对象的区别
  • Kafka Controller的作用是什么?故障时如何恢复? (管理分区和副本状态;通过ZooKeeper选举新Controller)
  • Linux系统Shell脚本之shell函数
  • Kafka的核心组件有哪些?简要说明其作用。 (Producer、Consumer、Broker、Topic、Partition、ZooKeeper)
  • java多线程------synchronized
  • CVE体系若消亡将如何影响网络安全防御格局
  • git合并分支后回滚,再次合并导致更改没有合并的问题
  • CentOS 7 基础环境安装脚本
  • Milvus(16):索引解释
  • 【前端基础】6、CSS的文本属性(text相关)
  • 嵌入式通信协议总览篇:万物互联的基石
  • 记一次SSE数据被缓存导致实时性失效问题