赞
踩
它是个什么项目?——在C++下利用Mysql API实现Mysql的功能的类Mysql的客户端,助力初学者快速熟悉Mysql命令以及Mysql API
先展示一下效果图
下图是正宗的mysql:
下图是我利用Mysql API函数,实现一个类Mysql的客户端窗口:
可以看出来和原版效果差不多吧~,下面来和我一起学习吧!
需求:在C++下,利用Mysql API函数,实现一个类Mysql的客户端窗口,实现对mysql数据库的操作
流程是用C写的,和C++用类实现大差不差,主要看看整体流程的逻辑
mysql客户端编写思路分析: 1 mysql初始化--mysql_init 2 连接mysql数据库---mysql_real_connect 3 while(1) { //打印提示符:write(STDOUT_FILENO, "mysql >", strlen("mysql >")); //读取用户输入: read(STDIN_FILENO, buf, sizeof(buf)) //判断用户输入的是否为退出: QUIT quit exit EXIT if(strncasecmp(buf, "exit", 4)==0 || strncasecmp(buf, "quit", 4)==0) { //关闭连接---mysql_close(); exit(); } //执行sql语句--mysql_query(); //若不是select查询, 打印执行sql语句影响的行数--mysql_affected_rows(); if(strncasecmp(buf, "select", 6)!=0) { printf("Query OK, %d row affected", mysql_affected_rows()); continue; } //若是select查询的情况 ---//获取列数: mysql_field_count() //获取结果集: mysql_store_result() --获取列数: int mysql_num_fields(); //获取表头信息并打印表头信息:mysql_fetch_fields(); //循环获取每一行记录并打印: mysql_fetch_row() //释放结果集: mysql_free_result() } 4 关闭连接: mysql_close();
主要实现CRUD操作,增删改操作不需要额外处理,所以可以放一起操作,而查由于需要获取结果集,所以需要单独处理。
主要实现的功能如下:
class Mysql { public: //初始化数据库,连接数据库 Mysql(char* ip, char* user, char* password, char* db, int port); //增删改操作----update\insert\delete void db_CUD(char * buf); //查操作----select void db_select(char * buf); //判断是什么语句,然后自动调用相应的操作 void execute_sql(char * buf); //断开数据库的连接 void db_close(); MYSQL * m_mysql; MYSQL * m_conn; MYSQL_RES * m_result; };
具体实现:
//初始化数据库,连接数据库 Mysql::Mysql(char* ip, char* user, char* password, char* db, int port) { //初始化数据库 this->m_mysql = mysql_init(NULL); if(this->m_mysql == NULL) { printf("mysql init error \n"); exit(-1); } //连接数据库 this->m_conn = mysql_real_connect(this->m_mysql, ip, user, password, db, port, NULL, 0); if(this->m_conn==NULL) { printf("mysql connect error ! \n"); exit(-1); } //设置字符集----解决中文问题 cout<<"before:"<<mysql_character_set_name(this->m_conn)<<endl; mysql_set_character_set(this->m_conn,"utf8");//设置字符集为 utf8 cout<<"after:"<<mysql_character_set_name(this->m_conn)<<endl; } //增删改操作----update\insert\delete void Mysql::db_CUD(char * buf) { int ret = mysql_query(this->m_conn, buf); //通过调用mysql_affected_rows(),可发现有多少行已被改变(影响)。 if( ret == 0)//mysql_query调用成功 { ret = mysql_affected_rows(this->m_conn); cout<<"Query OK, "<< ret <<" rows affected"<<endl; cout<<"Rows matched: "<<ret<<" Changed: "<<ret<<" Warnings: 0"<<endl; } else//mysql_query调用失败---sql语句出错 cout<<"ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1"<<endl; } //查操作----select void Mysql::db_select(char *buf) { int ret = mysql_query(this->m_conn, buf); if(ret != 0) cout<<"mysql_query--select失败!"<<endl; else { //获取数据集 this->m_result = mysql_store_result(this->m_conn); //获取失败 if( this->m_result == NULL) { cout<<"mysql_store_result error"; return; } //获取成功 else { //获取列数 int row_num = mysql_num_fields(this->m_result); //打印表头信息 MYSQL_FIELD *fields = NULL; fields = mysql_fetch_fields(this->m_result); //得到表头的结构体数组 // cout<<"+----+-----------+------+--------------------+--------+------------+-----------+---------+"<<endl; for(int i=0; i<row_num; ++i) { cout<<fields[i].name<<"\t"; } cout<<endl; // cout<<"+----+-----------+------+--------------------+--------+------------+-----------+---------+"<<endl; //获取结果集每一行记录 MYSQL_ROW row; while( row = mysql_fetch_row(this->m_result) ) { for (int i=0; i<row_num; i++) { cout<<row[i]<<"\t"; } cout<<endl; } // cout<<"+----+-----------+------+--------------------+--------+------------+-----------+---------+"<<endl; //释放结果集 mysql_free_result(this->m_result); } } } //判断是什么语句,然后自动调用相应的操作 void Mysql::execute_sql(char * buf) { //先判断是不是QUIT quit EXIT exit if(strncasecmp(buf, "quit", 4)==0 || strncasecmp(buf, "exit", 4) == 0) { this->db_close(); } //在判断是增删改还是查 else if( strncasecmp(buf, "insert", 6) == 0 || strncasecmp(buf, "update", 6) == 0 || strncasecmp(buf, "delete", 6) == 0) { db_CUD(buf); } else if(strncasecmp(buf, "select", 6) == 0) { db_select(buf); } //输入错误指令 else { cout<<"ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near"<<"\'"<<buf<<"\'at line 1"<<endl; } } //关闭连接 void Mysql::db_close() { mysql_close(this->m_conn); cout<<"Bye"<<endl; exit(1); }
注意:对于用户输入的数据有三个方面需要处理
具体实现如下:
//处理buf异常情况 int clean_buf(char * buf) { //处理输入回车报错的情况 if(buf[0]=='\n') return 1; //去掉末尾的; char * p = strrchr(buf, ';'); if(p!=NULL) *p = 0x00; //去除前面的空格 int i; for(i=0; strlen(buf);++i) { if(buf[i]!=' ')//只要前面是空格,指针往前走 break; } int n = strlen(buf); memmove(buf, buf+i, n-i+1);//memmove拷贝字符串。+1是因为多拷贝一个\0 return 0; }
最后,主体main函数主要实现循环的功能。
具体实现如下:
int main() { char buf[1024]; //初始化、连接数据库 Mysql mysql=Mysql("localhost", "root", "thisispw", "thisistable", 0); while(1) { //将"mysql"输出到终端 write(STDIN_FILENO,"mysql> ",strlen("mysql> ")); //获取用户输入 memset(buf,0x00,sizeof(buf)); read(STDOUT_FILENO, buf, sizeof(buf)); //处理buf异常情况 int flag = clean_buf(buf); if(flag==1) continue; //判断是什么语句,然后自动执行相应的语句 mysql.execute_sql(buf); } }
输出结果 before:utf8mb4 after:utf8mb3 mysql> select * from score id name math english chinese 1 Tom 67 88 95 2 Rose 23 66 90 3 Jack 56 98 76 mysql> insert into score values (4, "lu", 23, 42, 55) Query OK, 1 rows affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from score id name math english chinese 1 Tom 67 88 95 2 Rose 23 66 90 3 Jack 56 98 76 4 lu 23 42 55 mysql> delete from score where id=4 Query OK, 1 rows affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from score id name math english chinese 1 Tom 67 88 95 2 Rose 23 66 90 3 Jack 56 98 76 mysql> update score set math = 33 where id = 3 Query OK, 1 rows affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from score id name math english chinese 1 Tom 67 88 95 2 Rose 23 66 90 3 Jack 33 98 76 mysql> error ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near'error 'at line 1 mysql> quit Bye
源码可移步:https://github.com/jiong1998/C-_mysql_client
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。