赞
踩
使用C/C++访问MySQL,首先需要MySQL的开发者库
这里提供两种方法:
在MySQL的官网下载
MtySQL Community Downloads
红框里的是各种语言的开发者包,本篇博客介绍C语言的接口,也就是C API
选择和要访问的MySQL服务器一样环境,版本的开发者包
Archives
可以看到历史版本
注意不要
下载成Debug版本
下载完成后,在云服务上使用rz
命令将Windows的文件拷贝到云服务上
使用tar xzf 压缩包
解压,然后可以再改个名
里面有很多的库文件,我们主要使用include里的mysql.h
第一种方法先介绍到这
如果你的MySQL是通过yum源安装的,那么yum在安装MySQL的同时,已经帮我们下好了开发者工具,并且配置好了
头文件默认放在/usr/include/mysql
中
动静态库在/lib64/mysql
中
如果没有,使用以下命令安装
yum install mysql-devel
第三方库的使用可以移步【Linux】动静态库
这里简要说一下使用
gcc/g++默认搜索的头文件路径是/user/include
默认搜索的库路径是
/usr/local/lib
/usr/lib
/lib
编译可执行时需要如下命令
g++ -o -std=c++11 -I/usr/include/mysql -L/lib64/mysql -lmysqlclient
-I选项:
指认使用的头文件。如果代码中#include<mysql/mysql.h>,其实可以不带-I选项,因为g++找得到
-L选项:
指认库路径
-l:
指认链接的库的名字
简单使用
makefile
mytest:test.cc
g++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient
.PHONY:clean
clean:
rm -f mytest
test.cc
#include<iostream>
#include<mysql/mysql.h>
int main()
{
std::cout<<"mysql client version: "<<mysql_get_client_info()<<std::endl;
return 0;
}
mysql_get_client_info()是mysql.h中的一个函数,可以获取和次开发包相应对应的mysql客户端版本
运行成功
C API的各种接口和变量都可以在官方文档查找
MySQL官方文档(全)
下拉找到Conectors&APIs,可以找到C API,选择合适的版本C API 8.0
左侧的C API Basic Interface
里的C API Funciton-reference
是各函数C API函数
C API Basic Data Structures
是各种变量,结构体C API结构体
MySQL本质是网络服务
C API使用MYSQL结构体管理客户端与服务器的链接等信息
初始化MYSQL结构体
MYSQL * mysql_init(MYSQL*mysql)
参数可以传nullptr,如果传入一个MYSQL,则会重置此MYSQL,结果都是返回一个新的MYSQL
链接MySQL
MYSQL * mysql_real_connect(MYSQL*mysql,
const char*host,
const char*user,
const char*passwd,
const char*db,
unsigned int port,
const char*unix_socket,
unsigned long clientflag
)
MYSQL是C API中一个非常重要的变量,里面内容非常丰富,有port,dbname,charset等链接基本参数,也包含一个
st_mysql_methods
的结构体变量,里面保存着很多函数指针,这些函数指针将会在数据库连接成功后的各种数据库操作中调用
如下是MYSQL结构体的定义
typedef struct st_mysql { NET net; /* Communication parameters */ unsigned char *connector_fd; /* ConnectorFd for SSL */ char *host,*user,*passwd,*unix_socket,*server_version,*host_info; char *info, *db; struct charset_info_st *charset; MYSQL_FIELD *fields; MEM_ROOT field_alloc; my_ulonglong affected_rows; my_ulonglong insert_id; /* id if insert on table with NEXTNR */ my_ulonglong extra_info; /* Not used */ unsigned long thread_id; /* Id for connection in server */ unsigned long packet_length; unsigned int port; unsigned long client_flag,server_capabilities; unsigned int protocol_version; unsigned int field_count; unsigned int server_status; unsigned int server_language; unsigned int warning_count; struct st_mysql_options options; enum mysql_status status; my_bool free_me; /* If free in mysql_close */ my_bool reconnect; /* set to 1 if automatic reconnect */ /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; my_bool unused1; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; void *thd; /* Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag from mysql_stmt_close if close had to cancel result set of this object. */ my_bool *unbuffered_fetch_owner; /* needed for embedded server - no net buffer to store the 'info' */ char *info_buffer; void *extension; } MYSQL;
- host:链接的MySQL服务器的主机IP
- user:登录的用户
- passwd:用户密码
- db:使用的数据库
- port:MySQL服务器的端口号
- unix_socket:域间套接字(管道通信),通常为nullptr
- clientflag:通常为0,其他设置可查看官网
连接成功会将host,port等信息绑定到MYSQL中
失败则返回空指针
可以在MySQL中使用show processlist
查看当前连接的用户
关闭连接
void mysql_close(MYSQL*mysql);
int mysql_query(MYSQL*mysql,const char*sql);
mysql:要哪个连接执行
sql:具体的sql语句
成功返回0,失败返回非0
案例:
准备了一个用户名为’ljh’,密码为123456,登录方式为localhost的用户
因为本地连接,所以IP使用本地环回127.0.0.1
端口号默认为3306
使用test数据库,其中有一个user表
表结构如下:
mysql> desc user;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| telephone | varchar(11) | YES | UNI | NULL | |
+-----------+-------------+------+-----+---------+----------------+
连接代码如下:
#include<iostream> #include<string> #include<mysql/mysql.h> const std::string host ="127.0.0.1"; const std::string user="ljh"; const std::string passwd="123456"; const std::string db="test"; const unsigned int port=3306; int main() { //初始化 MYSQL*conn=mysql_init(nullptr); if(conn==nullptr) { //初始化失败 std::cerr<<"mysql init error"<<std::endl; return 1; } //建立连接 conn=mysql_real_connect(conn,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0); if(conn==nullptr) { std::cerr<<"mysql connect error"<<std::endl; return 2; } std::cout<<"mysql connect success"<<std::endl; //关闭连接 mysql_close(conn); return 0; }
insert操作
在建立连接成功后
const std::string sql="insert into user (name,age,telephone) values ('zhangsan',23,'123456')";
int n=mysql_query(conn,sql.c_str());
if(n==0)
{
std::cout<<sql<<" success "<<std::endl;
}
else
{
std::cerr<<"sql error"<<std::endl;
return 3;
}
mysql> select * from user;
Empty set (0.01 sec)
mysql> select * from user;
+----+----------+------+-----------+
| id | name | age | telephone |
+----+----------+------+-----------+
| 1 | zhangsan | 23 | 123456 |
+----+----------+------+-----------+
delete和update操作同理,只需要更改一下sql就可以了
编码格式
但是如果插入的是汉字,则会出现乱码的现象
const std::string sql="insert into user (name,age,telephone) values ('张三',23,'654321')";
mysql> select * from user;
+----+---------------+------+-----------+
| id | name | age | telephone |
+----+---------------+------+-----------+
| 1 | zhangsan | 23 | 123456 |
| 4 | å¼ ä¸‰ | 23 | 654321 |
+----+---------------+------+-----------+
原因是开发者包默认使用的编码格式Latin1,MySQL默认使用utf8
更改编码格式
int mysql_set_character_set(MYSQL*mysql,const char* csname);
csname:指明编码格式
在建立连接后设置
mysql_set_character_set(conn,"utf8");
mysql> select * from user;
+----+----------+------+-----------+
| id | name | age | telephone |
+----+----------+------+-----------+
| 1 | zhangsan | 23 | 123456 |
| 5 | 张三 | 23 | 654321 |
+----+----------+------+-----------+
如果执行的sql语句是select,那么还需要调出结果
select语句通过mysql_query执行成功后,结果会放到MYSQL中,但为了更好的遍历,我们需要将结果拷贝到MYSQL_RES结果集
中。
函数如下:
MYSQL_RES* mysql_store_result(MYSQL*mysql)
MYSQL_RES可以理解为一个char**的数组,一行数据其实就是一个char **
因为约束,所以MySQL的表数据时规整的,可以使用循环遍历
获取结果集的行数
uint64_t mysql_num_rows(MYSQL_RES *result)
获取结果集的列数
unsigned int mysql_num_fields(MYSQL_RES *result)
行迭代器 MYSQL_ROW
MYSQL_ROW就是char**
typedef char **MYSQL_ROW;
函数如下
MYSQL_ROW mysql_fetch_row(MYSQL_RES*res);
注意此处返回的是结构体对象,不是指针
每次调用这个函数后,下次调用都会将MYSQL_ROW定位到下一行数据
该函数会调用MYSQL变量中的st_mysql_methods中的read_rows函数指针来获取查询结果。同时malloc一片内存空间来存储查询到的数据,所以后续需要free释放这段空间
void mysql_free_result(MYSQL_RES *result)
案例:
#include<iostream> #include<string> #include<mysql/mysql.h> const std::string host ="127.0.0.1"; const std::string user="ljh"; const std::string passwd="123456"; const std::string db="test"; const unsigned int port=3306; int main() { //初始化 MYSQL*conn=mysql_init(nullptr); if(conn==nullptr) { //初始化失败 std::cerr<<"mysql init error"<<std::endl; return 1; } //建立连接 conn=mysql_real_connect(conn,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0); if(conn==nullptr) { std::cerr<<"mysql connect error"<<std::endl; return 2; } std::cout<<"mysql connect success"<<std::endl; mysql_set_character_set(conn,"utf8");//设置编码格式 const std::string sql="select * from user"; //执行sql语句 int n=mysql_query(conn,sql.c_str()); if(n==0) { std::cout<<sql<<" success "<<std::endl; } else { std::cerr<<"sql error"<<std::endl; return 3; } //获取结果集 MYSQL_RES* res=mysql_store_result(conn); if(res==nullptr) { std::cerr<<"store error"<<std::endl; return 4; } int row=mysql_num_rows(res);//行数 int field=mysql_num_fields(res);//列数 //遍历 for(int i=0;i<row;++i) { MYSQL_ROW rows=mysql_fetch_row(res); for(int j=0;j<field;++j) { std::cout<<rows[j]<<"\t"; } std::cout<<std::endl; } mysql_free_result(res); //关闭连接 mysql_close(conn); return 0; }
获取列属性MYSQL_FIELD
MYSQL_FIELD是一个结构体,定义如下:
typedef struct st_mysql_field { char *name; /* Name of column */ char *org_name; /* Original column name, if an alias */ char *table; /* Table of column if column was a field */ char *org_table; /* Org table name, if table was an alias */ char *db; /* Database for table */ char *catalog; /* Catalog for table */ char *def; /* Default value (set by mysql_list_fields) */ unsigned long length; /* Width of column (create length) */ unsigned long max_length; /* Max width for selected set */ unsigned int name_length; unsigned int org_name_length; unsigned int table_length; unsigned int org_table_length; unsigned int db_length; unsigned int catalog_length; unsigned int def_length; unsigned int flags; /* Div flags */ unsigned int decimals; /* Number of decimals in field */ unsigned int charsetnr; /* Character set */ enum enum_field_types type; /* Type of field. See mysql_com.h for types */ void *extension; } MYSQL_FIELD;
可以通过MYSQL_FIELD获取列名,列属性等信息
案例:
MYSQL_FIELD*fields=mysql_fetch_field(res);
for(int i=0;i<field;++i)
{
std::cout<<"列名:"<<fields[i].name<<std::endl;
}
感谢看到此处
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。