文章目录
一、环境问题
首先介绍几个我自己的配置环境的时候遇到的问题:
1.如果你使用的是yum来进行下载的MySQL,那么库文件应该是被配置好了的,如果没有找到,那么需要在官网上进行自己下载。
2.下载之后连接某一个用户的话,MySQL8.0需要修改密码的加密规则才能成功连接,可以使用函数mysql_error()来进行寻错。
3.在插入数据的时候出现乱码信息,需要使用mysql_set_charset_set()函数来设置对应的编码规则。
二、Makefile文件
编写makefile文件需要一些动静态库的知识,这些在我之前的博客中都有提及(动静态库的链接),这里不多赘述:
mytest:test.cc
g++ -o $@ $^ -std=c++11 -I./include -L./lib -lmysqlclient
.PHONY:clean
rm -rf mytest
三、链接MySQL
1.准备工作
首先我们需要明确链接哪一个数据库,用户是谁,用什么主机,端口号是什么等等的信息,这些信息使用字符串来进行保存。
string user="test";
string host="127.0.0.1";
string password = "Homelander@2022";
string db="db";
unsigned int port=3306;
2.初始化一个句柄
我们将通过这个句柄来实现和远程数据库的链接或者关闭:
MYSQL* my=mysql_init(nullptr);//创建并初始化一个MySQL句柄
mysql_close(my);//关闭mysql句柄
3.连接数据库
使用函数mysql_real_connect来链接数据库:
if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0)==nullptr)
{
cout<<mysql_error(my)<<endl;
cout<<"connect failed"<<endl;
return 1;
}
cout<<"connect succeed"<<endl;
mysql_set_character_set(my,"utf8");//将编码格式修改为utf8
当他的返回值为空的时候,表示没有链接成功,如果你是MySQL8.0,很有可能是因为密码的加密方式导致链接失败。
4.增删改
相对于查来说,增删改的操作就比较容易一些,它们的本质是将MySQL的语句当做一个字符串来传入,执行交给mysql_query这个函数来完成:
string sql="insert into test values(3,\'祖国人\')";
int res=mysql_query(my,sql.c_str());
if(res!=0)
{
cout<<"execute:"<<sql<<"failed"<<endl;
return 2;
}
cout<<"execute:"<<sql<<endl;
对于sql来说,我们也可以对其执行其他的增删改操作,只需要修改sql的内容就可以了。在MySQL端可以看到已经成功插入了:
注意,在C语言中写MySQL语句的时候需要使用转义字符\,并且最后不需要加分号。
5.查
查与增删改不同,查是需要看到内容的,因此需要更多的接口:
(1)获取句柄中最后一次返回
string sql="select * from account";
int res = mysql_query(my, sql.c_str());
if(res!=0)
{
cout<<"execute:"<<sql<<"failed"<<endl;
return 2;
}
MYSQL_RES* result=mysql_store_result(my);//存放mysql句柄中最后一次返回
但获取之后,我们就不需要和句柄打交道了,而是直接和返回的result打交道。
(2)获取行和列
注意这里的行和列是不包括字段名那一行的。
int rows=mysql_num_rows(result);
int cols=mysql_num_fields(result);
cout<<"行数"<<rows<<"列数"<<cols<<endl;
可以看到不需要再传入句柄了,因为整个select的信息已经被保存在了result中。
(3)获取列名
使用MYSQL_FIELD结构体类型来获取列名,该结构体的name存放的就是列名。fields是一个指向首列元素的指针。
MYSQL_FIELD * fields=mysql_fetch_fields(result);
for(int i=0;i<cols;i++)
{
cout<<fields[i].name<<"\t";
}
cout<<endl;
(4)获取每行内容
行处理规则和列处理规则有所不同。
MYSQL_ROW使用的不是指针类型,fetch的是row而不是rows,需要注意一下这些细节:
for(int i=0;i<rows;i++)
{
MYSQL_ROW line=mysql_fetch_row(result);
for(int j=0;j<cols;j++)
{
cout<<line[j]<<"\t";
}
cout<<endl;
}
先找到每一行,然后再在行中找到每一列的内容。
此时就获取成功了。
四、完整代码
#include<iostream>
#include<cstdio>
#include<mysql.h>
using namespace std;
int main()
{
//printf("mysql client version:%s\n",mysql_get_client_info());
string user="test";
string host="127.0.0.1";
string password = "Homelander@2022";
string db="db";
unsigned int port=3306;
MYSQL* my=mysql_init(nullptr);//创建并初始化一个MySQL句柄
if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0)==nullptr)
{
cout<<mysql_error(my)<<endl;
cout<<"connect failed"<<endl;
return 1;
}
cout<<"connect succeed"<<endl;
mysql_set_character_set(my,"utf8");
// string sql="insert into test values(3,\'祖国人\')";
// int res=mysql_query(my,sql.c_str());
// if(res!=0)
// {
// cout<<"execute:"<<sql<<"failed"<<endl;
// return 2;
// }
string sql="select * from account";
int res = mysql_query(my, sql.c_str());
if(res!=0)
{
cout<<"execute:"<<sql<<"failed"<<endl;
return 2;
}
cout << "execute:" << sql << endl;
MYSQL_RES* result=mysql_store_result(my);//存放mysql句柄中最后一次返回
int rows=mysql_num_rows(result);
int cols=mysql_num_fields(result);
cout<<"行数"<<rows<<"列数"<<cols<<endl;
MYSQL_FIELD * fields=mysql_fetch_fields(result);
for(int i=0;i<cols;i++)
{
cout<<fields[i].name<<"\t";
}
cout<<endl;
for(int i=0;i<rows;i++)
{
MYSQL_ROW line=mysql_fetch_row(result);
for(int j=0;j<cols;j++)
{
cout<<line[j]<<"\t";
}
cout<<endl;
}
mysql_close(my);
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38850.html