玖叶教程网

前端编程开发入门

docker环境linuxubuntu C连接mysql数据 docker容器连接主机mysql

一、在ubuntu系统中C/C++连接mysql

1. 更新并升级软件源

apt-get update
apt-get upgrade

2. 安装c/c++解释器

apt-get install g++

安装后,执行 g++ --version 可显示版本信息

3. 安装mysql服务器(若不使用本地数据库,而使用远程数据库,或docker环境下使用宿主机mysql ,可跳过此步)

apt-get install mysql-client mysql-server

安装mysql时,中途会提示你设置用户密码等,请牢记!并在第6步的c++程序中,修改相应的数据库配置变量!顺便新建一个数据库供后面测试:

create database mydatabase; # 新建数据库

4. 安装C/C++连接mysql驱动包

apt-get install libmysqlclient-dev

5. 编写C++程序进行测试

vim test.cpp
#include<stdio.h>
#include<mysql/mysql.h>
const char *db_host="localhost";
const char *db_user="root";
const char *db_pass="rootroot";
const char *db_name="mydatabase";
const int db_port=3306;
int main ()
{
 MYSQL *mysql=mysql_init(NULL); //初始化数据库连接变量
 if(mysql==NULL)
 {
 printf("Error:%s\n",mysql_error(mysql));
 exit(1);
 }
 mysql = mysql_real_connect(mysql,db_host,db_user,db_pass,db_name, db_port,NULL,0); //连接mysql
 if(mysql)
 printf("Success!\n"); //连接成功
 else printf("Failed!\n");
 return 0;
}

6. 编译C++程序并执行

g++ test.cpp -o test -lmysqlclient

注:末尾务必加上 -lmysqlclient 否则编译时找不到mysql库

./test

这是执行程序,如果成功连接mysql,则会显示 Success!

二、在docker容器ubuntu系统内使用C/C++连接宿主机的mysql

注意:请保证宿主机已安装mysql服务器,并开启服务。

1. 编写makefile

# 第一步,增加特权用户

mysql -u root -p # 进入mysql,回车后需要输入root密码
# 下面在mysql交互里修改root用户的可访问地址
grant all privileges on *.* to 'testuser'@'%' identified by '123456';
flush privileges;
exit;
# testuser是新建的用户名,其密码是123456
# '%' 允许访问数据库的IP地址,%意思是任意IP,也可以指定IP
# flush privileges 刷新权限信息 
# 第二步,允许外网连接mysql服务器
vim /etc/mysql/mysql.conf.d/mysqld.cnf
# 找到 bind-address = 127.0.0.1 这一行,注释掉(行首加#)
②宿主机是windows(宿主机操作)
一步:创建允许外网访问的特权用户。
# 请使用管理员权限运行cmd
# 进入到mysql的安装目录里的/bin/目录下,再执行:
.\mysql -uroot -p #进入mysql交互
# 下面在mysql交互里修改root用户的可访问地址
grant all privileges on *.* to 'testuser'@'%' identified by '123456';
flush privileges;
exit;
# testuser是新建的用户名,其密码是123456
# '%' 允许访问数据库的IP地址,%意思是任意IP,也可以指定IP
# flush privileges 刷新权限信息

2. 运行makefile,生成镜像(最后有个点。myimage是镜像名字,tag是版本号)

$ docker build -t myimage:tag .

3. 生成容器并进入

docker run -it myimage:tag /bin/bash

4. 使宿主机允许docker容器连接mysql服务

缘由分析: 容器内访问localhost是访问容器本身,访问不到宿主机,故先查宿主机ip。容器内执行 ifconfig 可以查看ip:


【未解决的问题】:按说现在可以直接通过ip:172.17.0.1连接宿主机了,但实际测试中总是不行,使用WIFI局域网的ip都连通了,唯独172.17.0.1拒绝访问。恳请知情的大神在评论区指点!

若ifconfig和ping命令不识别,请安装插件:

apt install net-tools # ifconfig
apt-get install inetutils-ping # ping
apt-get install telnet # telnet

但是默认情况下,宿主机的mysql只允许本地(localhost)访问,docker容器是拒绝访问的。因此需要修改宿主机mysql用户的权限。

①宿主机是ubuntu系统(宿主机操作)

两步,1.创建允许外网访问的特权用户,2.修改mysql配置文件,使其接受外网连接。

# 第一步,增加特权用户
mysql -u root -p # 进入mysql,回车后需要输入root密码
# 下面在mysql交互里修改root用户的可访问地址
grant all privileges on *.* to 'testuser'@'%' identified by '123456';
flush privileges;
exit;
# testuser是新建的用户名,其密码是123456
# '%' 允许访问数据库的IP地址,%意思是任意IP,也可以指定IP
# flush privileges 刷新权限信息
# 第二步,允许外网连接mysql服务器
vim /etc/mysql/mysql.conf.d/mysqld.cnf
# 找到 bind-address = 127.0.0.1 这一行,注释掉(行首加#)

②宿主机是windows(宿主机操作)

一步:创建允许外网访问的特权用户。

# 请使用管理员权限运行cmd
# 进入到mysql的安装目录里的/bin/目录下,再执行:
.\mysql -uroot -p #进入mysql交互
# 下面在mysql交互里修改root用户的可访问地址
grant all privileges on *.* to 'testuser'@'%' identified by '123456';
flush privileges;
exit;
# testuser是新建的用户名,其密码是123456
# '%' 允许访问数据库的IP地址,%意思是任意IP,也可以指定IP
# flush privileges 刷新权限信息

【未解决的问题】:按说现在可以直接通过ip:172.17.0.1连接宿主机了,但实际测试中总是不行,使用WIFI局域网的ip都连通了,唯独172.17.0.1拒绝访问。恳请知情的大神在评论区指点!

5. 在容器内编写C++程序【关注ip与端口】

vim test.cpp
#include<stdio.h>
#include<mysql/mysql.h>
const char *db_host="localhost";
const char *db_user="root";
const char *db_pass="rootroot";
const char *db_name="mydatabase";
const int db_port=3306;
int main ()
{
 MYSQL *mysql=mysql_init(NULL); //初始化数据库连接变量
 if(mysql==NULL)
 {
 printf("Error:%s\n",mysql_error(mysql));
 exit(1);
 }
 mysql = mysql_real_connect(mysql,db_host,db_user,db_pass,db_name, db_port,NULL,0); //连接mysql
 if(mysql)
 printf("Success!\n"); //连接成功
 else printf("Failed!\n");
 return 0;
}

6. 编译C++程序并执行

g++ test.cpp -o test -lmysqlclient

注:末尾务必加上 -lmysqlclient 否则编译时找不到mysql库

./test

这是执行程序,如果成功连接mysql,则会显示 Success!

三、libmysqlclient-dev库常用函数

示例1

#include<stdio.h>

#include<mysql/mysql.h>

 

const char *db_host="172.17.0.1";

const char *db_user="root";

const char *db_pass="rootroot";

const char *db_name="mydatabase";

const int db_port=3306;

 

int main ()

{

 

 MYSQL *mysql=mysql_init(NULL); //初始化数据库连接变量

 if(mysql==NULL)

 {

 printf("Error:%s\n",mysql_error(mysql));

 exit(1);

 }

 mysql = mysql_real_connect(mysql,db_host,db_user,db_pass,db_name, db_port,NULL,0); //连接mysql

 if(mysql)

 printf("Suucess!\n"); //连接成功

 else printf("Failed!\n");

 return 0;

}

6. 编译C++程序并执行

g++ test.cpp -o test -lmysqlclient

 注:末尾务必加上 -lmysqlclient 否则编译时找不到mysql库

./test

 这是执行程序,如果成功连接mysql,则会显示 Success! 

 

三、libmysqlclient-dev库常用函数

示例1

#include <iostream>

#include <cstdlib>

#include <string>

#include <vector>

#include <mysql/mysql.h>

using namespace std;

 

int main(){

 

 const char *host = "localhost";

 const char *user = "root";

 const char *upwd = "root";

 const char *dbs = "test";

 unsigned int port = 3306;

 

 

 MYSQL mydata;

 

 if(0==mysql_library_init(0,NULL,NULL)){

 cout<<"mysql_library_init() successed!!"<<endl;

 }else{

 cout<<"mysql_library_init() failed!!"<<endl;

 return -1;

 }

 

 //初始化数据结构

 if(NULL != mysql_init(&mydata)){

 cout<<"初始化数据结构成功!"<<endl;

 }else{

 cout<<"初始化数据结构失败"<<endl;

 return -1;

 }

 

 //设置数据库编码类型

 if(0==mysql_options(&mydata,MYSQL_SET_CHARSET_NAME,"utf8")){

 cout<<"设置数据库编码类型成功!"<<endl;

 }else{

 cout<<"设置数据库编码类型失败!"<<endl;

 return -1;

 }

 

 //连接数据库

 if(NULL != mysql_real_connect(&mydata,host,user,upwd,dbs,port,NULL,0)){

 cout<<"数据库连接成功了!"<<endl;

 }else{

 cout<<"数据库连接失败了!!"<<endl;

 return -1;

 }

 

 //插入数据

 //string sqlstr;

 //sqlstr="INSERT INTO user(`username`, `password`) VALUES ('test', 'test123');";

 //if(0==mysql_query(&mydata,sqlstr.c_str())){

 // cout<<"插入数据成功"<<endl;

 //}else{

 // cout<<"插入数据失败了!!"<<endl;

 //}

 

 string sqlstr_select = " select * from user;";

 //显示查询结果

 MYSQL_RES *result=NULL;

 if(0==mysql_query(&mydata,sqlstr_select.c_str())){

 cout<<"查询成功!"<<endl;

 

 //一次性取得数据集 

 result =mysql_store_result(&mydata);

 

 //取得并打印行数 

 my_ulonglong rowcount = mysql_num_rows(result); 

 cout << "row count: " << rowcount << endl; 

 //取得并打印各字段的名称 
 unsigned int fieldcount = mysql_num_fields(result); 
 MYSQL_FIELD *field = NULL;
 for (unsigned int i = 0; i < fieldcount; i++) { 
 field = mysql_fetch_field_direct(result, i); 
 cout << field->name << "\t\t";
 } 
 cout << endl; 
 ////打印各行 
 //MYSQL_ROW row = NULL; 
 //row = mysql_fetch_row(result); 
 //while (NULL != row) { 
 // for (int i = 0; i < fieldcount; i++) { 
 // cout << row[i] << "\t\t"; 
 // } 
 // cout << endl; 
 // row = mysql_fetch_row(result); 
 //} 
 }else{
 cout << "mysql_query() select data failed" << endl; 
 mysql_close(&mydata); 
 return -1; 
 }
 mysql_close(&mydata);
 mysql_library_end();
 return 0;
}

示例2

#include<stdio.h>
#include<stdlib.h>

#include<string.h>

#include<string.h>

#include<time.h>

#include<mysql/mysql.h>

#include<unistd.h>

#include<sys/types.h>

#include<sys/wait.h>

 

const char *db_host="192.168.31.16";

const char *db_user="testuser";

const char *db_pass="123456";

const char *db_name="woj";

const int db_port=3306;

 

 

 

static MYSQL *mysql; //数据库连接对象

static MYSQL_RES *mysql_res; //sql查询结果

static MYSQL_ROW mysql_row; //sql查询到的单行数据

char sql[256]; //暂存sql语句

 

 

void get_wating_solution(int solution_queue[],int &queueing_cnt) //从solution表读取max_running个待判编号

{

 queueing_cnt=0;

 sprintf(sql,"SELECT id FROM solution WHERE result<=%d ORDER BY id ASC limit %d",OJ_WT,max_running);

 if(mysql_real_query(mysql,sql,strlen(sql))!=0){

 printf("select failed!\n");

 exit(1);

 }

 mysql_res=mysql_store_result(mysql); //保存查询结果

 char sid_str[max_running*11]="\0";

 while(mysql_row=mysql_fetch_row(mysql_res)) //将结果读入判题队列

 {

 solution_queue[queueing_cnt++]=atoi(mysql_row[0]);

 if(sid_str[0]!='\0')strcat(sid_str,",");

 strcat(sid_str,mysql_row[0]);

 }

 if(queueing_cnt>0) //更新已读入的solution的result

 {

 sprintf(sql,"UPDATE solution SET result=%d WHERE id in (%s)",OJ_QI,sid_str); //更新状态
 mysql_real_query(mysql,sql,strlen(sql));
 
}
int main ()
{
 mysql = mysql_init(NULL); //初始化数据库连接
 mysql = mysql_real_connect(mysql,db_host,db_user,db_pass,db_name, db_port,NULL,0);
 if(!mysql){
 printf("Error: Can't connect to database!\n\n");
 exit(1);
 }
 static int running_cnt=0,queueing_cnt; //排队数
 static int solution_queue[max_running]; //队列
 get_wating_solution(solution_queue,queueing_cnt);
 mysql_close(mysql);
 return 0;
}

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言