Linux下C++访问MySQL数据库
由于想要开始了解并学习用LAMP进行web开发,所以昨晚我在Fedora上安装了MySQL,学习了MySQL的几个常用命令。想着在学习进行web开发(PHP访问数据库)之前,先用我熟悉的C++连接数据库试试。由于以前只接触过SQL Server,所以在网上查了很多资料,这里记录一下,以备后用。
一,安装MySQL
当然在使用MySQL之前,首先需要安装。我的linux发行版是Fedora 20,所以我先在MySQL官网下了一个通用版的MySQL-5.6.17-1.linux_glibc2.5.x86_64.rpm-bundle.rar,然后用归档管理器提取出来以后,发现里面有7个rpm文件,我们要使用MySQL数据库,只需要安装MySQL-server和MySQL-client就行了。具体的安装完了以后的设置密码我就不多说了。安装好了以后,在终端输入mysql
-u root -p就可以进入mysql操作环境了。
二,C/C++连接MySQL
连接MySQL数据库有两种方法:第一种是使用ADO连接,不过这种只适合Windows平台;第二种是使用MySQL自己的C API函数连接数据库。
这里我们说的就是使用MySQL的C API函数访问MySQL数据库。C API代码是与MySQL一起提供的,它包含在mysqlclient库中,并允许C/C++程序访问数据库。具体的数据类型和函数描述可以去看MySQL官网的MySQL_C_API参考手册。
这里的例子有使用到几个函数:
| mysql_init() | 获取或初始化MYSQL结构 |
| mysql_real_connect() | 连接到MySQL服务器。 |
| mysql_query() | 执行指定为“以Null终结的字符串”的SQL查询。 |
| mysql_use_result() | 初始化逐行的结果集检索。 |
| mysql_field_count() | 返回上次执行语句的结果集的列数。 |
| mysql_fetch_row() | 从结果集中获取下一行 |
| mysql_num_fields() | 返回结果集中的字段数 |
示例代码:
/*************************************************************************
> File Name: MyDB.h
> Author: SongLee
> E-mail: lisong.shine@qq.com
> Created Time: 2014年05月04日 星期日 23时25分50秒
> Personal Blog: http://songlee24.github.io
************************************************************************/
#ifndef __MYBD_H__
#include<iostream>
#include<string>
#include<mysql/mysql.h>
using namespace std; class MyDB
{
public:
MyDB();
~MyDB();
bool initDB(string host, string user, string pwd, string db_name);
bool exeSQL(string sql);
private:
MYSQL *connection;
MYSQL_RES *result;
MYSQL_ROW row;
}; #endif
/*************************************************************************
> File Name: MyDB.cpp
> Author: SongLee
> E-mail: lisong.shine@qq.com
> Created Time: 2014年05月04日 星期日 23时37分08秒
> Personal Blog: http://songlee24.github.io
************************************************************************/
#include<iostream>
#include<cstdlib>
#include "MyDB.h"
using namespace std; MyDB::MyDB()
{
connection = mysql_init(NULL); // 初始化数据库连接变量
if(connection == NULL)
{
cout << "Error:" << mysql_error(connection);
exit(1);
}
} MyDB::~MyDB()
{
if(connection != NULL) // 关闭数据库连接
{
mysql_close(connection);
}
} bool MyDB::initDB(string host, string user, string pwd, string db_name)
{
// 函数mysql_real_connect建立一个数据库连接
// 成功返回MYSQL*连接句柄,失败返回NULL
connection = mysql_real_connect(connection, host.c_str(),
user.c_str(), pwd.c_str(), db_name.c_str(), 0, NULL, 0);
if(connection == NULL)
{
cout << "Error:" << mysql_error(connection);
exit(1);
}
return true;
} bool MyDB::exeSQL(string sql)
{
// mysql_query()执行成功返回0,失败返回非0值。与PHP中不一样
if(mysql_query(connection, sql.c_str()))
{
cout << "Query Error:" << mysql_error(connection);
exit(1);
}
else
{
result = mysql_use_result(connection); // 获取结果集
// mysql_field_count()返回connection查询的列数
for(int i=0; i < mysql_field_count(connection); ++i)
{
// 获取下一行
row = mysql_fetch_row(result);
if(row <= 0)
{
break;
}
// mysql_num_fields()返回结果集中的字段数
for(int j=0; j < mysql_num_fields(result); ++j)
{
cout << row[j] << " ";
}
cout << endl;
}
// 释放结果集的内存
mysql_free_result(result);
}
return true;
}
/*************************************************************************
> File Name: main.cpp
> Author: SongLee
> E-mail: lisong.shine@qq.com
> Created Time: 2014年05月05日 星期一 00时30分45秒
> Personal Blog: http://songlee24.github.io
************************************************************************/
#include<iostream>
#include "MyDB.h"
using namespace std; int main()
{
MyDB db;
db.initDB("localhost", "root", "songlee", "student");
db.exeSQL("select * from student_info");
return 0;
}
基本步骤就是:
- 使用mysql_init()初始化连接
- 使用mysql_real_connect()建立一个到mysql数据库的连接
- 使用mysql_query()执行查询语句
- result = mysql_use_result(conn)获取结果集
- mysql_field_count(conn)获取查询的列数,mysql_num_fields(result)获取结果集的字段数
- 通过mysql_fetch_row(result)不断获取下一行,然后循环输出
- 释放结果集所占内存mysql_free_result(result)
- mysql_close(conn)关闭连接
三,创建所需数据库
通过C++查询数据库的数据,当然你得创建所需数据库,可以通过代码创建,也可以在终端创建数据库。首先通过用户名和密码进入mysql:
mysql -u root -p
1,查看所有数据库:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
MySQL默认有自带的数据库,mysql库存放着mysql的系统和用户权限信息,我们改密码和新增用户,实际上就是对这个库进行操作。
2,创建数据库:
mysql> CREATE DATABASE student;
Query OK, 1 row affected (0.00 sec)
3,建表:
mysql> CREATE TABLE student_info(
-> stu_num CHAR(20) NOT NULL,
-> stu_name CHAR(10) NOT NULL,
-> stu_age int NOT NULL,
-> stu_grade CHAR(5) NOT NULL,
-> stu_score int,
-> PRIMARY KEY(stu_num));
Query OK, 0 rows affected (0.38 sec)
4,查看所有数据表
mysql> use student;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_student |
+-------------------+
| student_info |
+-------------------+
1 row in set (0.00 sec)
5,查看数据表的结构(字段)
mysql> describe student_info;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| stu_num | char(20) | NO | PRI | NULL | |
| stu_name | char(10) | NO | | NULL | |
| stu_age | int(11) | NO | | NULL | |
| stu_grade | char(5) | NO | | NULL | |
| stu_score | int(11) | YES | | NULL | |
+-----------+----------+------+-----+---------+-------+
5 rows in set (0.10 sec)
6,插入数据
mysql> INSERT INTO student_info VALUES("U201018113", "SongLee", 23, "1007", 85);
Query OK, 1 row affected (0.10 sec)
7,查询数据
mysql> SELECT * FROM student_info;
+------------+----------+---------+-----------+-----------+
| stu_num | stu_name | stu_age | stu_grade | stu_score |
+------------+----------+---------+-----------+-----------+
| U201018113 | SongLee | 23 | 1007 | 85 |
+------------+----------+---------+-----------+-----------+
1 row in set (0.00 sec)
四,运行程序获取MySQL数据库数据
下面来编译运行上面的示例代码,首先进行编译,我写了一个Makefile文件:
mydb:main.cpp MyDB.cpp
g++ -o mydb main.cpp MyDB.cpp
注意,g++前面是tab而不是空格。然后在终端输入make,回车。出现了错误:
[songlee@localhost ~]$ make
g++ -o mydb main.cpp MyDB.cpp
In file included from main.cpp:9:0:
MyDB.h:11:18: 致命错误:mysql.h:没有那个文件或目录
#include<mysql/mysql.h>
^
编译中断。
In file included from MyDB.cpp:10:0:
MyDB.h:11:18: 致命错误:mysql.h:没有那个文件或目录
#include<mysql/mysql.h>
^
编译中断。
make: *** [mydb] 错误 1
找不到mysql.h头文件。。。于是除了MySQL-server-和MySQL-client-之外,我又安装了devel和shared包:
sudo rpm -ivh MySQL-devel-5.6.17-1.linux_glibc2.5.x86_64.rpm
sudo rpm -ivh MySQL-shared-5.6.17-1.linux_glibc2.5.x86_64.rpm
再make一次,mysql.h头文件找到了,但是又出现了问题:
[songlee@localhost ~]$ make
g++ -o mydb main.cpp MyDB.cpp
/tmp/cc9ZZHBx.o:在函数‘MyDB::MyDB()’中:
MyDB.cpp:(.text+0x13):对‘mysql_init’未定义的引用
MyDB.cpp:(.text+0x35):对‘mysql_error’未定义的引用
/tmp/cc9ZZHBx.o:在函数‘MyDB::~MyDB()’中:
MyDB.cpp:(.text+0x8b):对‘mysql_close’未定义的引用
/tmp/cc9ZZHBx.o:在函数‘MyDB::initDB(std::string, std::string, std::string, std::string)’中:
MyDB.cpp:(.text+0x11a):对‘mysql_real_connect’未定义的引用
MyDB.cpp:(.text+0x13c):对‘mysql_error’未定义的引用
/tmp/cc9ZZHBx.o:在函数‘MyDB::exeSQL(std::string)’中:
MyDB.cpp:(.text+0x1a6):对‘mysql_query’未定义的引用
MyDB.cpp:(.text+0x1be):对‘mysql_error’未定义的引用
MyDB.cpp:(.text+0x1f4):对‘mysql_use_result’未定义的引用
MyDB.cpp:(.text+0x218):对‘mysql_fetch_row’未定义的引用
MyDB.cpp:(.text+0x284):对‘mysql_num_fields’未定义的引用
MyDB.cpp:(.text+0x2b2):对‘mysql_field_count’未定义的引用
MyDB.cpp:(.text+0x2cf):对‘mysql_free_result’未定义的引用
collect2: 错误:ld 返回 1
make: *** [mydb] 错误 1
找到了头文件,但是相关函数都未定义,原因是因为没有链接需要的库libmysqlclient.so,终端输入命令mysql_config --libs:
[songlee@localhost ~]$ mysql_config --libs
-L/usr/lib64 -lmysqlclient -lpthread -lm -lrt -ldl
将选项-L/usr/lib64 -lmysqlclient加入gcc/g++命令中,即修改Makefile文件为:
mydb:main.cpp MyDB.cpp
g++ -L/usr/lib64 -lmysqlclient -o mydb main.cpp MyDB.cpp
再次make成功了,运行程序:
[songlee@localhost ~]$ make
g++ -L/usr/lib64 -lmysqlclient -o mydb main.cpp MyDB.cpp
[songlee@localhost ~]$ ./mydb
U201018113 SongLee 23 1007 85
这样,MySQL数据库访问成功!
Linux下C++访问MySQL数据库的更多相关文章
- Linux下自动备份MySQL数据库并上传到远程FTP服务器
Linux下自动备份MySQL数据库并上传到远程FTP服务器且删除指定日期前的备份Shell脚本 说明: 1.备份MySQL数据库存放目录/var/lib/mysql下面的xshelldata数据库 ...
- Linux下定时备份MySQL数据库的Shell脚本
Linux下定时备份MySQL数据库的Shell脚本 对任何一个已经上线的网站站点来说,数据备份都是必须的.无论版本更新还是服务器迁移,备份数据的重要性不言而喻.人工备份数据的方式不单耗费大量时间 ...
- Linux下C连接MySql数据库
目录: 一.解决小的问题: 二.大问题,如果你不小心把/usr/lib的所属用户改了导致sudo命令用不了: 三.C连接MySql编程本身: 其实写这个程序真的很简单,十多分钟的事情,只是以前没在Li ...
- Linux下远程连接MySQL数据库
估计搞了一个多小时才把这个远程连接搞好.一台本地电脑,一台云服务器,都是linux系统. 步骤 在服务器端开启远程访问 首先进入mysql数据库,然后输入下面两个命令: grant all privi ...
- Linux下如何启用MySQL数据库远程访问
远程连接MySQL出于安全考虑,一般都关闭了远程访问,但有时候需要提供远程访问数据库的服务,下面我们快速学习下: 第一步:修改my.cnf文件使用文本编辑器去编辑MySQL服务器的配置文件my.cnf ...
- linux 下C++查询mysql数据库
上一节我们看了怎么使用mysql提供的API来连接mysql数据库,现在来看看怎么执行一条简单的查询语句,并且把查询的结果显示出来. 准备工作:首先新建了一个数据库inote,在这个数据库下面新建了一 ...
- Linux下C++连MySQL数据库
1.查看本地有没有安装mysql,命令就是mysql,如果有这个命令就表示安装了mysql数据库软件.如果没有就自行安装. MySQL-server-4.0.16-0.i386.rpm MySQL-c ...
- Linux下如何从mysql数据库里导出导入数据
https://blog.csdn.net/u012884402/article/details/47337701 一. 表的导入 1.进入数据库 mysql 数据库名 2.查看表 show tab ...
- Linux下第一次使用MySQL数据库,设置密码
在终端下输入:/etc/rc.d/init.d/mysqld status 查看MySQL状态,看看是否运行. 没有运行的话就输入:/etc/rc.d/init.d/mysqld start 这时,就 ...
随机推荐
- TypeError: string indices must be integers, not str
1. TypeError: string indices must be integers, not str 字符串类型取第index个字符的时候,应该传入int而不是str.如 1 a='abcde ...
- ES6:Generator函数(1)
Generator函数是ES6提供的一种异步编程解决方案.它会返回一个遍历器对象 function* helloWorldGenerator(){ yield “hello”; yield “worl ...
- Elasticsearch--搜索
目录 基本知识 查询结果返回设置:版本值.得分限制.定制返回字段 搜索类型 搜索执行偏好 基本查询 过滤器类型 高亮 控制高亮的片段 验证查询 数据排序 查询重写 基本知识 查询结果返回设置:版本值. ...
- 树莓派连接arduino(USB串口通讯)
2018-06-0115:12:19 https://blog.csdn.net/song527730241/article/details/50884890 重要步骤 查看端口:(ttyUSB0或 ...
- 关于Python多线程condition变量的应用
''' 所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据. 它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且 ...
- [算法天天练] - C语言实现双向链表(一)
双向链表是比较常见的,主要是在链表的基础上添加prev指针,闲话少说直接上代码吧(这个也是网上一个大神的思路,真心不错,条理清楚,逻辑缜密) 主要也是为了学习,贴上我所调试成功的代码(Linux环境下 ...
- android studio java.io.IOException:setDataSourse fail.
这一次是针对Android开发中的一个小问题,权限获取的问题. 在写了一个一个小Android程序的时候,有时候普需要获取本机的文件(Audio&Video),这时候如果不加权限就会出现这种情 ...
- Python+selenium学习(一) 打开Firefox浏览器,IE浏览器和Chrome浏览器
from selenium import webdriver # open Firefox #driver=webdriver.Firefox() # Open IE #driver=webdrive ...
- Redis系列(二)--分布式锁、分布式ID简单实现及思路
分布式锁: Redis可以实现分布式锁,只是讨论Redis的实现思路,而真的实现分布式锁,Zookeeper更加可靠 为什么使用分布式锁: 单机环境下只存在多线程,通过同步操作就可以实现对并发环境的安 ...
- openssl 下的对称加密和非对称加密
对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法. 非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个负责解 ...