目录
mysql connect
我们使用 C 接口库来进行连接要正确使用,我们需要做一些准备工作:
- 保证mysql服务有效
- 在官网上下载合适自己平台的mysql connect库,以备后用
Connector/C 使用
我们下下来的库格式如下:[lml @MiWiFi - R1CL - srv lib ] $ tree ..├── include│ ├── big_endian . h│ ├── byte_order_generic . h│ ├── byte_order_generic_x86 . h│ ├── decimal . h│ ├── errmsg . h│ ├── keycache . h│ ├── little_endian . h│ ├── m_ctype . h│ ├── m_string . h│ ├── my_alloc . h│ ├── my_byteorder . h│ ├── my_compiler . h│ ├── my_config . h│ ├── my_dbug . h│ ├── my_dir . h│ ├── my_getopt . h│ ├── my_global . h│ ├── my_list . h│ ├── my_pthread . h│ ├── mysql│ │ ├── client_authentication . h│ │ ├── client_plugin . h│ │ ├── client_plugin . h . pp│ │ ├── get_password . h│ │ ├── plugin_auth_common . h│ │ ├── plugin_trace . h│ │ ├── psi│ │ │ ├── mysql_file . h│ │ │ ├── mysql_idle . h│ │ │ ├── mysql_mdl . h│ │ │ ├── mysql_memory . h│ │ │ ├── mysql_ps . h│ │ │ ├── mysql_socket . h│ │ │ ├── mysql_sp . h│ │ │ ├── mysql_stage . h│ │ │ ├── mysql_statement . h│ │ │ ├── mysql_table . h│ │ │ ├── mysql_thread . h│ │ │ ├── mysql_transaction . h│ │ │ ├── psi_base . h│ │ │ ├── psi . h│ │ │ └── psi_memory . h│ │ ├── service_my_snprintf . h│ │ └── service_mysql_alloc . h│ ├── mysql_com . h│ ├── mysql_com_server . h│ ├── mysqld_ername . h│ ├── mysqld_error . h│ ├── mysql_embed . h│ ├── mysql . h│ ├── mysql_time . h│ ├── mysql_version . h│ ├── my_sys . h│ ├── my_xml . h│ ├── sql_common . h│ ├── sql_state . h│ ├── sslopt - case . h│ ├── sslopt - longopts . h│ ├── sslopt - vars . h│ └── typelib . h└── lib├── libmysqlclient . a├── libmysqlclient_r . a -> libmysqlclient . a├── libmysqlclient_r . so -> libmysqlclient . so├── libmysqlclient_r . so . 18 -> libmysqlclient . so . 18├── libmysqlclient_r . so . 18.3.0 -> libmysqlclient . so . 18.3.0├── libmysqlclient . so -> libmysqlclient . so . 18├── libmysqlclient . so . 18 -> libmysqlclient . so . 18.3.0└── libmysqlclient . so . 18.3.0其中 include 包含所有的方法声明, lib 包含所有的方法实现(打包成库)尝试链接mysql client通过 mysql_get_client_info() 函数,来验证我们的引入是否成功#include <stdio.h>#include <mysql.h>int main (){printf ( "mysql client Version: %s\n" , mysql_get_client_info ());return 0 ;}[lml @MiWiFi - R1CL - srv lib ] $ gcc - o test test . c -I./include -L./lib -lmysqlclient #这一步是编译[lml @MiWiFi - R1CL - srv lib ] $ lsinclude lib test test . c[lml @MiWiFi - R1CL - srv lib ] $ . / test. / test : error while loading shared libraries : libmysqlclient . so . 18 : cannot openshared object file : No such file or directory[lml@MiWiFi-R1CL-srv lib]$ export LD_LIBRARY_PATH=./lib #动态库查找路径(ldd)这一步是链接[lml @MiWiFi - R1CL - srv lib ] $ . / testmysql client Version : 6.1.6至此引入库的工作已经做完,接下来就是熟悉接口。mysql接口介绍
初始化 mysql_init()要使用库,必须先进行初始化!MYSQL *mysql_init(MYSQL *mysql) ;如: MYSQL *mfp = mysql_init(NULL)链接数据库 mysql_real_connect初始化完毕之后,必须先链接数据库,在进行后续操作。( mysql 网络部分是基于 TCP/IP 的)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 );// 建立好链接之后,获取英文没有问题,如果获取中文是乱码:// 设置链接的默认字符集是 utf8 ,原始默认是 latin1mysql_set_character_set ( myfd , "utf8" );第一个参数 MYSQL 是 C api 中一个非常重要的变量( mysql_init 的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods 的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect 函数中各参数,基本都是顾名思意。下发 mysql 命令 mysql_queryint mysql_query ( MYSQL * mysql , const char * q );第一个参数上面已经介绍过,第二个参数为要执行的 sql 语句 , 如 “select * from table” 。获取执行结果 mysql_store_resultsql 执行完以后,如果是查询语句,我们当然还要读取数据,如果 update , insert 等语句,那么就看下操作成功与否即可。我们来看看如何获取查询结果: 如果mysql_query 返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:MYSQL_RES * mysql_store_result ( MYSQL * mysql );该函数会调用 MYSQL 变量中的 st_mysql_methods 中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数 malloc 了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result), 不然是肯定会造成内存泄漏的。 执行完mysql_store_result 以后,其实数据都已经在 MYSQL_RES 变量中了,下面的 api 基本就是读取MYSQL_RES 中的数据。获取结果行数 mysql_num_rowsmy_ulonglong mysql_num_rows ( MYSQL_RES * res );获取结果列数 mysql_num_fieldsunsigned int mysql_num_fields ( MYSQL_RES * res );获取列名 mysql_fetch_fieldsMYSQL_FIELD * mysql_fetch_fields ( MYSQL_RES * res );如:int fields = mysql_num_fields ( res );MYSQL_FIELD * field = mysql_fetch_fields ( res );int i = 0 ;for (; i < fields ; i ++ ){cout << field [ i ]. name << " " ;}cout << endl ;获取结果内容 mysql_fetch_rowMYSQL_ROW mysql_fetch_row ( MYSQL_RES * result );它会返回一个 MYSQL_ROW 变量, MYSQL_ROW 其实就是 char **. 就当成一个二维数组来用吧。i = 0 ;MYSQL_ROW line ;for (; i < nums ; i ++ ){line = mysql_fetch_row ( res );int j = 0 ;for (; j < fields ; j ++ ){cout << line [ j ] << " " ;}cout << endl ;}关闭 mysql 链接 mysql_closevoid mysql_close ( MYSQL * sock );另外, mysql C api 还支持事务等常用操作:my_bool STDCALL mysql_autocommit ( MYSQL * mysql , my_bool auto_mode );my_bool STDCALL mysql_commit ( MYSQL * mysql );my_bool STDCALL mysql_rollback ( MYSQL * mysql );MySQL_Client.cc
#include <iostream> #include <cstdlib> #include <string> #include <cstdio> #include <cstring> #include <mysql/mysql.h> using namespace std; string host = "127.0.0.1"; //'localhost' string user = "whb"; string passwd = "123456"; string db = "test_db"; unsigned int port = 8080; int main() { // cout << "mysql client version: " << mysql_get_client_info() << endl; // 0. 初始化mysql对象 MYSQL *msql = mysql_init(nullptr); if (msql == nullptr) { cerr << "mysql_init error" << endl; exit(1); } // 1. 登陆认证 if (mysql_real_connect(msql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr) { cerr << "mysql_real_connect error" << endl; exit(2); } mysql_set_character_set(msql, "utf8"); cout << "mysql_real_connect success" << endl; // string sql = "insert into emp values (666, '张飞', 789.987)"; // string delSql = "delete from emp where id=666"; // string updateSql = "update emp set name='赵云' where id=666"; // string selectSql = "select * from emp"; char sql[1024]; while (true) { printf("mysql> "); fgets(sql, sizeof sql, stdin); //' select * from user ' // 调用成功的时候,返回值是0, 否则就是1 int n = mysql_query(msql, sql); if (strcasestr(sql, "select") && n == 0) { cout << "result: " << n << endl; // 对结果进行解析 MYSQL_RES *res = mysql_store_result(msql); if (res == nullptr) exit(0); int rows = mysql_num_rows(res); int fields = mysql_num_fields(res); MYSQL_FIELD *fname = mysql_fetch_fields(res); for (int j = 0; j < fields; j++) cout << fname[j].name << "\t|\t"; cout << endl; MYSQL_ROW line; for (int i = 0; i < rows; i++) { line = mysql_fetch_row(res); // 按行获取文件的内容,自动会更新行数 for (int j = 0; j < fields; j++) cout << line[j] << "\t|\t"; cout << endl; } printf("%d rows in set\n", rows); } else { cout << "execl sql : " << sql << " done" << endl; } } // 关闭mysql对象 mysql_close(msql); return 0; }