一个程序如何连接数据库?以C++为例
一、场景模拟
假设我们现在需要维护用户信息,那么我们需要在数据库中创建一个用户信息表来管理用户,表内容包括用户名,密码;
1.1、首先我们要创建一个专门来管理用户信息表所在的数据库的mysql登陆用户:
那么我们先来创建一个登陆mysql的用户吧,把它取名为test,密码设为123456,让它来管理这个用户表所在的数据库:
-
mysql -uroot -p
这条命令是以root身份登陆到mysql,-u后面跟着要登陆的用户名,-p回车后会让你输入你的密码,如果你登陆成功,你会看到以下下界面:
接下来我们要做的是用root创建一个数据库并创建一个登陆mysql的用户,让这个用户来管理这个库:
-
create database testsql;
这条命令是创建一个名 为testsql的数据库,如果你创建成功通过show databases;可以查看到创建好的数据库:
create user 'test'@'localhost' identified by '123456' ;
这条命令是创建一个用户,用户名为test,密码为123456,注意:这里的user后面跟的是用户名,@后面跟的是允许这个用户在哪里登陆,localhost表示在本地登陆, identified用来设置密码; 如果你创建成功你在mysql的user表中能看到你的用户名:
上图中的 N 代表的是没有权限 ,Y代表赋予了权限 ,所以接下来我们要做的是给这个用户赋予权限:
在这之前我们先来看看没有权限的mysql用户是怎么样的:
mysql -utest -p
然后输入密码 :123456 ,然后我们就用刚才创建好的用户登陆进来了:
查看当前数据库跟表:
我们再用root管理员用户查看数据库对比:
1.2、用root管理员赋予test用户权限并使用test用户创建一个维护'用户信息的用户表'(注意这里的'用户信息表'的用户指的是客户,指的是业务上的用户)
grant all on testsql.* to 'test'@'localhost';
然后我们再登陆test用户查看数据库:
现在就可以用test用户随意访问testsql这个数据库,并随意建表了:
登陆test账号访问testsql数据库并建一个用户表:
-
use testsql;
-
create table users(id int primary key auto_increment , name varchar(32) not null unique key, pwd varchar(32) not null);
-
show tables;
-
show create table users \G
-
select*from users;
这样我们就创建好表了,现在这个表里什么数据都没有,接下来我们就用C++程序来连接一下吧!
二、C++程序连接数据库
2.1、连接前的准备
包含必要头文件,准备好登陆mysql的用户名密码,获取初始化后的MYSQL*句柄:
#include <iostream>
#include<unistd.h>
using namespace std;
//实现连接数据库的程序
#include <mysql/mysql.h>//连接数据准备
const string username="test";
const string userpwd="123456";
const string host="localhost";
const unsigned int port=3306;
int main()
{//1.初始化MYSQL* my=mysql_init(nullptr);if(nullptr==my){//初始化失败return -1;}//2.连接if(nullptr== mysql_real_connect(my,host.c_str(),\username.c_str(),userpwd.c_str(),\"testsql",port,nullptr,0))return -2;//连接成功sleep(10);//这里我故意设10s 用来运行程序后登陆mysql 的root账号来查看连接状态//关闭mysqlmysql_close(my);return 0;
}
编译程序运行,登陆root账号用show processlist 命令查看连接数据库的用户:
-
g++ -o test mysql_test.cpp -lmysqlclient;
运行前:
运行后:
OK,到这里连接数据库已经成功了,接下来就是用C++程序对数据库进行增删查改了!!
2.2、增删改
#include <iostream>
#include<unistd.h>
using namespace std;
//实现连接数据库的程序
#include <mysql/mysql.h>//连接数据准备
const string username="test";
const string userpwd="123456";
const string host="localhost";
const unsigned int port=3306;
int main()
{//1.初始化MYSQL* my=mysql_init(nullptr);if(nullptr==my){//初始化失败return -1;}//2.连接if(nullptr== mysql_real_connect(my,host.c_str(),\username.c_str(),userpwd.c_str(),\"testsql",port,nullptr,0))return -2;//连接成功//sleep(10);//-----------------------------------------------------------------------------------//新增代码 数据库增加用户信息string sql="insert into users(name,pwd) values('张三','123123');";if(mysql_query(my,sql.c_str())!=0){//查询失败return -3;}
//---------------------------------------------------------------------------------//关闭mysqlmysql_close(my);return 0;
}
编译运行后查表:
成功向users表中完成插入!!
我们插入多几条数据,然后查表:
ok接下来我们进行删除操作,删除名为李四的用户:
ok接下来我们进行更新操作,更新王五的密码为654321:
查表们看到王五的pwd信息被修改为654321!!! :
以上增删改完成,接下来我们要进行查询操作!!!!(这个比增删改要复杂点)!!!
2.3、查询操作
第一步:将查询结果提取到MYSQL_RES类型的结构体中:
这里用到MYSQL的库函数:
MYSQL_RES* mysql_store_result(MYSQL*);
//1.这里的函数参数为MYSQL*,即一开始连接数据库时初始化的句柄
//2.如果提取成功返回一个MYSQL_RES的结构体指针,失败则返回nullptr
第二步:通过返回的res获取查询表的行数、列数:
这里用到获取行、列数的接口:
unsigned long long mysql_num_rows(MYSQL_RES*);
unsigned long long mysql_num_fields(MYSQL_RES*);
//1.传入参数为MYSQL_RES结构体指针
//2.第一个个函数返回值为行数,第二个函数返回值为列数,类型为unsigned long long;
第三步:获取内容行:
这里用到的接口是一个会自动迭代的接口:
MYSQL_ROW mysql_fetch_row(MYSQL_RES*);
//1. 传入参数为MYSQL_RES结果集的结构体指针
//2. 返回的是一个char**类型的MYSQL_ROW
编译运行:
第四步:如果想获取属性行用以下接口:
MYSQL_FILELD* mysql_fetch_fields(MYSQL_RES*);
//1.传参为MYSQL_RES*
//2.如果成功返回一个用来获取属性的结构体指针,失败返回nullptr
再编译运行:
演示的全部代码:
#include <iostream>
#include<unistd.h>
using namespace std;
//实现连接数据库的程序
#include <mysql/mysql.h>//连接数据准备
const string username="test";
const string userpwd="123456";
const string host="localhost";
const unsigned int port=3306;
int main()
{//1.初始化MYSQL* my=mysql_init(nullptr);if(nullptr==my){//初始化失败return -1;}//2.连接if(nullptr== mysql_real_connect(my,host.c_str(),\username.c_str(),userpwd.c_str(),\"testsql",port,nullptr,0))return -2;//连接成功//sleep(10);//-----------------------------------------------------------------------------------//新增代码 数据库增加用户信息//string sql="insert into users(name,pwd) values('张三','123123');";//string sql="insert into users(name,pwd) values('李四','123123');";//string sql="insert into users(name,pwd) values('王五','123123');";//string sql="delete from users where name='李四'";//string sql="update users set pwd='654321' where name='王五'";string sql="select* from users;";if(mysql_query(my,sql.c_str())!=0){//查询失败return -3;}//提取结果集MYSQL_RES* res=mysql_store_result(my);if(res==nullptr){//提取结果集失败return -4;}//通过结果集获取行数,列数int row=mysql_num_rows(res);int filed=mysql_num_fields(res);//获取属性行MYSQL_FIELD*fileds_array= mysql_fetch_field(res);for(int i=0;i<filed;i++){cout<<fileds_array[i].name<<"\t";}cout<<endl;//获取内容行for(int i=0;i<row;i++){MYSQL_ROW r=mysql_fetch_row(res);for(int j=0;j<filed;j++){cout<<r[j]<<"\t";}cout<<endl;}//---------------------------------------------------------------------------------//关闭mysqlmysql_close(my);return 0;
}
三、总结
3.1、这里用到的接口前面的都好理解,难点在mysql_fetch_row()和mysql_fetch_fields()这两个接口
我们这样理解:
同理获取属性行的接口类似;
以上为本次分享的所有内容,如果对你有所帮助记得点赞收藏+关注哦!!
咱下期见!!!