mysql connect
mysql的基础,我们之前已经学过,后面我们只关心使用
要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载
我们使用C接口库来进行连接
要正确使用,我们需要做一些准备工作:
- 保证mysql服务有效
- 在官网上下载合适自己平台的mysql connect库,以备后用
Connector/C 使用
我们下下来的库格式如下:
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include/mysql
big_endian.h my_compiler.h mysql_embed.h plugin_group_replication.h
binary_log_types.h my_config.h mysql.h plugin.h
byte_order_generic.h my_config_x86_64.h mysql_time.h plugin_keyring.h
byte_order_generic_x86.h my_dbug.h mysql_version.h plugin_validate_password.h
decimal.h my_dir.h mysqlx_ername.h sql_common.h
errmsg.h my_getopt.h mysqlx_error.h sql_state.h
keycache.h my_global.h mysqlx_version.h sslopt-case.h
little_endian.h my_list.h my_sys.h sslopt-longopts.h
m_ctype.h mysql my_thread.h sslopt-vars.h
m_string.h mysql_com.h my_thread_local.h thr_cond.h
my_alloc.h mysql_com_server.h my_xml.h thr_mutex.h
my_byteorder.h mysqld_ername.h plugin_audit.h thr_rwlock.h
my_command.h mysqld_error.h plugin_ftparser.h typelib.h
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include -d
/usr/include
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include/mysql -d
/usr/include/mysql
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /lib64/mysql/*
/lib64/mysql/libmysqlclient.a /lib64/mysql/libmysqlclient.so.20.3.31
/lib64/mysql/libmysqlclient.so /lib64/mysql/libmysqlservices.a
/lib64/mysql/libmysqlclient.so.20
/lib64/mysql/mecab:
dic etc
/lib64/mysql/plugin:
adt_null.so keyring_file.so rewrite_example.so
authentication_ldap_sasl_client.so keyring_udf.so rewriter.so
auth_socket.so libmemcached.so semisync_master.so
connection_control.so libpluginmecab.so semisync_slave.so
debug locking_service.so validate_password.so
group_replication.so mypluglib.so version_token.so
ha_example.so mysql_no_login.so
innodb_engine.so mysqlx.so
用vscode进行编写下述代码:
#include <iostream>
#include <mysql/mysql.h>
int main()
{
std::cout << "mysql client version :" << mysql_get_client_info() << std::endl;
return 0;
}
编译并运行
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ g++ -o test test.cc -L/lib64/mysql -lmysqlclient
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ll
total 16
-rwxrwxr-x 1 hx hx 9040 Apr 7 13:44 test
-rw-rw-r-- 1 hx hx 157 Apr 7 13:42 test.cc
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ./test
mysql client version :5.7.44
当前MySQL的版本是5.7.44
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ldd test
linux-vdso.so.1 => (0x00007ffff7027000)
libmysqlclient.so.20 => /usr/lib64/mysql/libmysqlclient.so.20 (0x00007fcf248e3000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fcf245db000)
libm.so.6 => /lib64/libm.so.6 (0x00007fcf242d9000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fcf240c3000)
libc.so.6 => /lib64/libc.so.6 (0x00007fcf23cf5000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcf23ad9000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fcf238d5000)
librt.so.1 => /lib64/librt.so.1 (0x00007fcf236cd000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcf25287000)
g++ 编译时后面带的选项(-L / -l) 所代表的意思,请翻阅之前Linux博客当中的软硬链接这块
通过ldd可以看到test和mysqlclient建立了链接
至此引入库的工作已经做完,接下来就是熟悉接口
mysql接口介绍
这些接口的具体使用方案可以在MySQL的官网进行查看
我们采用的是C语言的方式链接,所以我们打开C语言的使用文档即可:
1. 初始化与关闭
要使用库,必须先进行初始化!
#include <iostream>
#include <mysql/mysql.h>
int main()
{
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
mysql_close(my);
return 0;
}
2. 链接数据库
链接数据库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);
第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect函数中各参数,基本都是顾名思意。
#include <iostream>
#include <string>
#include <mysql/mysql.h>
//const std::string host = "127.0.0.1";
const std::string host = "localhost";
const std::string user = "hx";
const std::string passwd = "123456";
const std::string db = "scott";
const unsigned int port = 3306;
int main()
{
// std::cout << "mysql client version :" << mysql_get_client_info() << std::endl;
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
std::cout << "connect success" << std::endl;
mysql_close(my);
return 0;
}
3. 下达SQL指令(增删改)
方式1:
std::string sql;
while(true)
{
std::cout << "MySQL>>>";
// getline 读取一行sql到cin当中
if(!std::getline(std::cin,sql) || sql == "quit")
{
std::cout << "ByeBye~" << std::endl;
break;
}
int n = mysql_query(my,sql.c_str());
// 如果n == 0 那么就获取到sql中的语句
if(n == 0)
{
std::cout << sql << "success: " << n << std::endl;
}
else
{
std::cerr << sql << "failed: " << n << std::endl;
}
}
方式2:
std:: string sql = "update stu set name='HXHX' where id = 1 ";
int n = mysql_query(my,sql.c_str());
if(n == 0) std::cout << sql << "success" << std::endl;
else std::cout << sql << "failed" << std::endl;
解决乱码问题
客户端和服务器端对于编码问题没有达成一致,导致乱码问题
//建立好链接之后,获取英文没有问题,如果获取中文是乱码:
//设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");
4. 下达SQL指令(显示)
std::string sql = "select * from stu";
int n = mysql_query(my,sql.c_str());
if(n == 0) std::cout << sql << "success" << std::endl;
else
{
std::cout << sql << "failed" << std::endl;
return 3;
}
MYSQL_RES *res = mysql_store_result(my);
if(nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 4;
}
// 获取对应的行,列
my_ulonglong rows = mysql_num_rows(res);
my_ulonglong fields = mysql_num_fields(res);
std::cout << "行:" << rows << std::endl;
std::cout << "列:" << fields << std::endl;
// 属性
MYSQL_FIELD *fields_array = mysql_fetch_fields(res);
for(int i = 0;i<fields;i++)
{
std::cout << fields_array[i].name << "\t";
}
std::cout << "\n";
// 内容
for(int i = 0; i < rows; i++)
{
MYSQL_ROW row = mysql_fetch_row(res);
for(int j = 0; j < fields; j++)
{
std::cout << row[j] << "\t";
}
std::cout << "\n";
}
MYSQL_RES *res中不仅包含内容还包含属性
原型如下:
MYSQL_RES *mysql_store_result(MYSQL *mysql);
该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。
同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。
支持事务
另外,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);