数据库—mysql、数据库编程(API)

1. Linux平台准备

        (1)安装SDK开发包的命令

sudo apt-get install libmysqlclient-dev

        (2)编译时需要链接的库:-lmysqlclient

2. mysql 的初始化和清理

#include <mysql/mysql.h>
MYSQL mysql1;  //创建句柄
mysql_init(&mysql1);  //初始化句柄
mysql_close(&mysql);  //关闭句柄

3. mysql 的连接登录

        (1)连接登录 mysql_real_connect

const char *p = "192.168.126.215";  //配置ip
const char *user = "root";  //配置用户名
const char *password" = "123456";  //配置密码
const char *db = "test";  //配置要打开的数据库

if ( mysql_real_connect(&mysql1, ip, user, password, db, 13306, nullptr, 0) == 0)  //等于0则打开失败
{
    cout<<"connect error"<<endl;
}
else
{
    cout<<"connect ok"<<endl;
}

        (2)设置断开自动重连 

//设置断开重连的功能
int ret = 1;
mysql_options(&mysql1, MYSQL_OPT_RECONNECT, &ret);
//中间的宏表示如果发现连接丢失,则启动与服务器的自动再连接;


//设置自动检测的超时时间
int timeout = 3;
mysql_options(&mysql1, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
//中间的宏表示以秒为单位的连接超时,即超过3秒就启动重新连接

//设置是否连接的检测
if( mysql_ping(&mysql1) != 0 )
{
    cout<<"connect failed"<<endl;
}
else
{
    cout<<"connect success"<<endl;
}

4. mysql 的数据查询

        (1)执行sql语句,注意:执行sql语句后,必须获取结果集并且清理;

//创建表
string sql = "create table person(id int, name varchar(20), age int";
mysql_real_query(&mysql, sql.c_str(), sql.size());
//mysql_query(&mysql, sql.c_str());  和上面不同的是,这里并没有指定长度,执行效率没有上面的快
//对于包含二进制数据的查询,必须使用mysql_real_query(),因为二进制代码数据可能包含‘\0’字符;

//插入数据
string sql2 = "insert into person(id, name, age)values(1, 'zhangsan', 14);
mysql_real_query(&mysql, sql2.c_str(), sql2.size());

//查询数据
string sql3 = "select * from person";
mysql_real_query(&mysql, sql3.c_str(), sql3.size());

        (2)获取结果集

//获取结果集
MYSQL_RES *result;  //定义一个MYSQL_RES结构;
result = mysql_use_result(&mysql1);  //将查询结构保存在result中;
if(result == nullptr)
{
    cout<<"select error"<<endl;
}

//获取字段个数,即查询获得的结果里有几列数据
int nums = 0;  
nums = mysql_num_fields(result);  //属于表结构的获取

//获取字段名,即列的名称
MYSQL_FIELD * fields;  //字段名的数据类型的变量
fields = mysql_fetch_fields(result);  //属于表结构的获取
for(int i = 0; i < num; i++)
{
    cout<<fields[i].name<<"|";
}
cout<<endl;

//遍历显示结果
MYSQL_ROW row;  //存储每一行数据的数据类型的变量
while( (row = mysql_fetch_row(result)) != nullptr)  //mysql_fetch_row()函数从指定的结果集中获取一行数据返回给row,是数组的形式,即row内部是字符串数组指针(二级指针)
{
    for(i = 0; i < nums; i++)
    {
        cout<<row[i]<<"|";
    }
    cout<<endl;
}

        (3)清理结果集

//释放结果集的指针空间
mysql_free_result(result);

整体示例如下:

#include <iostream>
#include <mysql/mysql.h>
#include <unistd.h>

using namespace std;

int main(int argc, char **argv)
{
    MYSQL mysql1;
    mysql_init(&mysql1);

    const char *ip = "192.168.226.128";
    const char *user = "root";
    const char *password = "123456";
    const char *db = "test";

    if(mysql_real_connect(&mysql1, ip, user, password, db, 13306, nullptr,0) == 0)
    {
        cout<<"connect error"<<endl;
    }
    else
    {
        cout<<"connect ok"<<endl;
    }
    
    string sql = "create table person(id int, name varchar(20), age int)";
    mysql_real_query(&mysql1, sql.c_str(), sql.size());

    // string sql1 = "select"

    int ret = 1;
    mysql_options(&mysql1, MYSQL_OPT_RECONNECT, &ret);

    int timeout = 3;
    mysql_options(&mysql1, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);

    // while(1)  //测试断开重连功能
    // {
    //     if(mysql_ping(&mysql1) != 0)
    //     {
    //         cout<<"connect failed"<<endl;
    //     }
    //     else
    //     {
    //         // cout<<"connnect ok"<<endl;
    //     }
    //     sleep(1);
    // }

    string sql2 = "insert into person(id, name, age)values(1,'zhangsan',12)";
    mysql_real_query(&mysql1, sql2.c_str(), sql2.size());

    string sql22 = "insert into person(id, name, age)values(2,'lisi',16)";
    mysql_real_query(&mysql1, sql22.c_str(), sql22.size());

    string sql3 = "select * from person";
    mysql_real_query(&mysql1, sql3.c_str(), sql3.size());

    MYSQL_RES * result = mysql_use_result(&mysql1);
    if(result == nullptr)
    {
        cout<<"select error"<<endl;
    }

    int nums = 0;
    nums = mysql_num_fields(result);
    cout<<"nums = "<<nums<<endl;

    MYSQL_FIELD * fields = mysql_fetch_fields(result);
    for(int i = 0; i < nums; i++)
    {
        cout<<fields[i].name<<"|";
    }
    cout<<endl;

    MYSQL_ROW row;
    while((row = mysql_fetch_row(result)) != nullptr)
    {
        for(int i =0; i < nums; i++)
        {
            cout<<row[i]<<"|";
        }
        cout<<endl;
    }

    mysql_free_result(result);
    mysql_close(&mysql1);
    return 0;
}

运行结果如下:

5. mysql 显示中文

//设置中文的思路是统一设置字符集为utf8;
const char * csname = "utf8";
mysql_set_character_set(&mysql, csname);

6. 图片存储与读取保存的例子

#include <iostream>
#include <mysql/mysql.h>
#include <thread>
#include <string>
#include <sstream>
#include <map>
#include <chrono>
#include <fstream>
using namespace std;
using namespace chrono;

int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char* host = "192.168.226.128";
	//const char *host = "192.168.0.203";
	const char* user = "root";
	const char* pass = "123456";
	const char* db = "test";		//数据库名称

	//CLIENT_MULTI_STATEMENTS 支持多条sql语句
	if (!mysql_real_connect(&mysql, host, user, pass, db, 13306, 0, CLIENT_MULTI_STATEMENTS))
		//if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0, 0))
	{
		cout << "mysql connect failed!" << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql connect success!" << endl;
	}
	string sql = "";

	//1 创建好存放二进制数据的表 t_data
	sql = "CREATE TABLE IF NOT EXISTS `t_data` (\
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`data` blob,\
		`size` int,\
		PRIMARY KEY(`id`))";

	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << mysql_error(&mysql) << endl;
	}

	//2 清空表 truncate t_data
	sql = "truncate t_data";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cerr << mysql_error(&mysql) << endl;
	}

	//3 初始化stmt mysql_stmt_init
	MYSQL_STMT* stmt = mysql_stmt_init(&mysql);
	if (!stmt)
	{
		cerr << "mysql_stmt_init failed!" << mysql_error(&mysql) << endl;
	}

	//4 预处理sql语句
	sql = "INSERT INTO `t_data` (name,data,size) VALUES(?,?,?)";
	if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size()))
	{
		cerr << "mysql_stmt_prepare failed!" << mysql_stmt_error(stmt) << endl;
	}

	//5 打开并读取文件
	string path = ".//";
	string filename = "mysql.jpg";

	cout << path + filename << endl;

	//读取二进制
	fstream in(path + filename, ios::in | ios::binary);
	if (!in.is_open())
	{
		cerr << "file " << filename << " open failed!" << endl;
	}
	//文件指针移动到结尾处
	in.seekg(0, ios::end);
	//文件大小和文件二进制地址
	int filesize = in.tellg();
	//回到开头
	in.seekg(0, ios::beg);

	char* data = new char[filesize];
	int readed = 0; //已经读了多少
	while (!in.eof())
	{
		in.read(data + readed, filesize - readed);
		//读取了多少字节
		if (in.gcount() <= 0)
			break;
		readed += in.gcount();
	}

	in.close();

	//6 绑定字段
	MYSQL_BIND bind[3] = { 0 };
	bind[0].buffer_type = MYSQL_TYPE_STRING;  //name 文件名
	bind[0].buffer = (char*)filename.c_str();
	bind[0].buffer_length = filename.size();

	bind[1].buffer_type = MYSQL_TYPE_BLOB;   //data 文件二进制内容
	bind[1].buffer = data; //二进制文件
	bind[1].buffer_length = filesize;

	//文件大小
	bind[2].buffer_type = MYSQL_TYPE_LONG;
	bind[2].buffer = &filesize;

	if (mysql_stmt_bind_param(stmt, bind) != 0)
	{
		cerr << "mysql_stmt_bind_param failed! " << mysql_stmt_error(stmt) << endl;
	}

	//7 执行stmt sql
	if (mysql_stmt_execute(stmt) != 0)
	{
		cerr << "mysql_stmt_execute failed! " << mysql_stmt_error(stmt) << endl;
	}
	delete data;
	mysql_stmt_close(stmt);


	sql = "select * from t_data";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cerr << "mysql query failed!" << mysql_error(&mysql) << endl;
	}
	//获取结果集
	MYSQL_RES* res = mysql_store_result(&mysql);
	if (!res)
	{
		cerr << "mysql_store_result failed!" << mysql_error(&mysql) << endl;
	}
	//取一行数据
	MYSQL_ROW row = mysql_fetch_row(res);
	if (!row)
	{
		cerr << "mysql_fetch_row failed!" << mysql_error(&mysql) << endl;
	}
	cout << row[0] << " " << row[1] << " " << row[3] << endl;

	//获取每列数据的大小
	unsigned long* lens = mysql_fetch_lengths(res);
	int fnum = mysql_num_fields(res);
	for (int i = 0; i < fnum; i++)
	{
		cout << "[" << lens[i] << "]";
	}
	filename = "out_";
	filename += row[1];
	fstream out(filename, ios::out | ios::binary);
	if (!out.is_open())
	{
		cerr << "open file  " << filename << " failed!" << endl;
	}
	out.write(row[2], lens[2]);
	out.close();


	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Mysql 8.0 API!\n";


	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Mysql 8.0 API!\n";
	getchar();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/27625.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

宝塔面板搭建Discuz论坛并发布互联网访问【无需云服务器】

文章目录 前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 转载自cpolar极点云的文章&#xff1a;Linux宝塔面板搭建Discuz论坛&#xff0c;并公网远程访问【内网穿透】 前言 Crossday Discuz! Board&#xff08;以…

MapReduce共享单车练习

MapReduce 本机运行 文章目录 MapReduce 本机运行✅前置工作1. 配置JDK2. 创建Java项目3. 导入所需JAR包 编程实现以下题目1. 统计各个月份共享单车使用的总数2. 统计不同天气情况下共享单车使用的总数3. 统计每个季度共享单车使用的总数4. 统计每个月份的注册数量5. 统计每天1…

【V4L2】v4l2框架分析之video_device

文章目录 &#x1f53a;一、video_device分析&#xff08;1-1&#xff09;struct video_device结构&#xff08;1-2&#xff09;struct v4l2_ioctl_ops结构&#xff08;1-3&#xff09;v4l2_file_operations结构 &#x1f53a;二、注册video设备&#x1f53a;三、卸载清除video…

WPF开发txt阅读器6:用树形图管理书籍

txt阅读器系列&#xff1a; 需求分析和文件读写目录提取类&#x1f48e;列表控件与目录字体控件绑定书籍管理系统 TreeView控件 TreeView可以通过可折叠的节点来显示层次结构中的信息&#xff0c;是表达文件系统从属关系的不二选择&#xff0c;其最终效果如下 为了构建这个树…

KISS复盘法

KISS复盘法 KISS复盘法是一种科学的项目复盘方法&#xff0c;能够把过往经验转化为实践能力&#xff0c;以促进下一次活动更好地展开&#xff0c;从而不断提升个人和团队的能力&#xff01; 模型介绍 【复盘】原是围棋术语&#xff0c;本意是对弈者在下完一盘棋之后&#xff0…

uniapp 横向滑动list(不同内容)分部问题:scroll-view,swiper overflow-x

横向滑动list,可使用标签&#xff1a; 1&#xff1a;scroll-view 2&#xff1a;swiper 3&#xff1a;overflow-x 正常来讲横向滑动的话 &#xff0c;需要特殊设置&#xff0c;只用view 设置display&#xff1a;flex&#xff0c;的话 无法横向滑动&#xff0c;右边的就会隐…

git hook

hook hook 翻译为钩子&#xff0c;简单说就是监听某个事件&#xff08;操作&#xff09;&#xff0c;然后触发自定义逻辑 在 git 中可以监听 commit&#xff0c;push 等操作&#xff0c;在操作之前或之后触发对应的 hook&#xff0c;在 hook 中写自定义的逻辑&#xff0c;比如…

Java Web开发实战经典学习过程笔记

Java Web开发实战经典学习简单笔记 第一章 Java Web 开发简介 1.胖客户端程序指的是&#xff0c;当一个程序运行时需要一个单独的客户端程序支持(如&#xff1a;QQ)。瘦客户端程序在操作时不需要任何其他程序的安装(如&#xff1a;登录网上论坛&#xff0c;只需浏览器即可)。 2…

算法刷题-链表-反转链表

反转链表 206.反转链表思路C代码双指针法递归法其他语言版本使用虚拟头结点解决链表翻转使用栈解决反转链表的问题 反转链表的写法很简单&#xff0c;一些同学甚至可以背下来但过一阵就忘了该咋写&#xff0c;主要是因为没有理解真正的反转过程。 206.反转链表 力扣题目链接 …

4.使用Express跨域资源共享(继上一章)

4.5、CORS跨域资源共享 1.接口的跨域问题 刚才编写的GET和POST接口&#xff0c;存在一个很严重的问题&#xff1a;不支持跨域请求。 解决接口跨域问题的方案主要有两种&#xff1a; ①CORS&#xff08;主流的解决方案&#xff0c;推荐使用&#xff09; ②JSONP&#xff08…

6.11下周黄金行情分析及开盘多空交易策略

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;金价周五(6月8日)收低&#xff0c;但在美元整体走软的支撑下&#xff0c;本周录得连续第二周上升。美市尾盘&#xff0c;现货黄金收报1960.83美元/盎司&#xff0c;…

Seata介绍、原理、配置

目录 介绍&#xff1a; 核心组件&#xff1a; 原理&#xff1a; Seata 会有 4 种分布式事务解决方案&#xff0c;分别是 AT 模式、TCC 模式、Saga 模式和 XA 模式 AT模式原理&#xff1a; 一阶段&#xff1a; 二阶段提交&#xff1a; 二阶段回滚&#xff1a; Seata配置…

华为OD机试真题 JavaScript 实现【数字涂色】【2022Q4 100分】,附详细解题思路

一、题目描述 疫情过后&#xff0c;希望小学终于又重新开学了&#xff0c;三年二班开学第一天的任务是将后面的黑板报重新制作。 黑板上已经写上了N个正整数&#xff0c;同学们需要给这每个数分别上一种颜色。 为了让黑板报既美观又有学习意义&#xff0c;老师要求同种颜色的…

每个程序员都必须知道的8种通用数据结构

8种常用数据结构 数据结构是一种特殊的组织和存储数据的方式&#xff0c;可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。 几乎所有已开发的程序或软件系统都使用数据结构。此外&#xff0c;数据结构属于计算机科学和…

微服务eureka和nacos

服务远程调用 /*** 创建RestTemplate并注入Spring容器* return*/Beanpublic RestTemplate restTemplate(){return new RestTemplate();} Autowiredprivate RestTemplate restTemplate;public Order queryOrderById(Long orderId) {// 1.查询订单Order order orderMapper.fin…

JMeter 测试 ActiveMq

JMeter 测试 ActiveMq 的资料非常少&#xff0c; 我花了大量的时间才研究出来 关于ActiveMq 的文章请参考我另外的文章。 版本号: ActiveMq 版本号: 5.91 Jmeter 版本号: 1.13 添加ActiveMq 的jar包 将 ActiveMq 下的 "activemq-all-5.9.1.jar" 复制…

【2023】Redis cluster集群模式搭建

目录 1.cluster集群介绍2.搭建cluster集群2.1.架构图2.2.搭建集群2.2.1.创建所需配置文件2.2.2.创建集群所需容器2.2.3.创建集群&#xff1a;master1节点连接其他节点2.2.4.配置从节点&#xff0c;完成三主三从 3.在cluster集群内读写数据 1.cluster集群介绍 Redis Cluster是R…

[C++]异常笔记

我不怕练过一万种腿法的对手,就怕将一种腿法 练一万次的对手。 什么是C的异常 在C中&#xff0c;异常处理通常使用try-catch块来实现。try块用于包含可能会抛出异常的代码&#xff0c;而catch块用于捕获并处理异常。当异常被抛出时&#xff0c;程序会跳过try块中未执行…

【ABAP】数据类型(二)「预定义数据类型」

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后端的开发语言A…

一文读懂 Mysql MVCC

&#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; 文章目录 1、什么是 MVCC2、什么是当前读、快照读3、MVCC 具体解决什么问题4、MVCC 的实现原理4.1、4个隐式字段4.2、undo 日志4.3、Read View 5、使用 MVCC 时&#xff0c;需…