Repository: webary/MySQL_Tools Branch: master Commit: 5ac4a886482a Files: 14 Total size: 38.5 KB Directory structure: gitextract_l5wtdj6k/ ├── C++封装MySQL数据库连接器类和消息管理类.cpp ├── MySQL常用操作.doc ├── MySQL常用操作及用法.cpp ├── MySQL环境配置.md ├── README.md ├── Untitled Diagram.drawio ├── 备用命令行代码及数据库表/ │ ├── stu.sql │ ├── workers.sql │ ├── 打开mysql.bat │ ├── 打开命令行.bat │ └── 打开命令行操作mysql.bat ├── 测试连接.cpp ├── 职工管理系统C++.cpp └── 职工管理系统C.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: C++封装MySQL数据库连接器类和消息管理类.cpp ================================================ #include #include #include #include #include #include #include #include //必须在包含mysql.h之前包含windows.h #include using std::string; using std::vector; using std::endl; ///数据库连接器类,负责连接数据库,并封装基本的数据库相关操作 class DB_Connector { protected: MYSQL* mysql; public: static string host_, user_, passwd_, db_; public: inline DB_Connector(); inline virtual ~DB_Connector(); //执行sql语句,成功则返回0,失败返回非0 inline int query(const string& sql); //返回上一次的错误提示 inline string error(); //获取结果集,将其保存到二维string数组中 inline vector > getResult(); }; DB_Connector::DB_Connector() { mysql = mysql_init(NULL); if (mysql_real_connect(mysql, host_.c_str(), user_.c_str(), passwd_.c_str(), db_.c_str(), 0, 0, 0) == 0) { string err = "Failed to connect database server: " + error(); throw std::logic_error(err); } query("set names 'GBK'");//设置字符集,防止中文出现乱码 } DB_Connector::~DB_Connector() { mysql_close(mysql); } //执行sql语句,成功则返回0,失败返回非0 int DB_Connector::query(const string& sql) { return mysql_query(mysql, sql.c_str()); } //返回上一次的错误提示 string DB_Connector::error() { return mysql_error(mysql); } //获取结果集,将其保存到二维string数组中 vector > DB_Connector::getResult() { vector >result; MYSQL_RES* res = mysql_store_result(mysql); if (res == NULL) return result; unsigned num = mysql_num_fields(res); //结果集的列数 for (MYSQL_ROW row; (row = mysql_fetch_row(res)) != NULL;) { result.push_back(vector(num)); for (size_t cur = result.size() - 1, i = 0; i < num; ++i) { result[cur][i] = row[i]; } } mysql_free_result(res); //释放结果集资源 return result; } ///消息管理类 class DB_Msg { protected: DB_Connector db_conn; //数据库连接器对象 const string tbName; //要操作的表名 std::ofstream fsLog; //日志记录文件流 public: inline DB_Msg(const string& _tableName, const string& _logFileName); inline virtual ~DB_Msg(); //添加消息 inline void push(const string& to, const string& from, const string& msg); //获取执行指定sql语句后的结果 inline vector > getBySql(const string& sql); //根据指定sql语句删除相应记录 inline void removeBySql(const string& sql); //获取当前日期和时间,用于更新日志 inline static string getTime(); protected: //创建存储聊天记录的表 inline void createTable(); }; DB_Msg::DB_Msg(const string& _tableName, const string& _logFileName) : tbName(_tableName) { if (_logFileName != "") { fsLog.open(_logFileName, std::ios::app); } createTable(); } DB_Msg::~DB_Msg() { if (fsLog) { fsLog.close(); } } //添加消息 void DB_Msg::push(const string& to, const string& from, const string& msg) { string sql = "insert into " + tbName + "(toUser,fromUser,msg) values('" + to + "','" + from + "','" + msg + "')"; if (fsLog) { fsLog << getTime() << ">>>execute: " + sql << endl; } if (db_conn.query(sql) != 0 && fsLog) { //执行sql语句失败返回非0 fsLog << "Failed to insert: " << db_conn.error() << endl; } } //获取执行指定sql语句后的结果 vector > DB_Msg::getBySql(const string& sql) { vector >result; if (fsLog) { fsLog << getTime() << ">>>execute: " + sql << endl; } if (db_conn.query(sql) == 0) { //执行成功则把结果输出 result = db_conn.getResult(); } else if (fsLog) { fsLog << "Failed to search: " << db_conn.error() << endl; } return result; } //根据指定sql语句删除相应记录 void DB_Msg::removeBySql(const string& sql) { if (fsLog) { fsLog << getTime() << ">>>execute: " << sql << endl; } if (db_conn.query(sql) != 0 && fsLog) { fsLog << "Failed to delete: " << db_conn.error() << endl; } } //获取当前日期和时间,用于更新日志 inline string DB_Msg::getTime() { char time_buf[64]; time_t now_time = time(NULL); strftime(time_buf, 64, "%Y-%m-%d %H:%M:%S ", localtime(&now_time)); return time_buf; } //创建存储聊天记录的表 void DB_Msg::createTable() { db_conn.query("show tables like '" + tbName + "'"); auto res = db_conn.getResult(); if (res.size() > 0 && res[0][0] == tbName) { return; } string sql = "CREATE TABLE `" + tbName + "` (" "`id` tinyint(4) NOT NULL AUTO_INCREMENT," "`toUser` varchar(20) NOT NULL," "`fromUser` varchar(20) NOT NULL," "`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP," "`msg` text NOT NULL," "PRIMARY KEY (`id`)" ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; if (fsLog) { fsLog << getTime() << ">>>execute: " << sql << endl; } if (db_conn.query(sql) != 0 && fsLog) { fsLog << "Failed to create: " << db_conn.error() << endl; } } ///离线消息管理类 - 仅用于服务器端 class DB_OfflineMsg : public DB_Msg { public: DB_OfflineMsg(const string& _tableName, const string _logFileName = "") : DB_Msg(_tableName, _logFileName) {} //从离线消息表中得到所有发送给user的消息,提取完后从数据库删除 inline vector > pop(const string& user); }; //从离线消息表中得到所有发送给user的消息,提取完后从数据库删除 vector > DB_OfflineMsg::pop(const string& user) { string sql = "select fromUser,time,msg from " + tbName + " where toUser='" + user + "'"; vector >result = getBySql(sql); //删除发给user的所有消息 if (result.size() > 0) { sql = "delete from " + tbName + " where toUser='" + user + "'"; removeBySql(sql); } return result; } ///聊天记录消息管理类 class DB_ChatLogMsg : public DB_Msg { public: //用户名标识用户,日志文件名为空时不建立前缀用于区分是在客户端还是服务器端 inline DB_ChatLogMsg(const string& _userName, const string _logFileName = "", const string& _prefix = "") : DB_Msg(_prefix + "chat_log_" + _userName, _logFileName), userName(_userName) {} //添加聊天记录消息 inline void push(const string& userOthers, const string& msg, bool isReceived = 1); //添加收到的带时间记录的离线消息 inline void pushOffline(const string& from, const string& msg, const string& _time); //获取消息user发来的或发给user的所有消息 inline vector > get(const string& user); //在该用户的聊天记录中查找与withUser的包含str的消息记录 inline vector > find(const string& str, const string& withUser = "*"); //根据传递的用户名删除与对应用户的聊天记录,传入"*"则删除所有记录 inline void remove(const string& user); //获取与当前用户有聊天记录的用户列表 inline vector getUserWithChatLog(); //获取当前用户的用户名 inline const string& getUserName(); protected: string userName; //该用户的用户名 }; //添加聊天记录消息 void DB_ChatLogMsg::push(const string& userOthers, const string& msg, bool isReceived) { if (isReceived) { //收到消息 DB_Msg::push(userName, userOthers, msg); } else { //发送消息 DB_Msg::push(userOthers, userName, msg); } } //添加收到的带时间记录的离线消息 void DB_ChatLogMsg::pushOffline(const string& from, const string& msg, const string& _time) { string sql = "insert into " + tbName + "(toUser,fromUser,time,msg) values('" + userName + "','" + from + "','" + _time + "','" + msg + "')"; if (fsLog) { fsLog << getTime() << ">>>execute: " + sql << endl; } if (db_conn.query(sql) != 0 && fsLog) { //执行sql语句失败返回非0 fsLog << "Failed to insert: " << db_conn.error() << endl; } } //获取消息user发来的或发给user的所有消息 vector > DB_ChatLogMsg::get(const string& user) { string sql = "select fromUser,time,msg from " + tbName + " where toUser='" + user + "' or fromUser='" + user + "'"; return getBySql(sql); } //在该用户的聊天记录中查找与withUser的包含str的消息记录 vector > DB_ChatLogMsg::find(const string& str, const string& withUser) { string sql = "select fromUser,toUser,time,msg from " + tbName + " where "; if (withUser != "*") { sql += "(toUser='" + withUser + "' or fromUser='" + withUser + "') and"; } sql += " msg like '%" + str + "%'"; return getBySql(sql); } //根据传递的用户名删除与用户user的聊天记录,传入"*"则删除所有记录 void DB_ChatLogMsg::remove(const string& user) { string sql = "delete from " + tbName; if (user != "*") { sql += " where toUser='" + user + "' or fromUser='" + user + "'"; } removeBySql(sql); } //获取与当前用户有聊天记录的用户列表 vector DB_ChatLogMsg::getUserWithChatLog() { string sql = "select distinct toUser from " + tbName; auto users = getBySql(sql); std::unordered_map userList; for (auto &elem : users) { userList[elem[0]]; } sql = "select distinct fromUser from " + tbName; users = getBySql(sql); for (auto &elem : users) { userList[elem[0]]; } userList.erase(userList.find(userName)); //删除用户列表中的自己 //将结果保存到vector中返回 vector res; res.reserve(userList.size()); for (auto &it : userList) { res.push_back(it.first); } return res; } //获取当前用户的用户名 inline const string& DB_ChatLogMsg::getUserName() { return userName; } using std::cout; //可直接输出查询结果 inline std::ostream& operator<<(std::ostream& out, const vector >& res) { if (res.size() == 0) { cout << "暂无内容可显示!" << endl; return out; } for (auto &it : res) { //显示提取出的离线消息内容 for (auto &elem : it) { cout << elem << " "; } cout << endl; } return out; } string DB_Connector::host_ = "localhost"; string DB_Connector::user_ = "root"; string DB_Connector::passwd_ = "123456"; string DB_Connector::db_ = "mfc_qq"; using namespace std; int main() { DB_OfflineMsg off_msg("offline_msg", "offileMsg.log"); off_msg.push("to", "from", "hey"); //存入一条离线消息 auto res = off_msg.pop("to"); //读取发给该用户的全部离线消息 cout << res << endl; DB_ChatLogMsg clMsg("Bob", "chat_log_Bob.log"); clMsg.push("Miranda-lym", "hello", 0); clMsg.push("Miranda-lym", "hi!", 1); clMsg.push("Miranda-lym", "this a test case!", 0); clMsg.push("Miranda-lym", "soga,I get it!", 1); clMsg.push("John", "what are you doing!", 1); cout << clMsg.get("Miranda-lym") << endl; cout << "find 'hi':\n" << clMsg.find("hi") << endl; auto userList = clMsg.getUserWithChatLog(); cout << "users that have chated with " < //必须在包含mysql.h之前包含windows.h #include #include int main() { char SqlText[256] = ""; //将用来保存要执行的SQL语句 MYSQL *conn = NULL; //MYSQL句柄类型(任何一个mysql操作都是基于MYSQL这个句柄来操作的) MYSQL_RES *res = NULL; //数据查询结果集 MYSQL_FIELD * fd = NULL; //MySQL表头域类型 MYSQL_ROW row; //一个行数据的类型安全(type-safe)的表示 conn = mysql_init(NULL); //初始化MYSQL连接 char server[20] = "localhost"; //mysql服务器的IP char user[20] = "root"; //用户名 char psd[20] = "123456"; ///密码 需要改为自己的密码 char dbName[1024] = "test"; ///数据库名 需要改为自己的数据库名 unsigned short port = 3306; //服务器端口号,默认3306 ///建立mysql连接 if(mysql_real_connect(conn, server, user, psd, dbName, port, NULL, 0)==0) { printf("Error connecting to database: %s\n", mysql_error(conn)); } else { puts("数据库连接成功!"); mysql_query(conn, "set names 'GBK'");//设置字符集,防止中文无法正常显示[可选操作] ///下面开始对数据库进行操作 const char tableName[30] = "UserInfo";//要操作的表名 //插入 sprintf(SqlText, "insert into %s(userName,passwd) values('%s','%s')", tableName, "test1", "test1"); printf(">>>执行: %s\n", SqlText); if (mysql_query(conn, SqlText) != 0) { //执行sql语句,执行成功返回0 printf("Can't insert data to table: "); printf("%s\n", mysql_error(conn)); //获取最后一次查询失败的错误提示 } //删除 sprintf(SqlText, "delete from %s where userName='test1'", tableName); printf("将执行删除语句 %s, 按y/Y确认!", SqlText); char c = getchar(); if(c == 'y' || c == 'Y') { printf(">>>执行: %s\n", SqlText); if (mysql_query(conn, SqlText) != 0) { //执行sql语句 printf("Can't delete data from table: "); printf("%s\n", mysql_error(conn)); //获取最后一次查询失败的错误提示 } } //查找 sprintf(SqlText, "select * from %s where type='0'", tableName); if (mysql_query(conn, SqlText)==0) { //执行成功则把结果输出 res = mysql_store_result( conn ); //存储查询得到的结果集 printf(">>>执行: %s\nrecords nums:", SqlText); printf("%u\n\n", mysql_num_rows(res)); //获取搜索到的结果集的条数 //输出数据结果各字段名,即表头被选取的部分 while((fd = mysql_fetch_field(res)) != NULL) { printf("%-10s ", fd->name); } puts(""); //打印获取的数据 int fieldNums = mysql_num_fields(res); //获取数据结果每条记录的列数 while ((row = mysql_fetch_row(res)) != NULL) { //不断获取下一组结果 for(int i = 0; i < fieldNums; i++) { printf("%-10s ", row[i]); } puts(""); } mysql_free_result(res); //释放结果集资源 } else { printf("查询失败: %s\n", mysql_error(conn)); } //修改 sprintf(SqlText, "update %s set passwd='passwd' where id='2'", tableName); printf(">>>执行: %s\n", SqlText); if (mysql_query(conn, SqlText) != 0) { //执行sql语句 printf("Can't update data on table: "); printf("%s\n", mysql_error(conn)); //获取最后一次查询失败的错误提示 } } mysql_close(conn); //关闭连接,即释放连接 getchar(); return 0; } ================================================ FILE: MySQL环境配置.md ================================================ ###最好安装32位的MySQL * 1.把libmysql.dll复制到C:/windows/system32/ (若是32位系统)和C:/windows/sysWOW64/ (若是64位系统)下 * 2.配置好IDE:
(1)添加包含目录:【安装位置\MySQL Server 5.6\include】
(2)添加库目录:【安装位置\MySQL Server 5.6\lib】
(3)让IDE包含必要的链接库文件:【安装位置\MySQL Server 5.6\lib\libmysql.lib】(vs中一般为‘链接器’-‘输入’-‘附加依赖项’:添加libmysql.lib) * 3.运行【安装位置\MySQL Server 5.6\bin】目录下的mysqld.exe,注意每次使用前都需要让这个后台运行 ================================================ FILE: README.md ================================================ # MySQL_Tools 使用C和C++连接MySQL数据库并进行常用的数据库操作。实现了简单的学生(或职工)信息管理系统,源于大学时的数据库课程设计。 如果觉得有用,欢迎大家star,同时也欢迎fork后贡献代码提交PR ================================================ FILE: Untitled Diagram.drawio ================================================ 7VhZc9MwEP41Hp5gfBQnecRp0wKhU2ihw6NiK7aI7DWynINfzyqWYzsOOYD0yDQv0a43K2m/b4/YcPrx/FKQNPoEAeWGbQZzwzk3bNuybQe/lGZRaLq9bqEIBQu0UaW4Zb+oVppam7OAZg1DCcAlS5tKH5KE+rKhI0LArGk2Bt7cNSUhbSlufcLb2nsWyEjfwu5U+ivKwqjc2XJ7xZOYlMb6JllEApjVVM6F4fQFgCxW8bxPuQpeGZf794t7Ppy4lx8+Zz/JV+/j3fW314WzwSE/WV1B0ET+X9d24XpKeK7jpe8qF2UABeRJQJUT03C8SMYclxYuf1ApFxpwkktAFQgZQQgJ4UOAVNuNIZHazFIyTYJ3CliURxz8SaEaMM71Hihp+y5KmRQwWWGnHKyAUMacjCj3iD8JlwftAweBjxJIqHIVIBn0XarDXVRab8/YagwyyIVPt9jpbJFEhHSbP7ewU+er8VQjd0khplIs0EBQTiSbNslMdE6EK7sKd1xo6A+ggdOiwZDEqcp6oFnySuJqBmKyhRsKl1nEJL1NyTJAMywnTb7UeYBX9UJOskyjuAPkw0CaUiHpfGtYy6euzu2yuGlxVlUKq0z/qFYlzswjAXHWAuI7Fs+XlPyXlHT3TMmyY+3MSU2Wkhh7p6j2dAMskTUTGI8zPNg6dVYb/j2b3rbYdA0tMu3G41nT7ZHI1DmMS9aT55L7hxbhcgyDNxK4CtUq5XkYIlnQXWI4g3btiiAe5dnudtHAWDFoQGLGVbyuKJ9SyXyyoakQzkLc99xHuKnYTB7ckiUhSm4l3S3JivX3iM2m02w2K7nebcwN3aZ7rG7TaWF6g+gV0NkmX+J7Yh3fsddA6D12y+/uU6SfdQl+8I5fVtPdLd/as0xr9phvHPw0CPT0p4DeXjPlyxhwHIbZpzYIlCes8cnL+ag9CYxykSwHAcjlyySwbRKwNzWhB50EykJYA/ULTQlDMM3hKc4B6//8z5zHngPKStGEgKuY2maRYSeGwfos5ljHwwDF6k1tUQqr993OxW8= ================================================ FILE: 备用命令行代码及数据库表/stu.sql ================================================ /* Navicat MySQL Data Transfer Source Server : 测试1 Source Server Version : 50616 Source Host : localhost:3306 Source Database : test Target Server Type : MYSQL Target Server Version : 50616 File Encoding : 65001 Date: 2014-05-11 00:37:03 */ SET FOREIGN_KEY_CHECKS=0; set names utf8; -- ---------------------------- -- Table structure for `stu` -- ---------------------------- DROP TABLE IF EXISTS `stu`; CREATE TABLE `stu` ( `Sno` char(12) NOT NULL DEFAULT '', `Sname` char(20) DEFAULT NULL, `Ssex` char(2) DEFAULT NULL, `Sage` smallint(6) DEFAULT NULL, `Sdept` char(20) DEFAULT NULL, PRIMARY KEY (`Sno`), UNIQUE KEY `Sno` (`Sno`), UNIQUE KEY `Sno_2` (`Sno`), UNIQUE KEY `Sname` (`Sname`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of stu -- ---------------------------- INSERT INTO `stu` VALUES ('121031325', '卫', '男', '22', '计算机学院'); INSERT INTO `stu` VALUES ('121031329', '闻', '男', '20', '计算机学院'); INSERT INTO `stu` VALUES ('121031323', '文', '男', '21', '计算机学院'); INSERT INTO `stu` VALUES ('121031324', '罗', '男', '21', '计算机学院'); INSERT INTO `stu` VALUES ('121031326', '郭王', '男', '22', '计算机学院'); ================================================ FILE: 备用命令行代码及数据库表/workers.sql ================================================ drop table if exists workers; CREATE TABLE `workers` ( 编号 char(12) NOT NULL, 姓名 char(10) DEFAULT NULL, 性别 char(2) DEFAULT '男' check(Wsex in('男','女')), 出生年月 char(8) DEFAULT NULL, 工作月数 int(11) DEFAULT '0' check(WworkTime>=0), 学历 char(10) DEFAULT NULL, 职务 char(20) DEFAULT NULL, 住址 char(30) DEFAULT NULL, 电话 char(12) DEFAULT NULL, PRIMARY KEY (编号) ) ENGINE=InnoDB DEFAULT CHARSET=gbk; INSERT INTO `workers` VALUES ('001', '甲', '男', '1993.2', '1', '本科', '普通员工', '北京', '010-1111111'); INSERT INTO `workers` VALUES ('002', '乙', '女', '1990.3', '16', '本科', '主管', '北京', '010-1111222'); INSERT INTO `workers` VALUES ('003', '丙', '男', '1992.2', '1', '本科', '普通员工', '武汉', '027-1234123'); INSERT INTO `workers` VALUES ('004', '丁', '女', '1993.1', '3', '本科', '普通员工', '武汉', '027-1234567'); ================================================ FILE: 备用命令行代码及数据库表/打开mysql.bat ================================================ mysql -h localhost -u root -p php_db1 < stu.sql pause select * from stu; ================================================ FILE: 备用命令行代码及数据库表/打开命令行.bat ================================================ cmd.exe ================================================ FILE: 备用命令行代码及数据库表/打开命令行操作mysql.bat ================================================ mysql -h localhost -u root -p test show databases; use test; show tables; describe stu; select * from stu; ================================================ FILE: 测试连接.cpp ================================================ #include #include #include #include #pragma comment( lib, "libmysql.lib") int main() { /// 例子1 puts("测试1...(链接)"); //MYSQL句柄 (任何一个mysql操作都是基于MYSQL这个句柄来操作的) MYSQL* link_ = mysql_init(NULL); //初始化MYSQL句柄 //设置超时时间(链接超时时间,查询超时时间,写数据库超时时间) int timeout = 3; //超时时间设置为3秒 if(link_ != NULL) { mysql_options(link_,MYSQL_OPT_CONNECT_TIMEOUT,(const char *)&timeout); //设置链接超时时间. mysql_options(link_,MYSQL_OPT_READ_TIMEOUT,(const char *)&timeout); //设置查询数据库(select)超时时间 mysql_options(link_,MYSQL_OPT_WRITE_TIMEOUT,(const char *)&timeout); //设置写数据库(update,delect,insert,replace等)的超时时间。 } //真正建立mysql链接 char host_name[1024] = "localhost"; //mysql服务器的IP char user_name[1024] = "root"; //用户名 char user_password[1024] = "123456"; ///密码 需要改为自己的密码 char server_name[1024] = "test"; ///数据库名 需要改为自己的数据库名 unsigned short host_port = 3306; //服务器端口 if(!mysql_real_connect(link_,host_name,user_name,user_password,server_name,host_port,NULL,0)) { //失败处理 int error_code = mysql_errno(link_); //获取错误码 //针对不同的错误码error_code,还应该做不同的处理 mysql_close(link_); //释放句柄 printf("链接建立失败! :%s\n",mysql_error(link_)); } else { puts("链接建立成功"); //链接建立成功,可以进行具体的操作(select insert delete update replace等) } /// 例子2,可以和上面一个例子分开运行 puts("\n测试2...(链接并查询)"); char SqlText[256] = ""; MYSQL mysql; MYSQL_RES *res = NULL; MYSQL_FIELD * fd = NULL; MYSQL_ROW row; int i = 0; mysql_init( &mysql ); if ( !mysql_real_connect( &mysql, "localhost", "root", "123456", "test", 3306, NULL, 0) ) { puts("数据库连接失败"); printf( "Error connecting to database: %s\n",mysql_error(&mysql)); mysql_close( &mysql ); return FALSE; } else { puts("数据库连接成功"); mysql_query(&mysql,"set names 'GBK'");//设置字符集,防止中文无法正常显示 sprintf( SqlText, "insert into animals(name, kg) values ('chicken',6), ('dog', 4)"); if ( !mysql_query(&mysql, SqlText ) ) { //insert失败 printf("Can't insert data to table: "); printf("%s\n", mysql_error(&mysql)); mysql_close( &mysql ); return FALSE; } sprintf( SqlText, "select * from %s","stu"); ///stu需要改为自己的数据库中对应的表名 //进行数据检索 if ( !mysql_query(&mysql, SqlText )) { res = mysql_store_result( &mysql ); i = (int)mysql_num_rows( res ); printf("Query: %s\n%d records found:\n", SqlText, i ); //输出各字段名 for (; fd = mysql_fetch_field(res);) printf("%-*s\t",50/mysql_num_fields(res), fd->name ); puts(""); //打印获取的数据 MYSQL_ROW row; //一个行数据的类型安全(type-safe)的表示 while (row = mysql_fetch_row(res)) { //获取下一行 for(int i=0; i #include #include //getche(),getch() #include #include #include using namespace std; class DB_worker { public: DB_worker(const char* tb = "stu"); ~DB_worker(); void showMenu(); void addRecord(); void deleteRecord(); void searchRecord(); void modifyRecord(); void sortRecord(); void showAllRecord(int saveToFile = 0); private: bool executeQuery(const char*s = 0, int show = 1, const char* todo = "select *", int saveToFile = 0); bool createConnection(); void printDateTime(FILE * fp); private: char column[20][30]; //存储属性名称 FILE *fpLog; //存储日志记录 char info[10][50]; //临时存放当前键入的属性值 MYSQL *conn; //mysql连接 MYSQL_RES *res; //这个结构代表返回的一个查询结果集 int num_fields; //结果集中的列数 char query[1024]; //查询语句 char tableName[20]; //表名 }; int main() { system("color fd"); DB_worker workers("workers"); workers.showAllRecord(); workers.showMenu(); return 0; } //构造函数中连接数据库 DB_worker::DB_worker(const char*tb) { fpLog = fopen("log.txt", "a+"); strcpy(tableName, tb); if (!createConnection()) { cout << "数据库连接失败,请检查连接后重试!" << endl; system("pause"); exit(-1); } } //释放连接和其他资源 DB_worker::~DB_worker() { mysql_free_result(res); mysql_close(conn); fclose(fpLog); } void DB_worker::showMenu() { char c = 1; while (c != '0') { showAllRecord(1); for (int j = 0; j < 65; j++) cout << "☆"; cout << endl; cout << "\t\t\t\t\t\t\t1.新增一名职工\n\t\t\t\t\t\t\t2.删除一名职工\n\t\t\t\t\t\t\t" "3.查找\n\t\t\t\t\t\t\t4.修改\n\t\t\t\t\t\t\t5.排序\n\t\t\t\t\t\t\t" "6.显示所有\n\t\t\t\t\t\t\t0.退出" << endl; for (int j = 0; j < 65; j++) cout << "☆"; cout << endl; cout << endl << "请选择: "; do { c = getche(); cout << "\r\t\t\t\r" << c << ":"; switch (c) { case '1': addRecord(); break; case '2': deleteRecord(); break; case '3': searchRecord(); break; case '4': modifyRecord(); break; case '5': sortRecord(); break; case '6': showAllRecord(); break; case '0': break; default: cout << "\r输入错误,请重新输入:"; } } while (c < '0' || c > '6'); cout << endl; fclose(fpLog); fpLog = fopen("log.txt", "a+"); } } void DB_worker::addRecord() { sprintf(query, "insert into %s values ('", tableName); cout << "请输入 " << column[0] << ": "; cin >> info[0]; strcat(query, info[0]); for (int i = 1; i < num_fields; i++) { cout << "请输入 " << column[i] << ": "; cin >> info[i]; strcat(query, "','"); strcat(query, info[i]); } strcat(query, "')"); printDateTime(fpLog); if (mysql_query(conn, query)) { //执行SQL语句 printf("添加失败 (%s)\n", mysql_error(conn)); fprintf(fpLog, "Error: %s (%s)\n", query, mysql_error(conn)); //增加日志 } else { puts("添加成功"); fprintf(fpLog, "%s\n", query); //增加日志 } } void DB_worker::deleteRecord() { char temp[128]; cout << "请输入需要删除的" << column[0] << ": "; cin >> info[0]; sprintf(temp, "where %s='%s'", column[0], info[0]); if (executeQuery(temp)) { //执行SQL语句 cout << "确定删除该元组?(1或y确认):"; char c = getch(); if (c == '1' || c == 'y' || c == 'Y') { printDateTime(fpLog); if (executeQuery(temp, 1, "delete")) { puts("删除成功"); fprintf(fpLog, "%s\n", query); //增加日志 } else { printf("删除失败 (%s)\n", mysql_error(conn)); fprintf(fpLog, "Error: %s (%s)\n", query, mysql_error(conn)); //增加日志 } } else cout << "已取消删除" << endl; } else { printDateTime(fpLog); puts("删除失败 (该元组不存在)"); fprintf(fpLog, "Error: %s : 该元组不存在\n", query); //增加日志 } } void DB_worker::searchRecord() { cout << "请选择查找方式:\n"; for (int i = 0; i < num_fields; i++) cout << i + 1 << "." << column[i] << " "; char c = getch(); if (c > 48 && c < 49 + num_fields) { cout << "\n请输入需要查找的" << column[c - 49] << ": "; cin >> info[0]; char temp[128]; sprintf(temp, "where %s='%s'", column[c - 49], info[0]); executeQuery(temp); } } void DB_worker::modifyRecord() { cout << "请选择需要修改元组的限制属性:\n"; for (int i = 0; i < num_fields; i++) cout << i + 1 << "." << column[i] << " "; char sel = getch(); char temp[128]; if (sel > 48 && sel < 49 + num_fields) { cout << "\r\t\t\t\t\t\t\t\t\t\t\r请输入限制元组的" << column[sel - 49] << ": "; cin >> info[0]; sprintf(temp, "where %s='%s'", column[sel - 49], info[0]); if (executeQuery(temp)) { cout << "请选择需要修改的属性:\n"; for (int i = 0; i < num_fields; i++) cout << i + 1 << "." << column[i] << " "; sel = getch(); if (sel > 48 && sel < 49 + num_fields) { cout << "\r\t\t\t\t\t\t\t\t\t\t\r请输入新的" << column[sel - 49] << ": "; cin >> info[0]; sprintf(query, "update %s set %s='%s' %s", tableName, column[sel - 49], info[0], temp); printDateTime(fpLog); if (mysql_query(conn, query)) { //执行SQL语句 printf("修改失败 (%s)\n", mysql_error(conn)); fprintf(fpLog, "Error: %s (%s)\n", query, mysql_error(conn)); //增加日志 } else { puts("修改成功"); fprintf(fpLog, "%s\n", query); //增加日志 } } } else cout << "未搜索到可修改项,建议更改修改限制属性" << endl; } } void DB_worker::sortRecord() { cout << "请选择排序方式:\n"; for (int i = 0; i < num_fields; i++) cout << i + 1 << "." << column[i] << " "; char c = getch(); if (c > 48 && c < 49 + num_fields) { char temp[128], way[5] = "asc"; cout << "\r\t\t\t\t\t\t\t\t\t\t\t\r以" << column[c - 49] << "降序排序请按1或y,按q取消排序,其他键将按升序排序: "; char c2 = getch(); cout << "\r\t\t\t\t\t\t\t\r按" << column[c - 49]; if (c2 == 'q' || c2 == 'Q') { cout << "\r\t\t\t\t\t\t\t\r已取消排序" << endl; return; } else if (c2 == '1' || c2 == 'y' || c2 == 'Y') { strcpy(way, "desc"); cout << "降序排序" << endl; } else cout << "升序排序" << endl; sprintf(temp, "order by %s %s", column[c - 49], way); if (executeQuery(temp)) { printDateTime(fpLog); fprintf(fpLog, "%s\n", query); } } } void DB_worker::showAllRecord(int saveToFile) { executeQuery(0, 1, "select *", saveToFile); } //连接数据库 bool DB_worker::createConnection() { int result = 1; conn = mysql_init(0); //初始化mysql,连接数据库 //此处密码字段可以根据具体环境修改参数 if (!mysql_real_connect(conn, "localhost", "root", "123456", "test", 0, NULL, 0)) { printf( "Error connecting to database:%s\n", mysql_error(conn)); result = 0; } else { printf("Connected successful\n"); int timeout = 2; //设置查询超时时长 if (conn != NULL) { //设置链接超时时间. mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout); //设置查询数据库(select)超时时间 mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, (const char *)&timeout); //设置写数据库(update,delect,insert,replace等)的超时时间。 mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&timeout); } mysql_query(conn, "set names 'GBK'"); //设置字符集,防止中文无法正常显示 //抽取表头信息并保存到column[] sprintf(query, "select * from %s ", tableName); mysql_query(conn, query); res = mysql_store_result(conn); //必须对返回的指针进行校验,否则如果没有这个表,会导致程序崩溃!! //必须养成校验返回值的习惯,特别是对返回的是指针的情况 if (res != NULL) { num_fields = mysql_num_fields(res); //获取各字段的表头名称 for (int i = 0; i < num_fields; i++) strcpy(column[i], mysql_fetch_field(res)->name); puts(""); } } puts("————————————————————\n"); return result; } //建立查询 bool DB_worker::executeQuery(const char*s, int show, const char* todo, int saveToFile) { sprintf(query, "%s from %s ", todo, tableName); if (s != NULL && s[0] != '\0') // 连接上条件语句 strcat(query, s); if (mysql_query(conn, query)) { //执行SQL语句 printf("Query failed (%s)\n", mysql_error(conn)); return 0; } else if (strcmp(todo, "delete") == 0) return 1; //获取结果集 if (!(res = mysql_store_result(conn))) { //获得sql语句结束后返回的结果集 printf("Couldn't get result from %s\n", mysql_error(conn)); return 0; } //打印结果数 int affect = mysql_affected_rows(conn); if (show) { if (!saveToFile) printf(">>>职工表中————共查询到 %d 组结果<<<\n", affect); //获取字段的信息 if (affect > 0) { if (saveToFile) freopen("data.txt", "w", stdout); for (int i = 0; i < num_fields; i++) printf("%-*s", 130 / num_fields, column[i]); puts(""); //打印获取的数据 MYSQL_ROW row; //一个行数据的类型安全(type-safe)的表示 while (row = mysql_fetch_row(res)) { //获取下一行 for (int i = 0; i < num_fields; i++) printf("%-*s", 130 / num_fields, row[i]); puts(""); } if (saveToFile) { freopen("CON", "w", stdout); return true; } } } puts("————————————————————\n"); return affect; } //在日志文件中打印当前日期和时间 void DB_worker::printDateTime(FILE * fp) { time_t now_time = time(NULL); struct tm *newtime = localtime(&now_time); char tmpbuf[128]; static int first = 1; if (first) { strftime(tmpbuf, 128, "\n******%Y/%m/%d******\n", newtime); fprintf(fp, tmpbuf); first = 0; } strftime(tmpbuf, 128, "%H:%M:%S ", newtime); fprintf(fp, tmpbuf); } ================================================ FILE: 职工管理系统C.cpp ================================================ #include #include #include #include #include #include #include #include using namespace std; char column[20][30]; //洢 FILE *fplog; char info[10][50]; //ʱŵǰֵ MYSQL mysql, *sock; //mysql MYSQL_RES *res; //ṹеһѯ int num_fields; //е char query[1024]; //ѯ char tableName[20]; // bool QueryDatabase(const char*s=0,int show=1,const char* todo="select * "); bool ConnectDatabase(); void printDateTime(FILE * fp); void DB(const char* tb = "worker"); void close(); void Choose(); void Add(); void Delete(); void Search(); void Modify(); void Sort(); void ShowAll(); int main() { DB("workers"); ShowAll(); Choose(); close(); return 0; } void Choose() { char c; while(c!='0') { cout<'6'); cout<>info[0]; strcat(query,info[0]); for(int i=1; i>info[i]; strcat(query,"','"); strcat(query,info[i]); } strcat(query,"')"); printDateTime(fplog); if(mysql_query(sock, query)) { //ִSQL printf("ʧ (%s)\n",mysql_error(sock)); fprintf(fplog,"Error: %s (%s)\n",query,mysql_error(sock)); //־ } else { puts("ӳɹ"); fprintf(fplog,"%s\n",query); //־ } } void Delete() { char temp[128]; cout<<"Ҫɾ"<>info[0]; sprintf(temp,"where %s='%s'",column[0],info[0]); if(QueryDatabase(temp)) { //ִSQL cout<<"ȷɾԪ飿(1yȷ):"; char c=getch(); if(c=='1' || c=='y' || c=='Y') { printDateTime(fplog); if(QueryDatabase(temp,1,"delete")) { puts("ɾɹ"); fprintf(fplog,"%s\n",query); //־ } else { printf("ɾʧ (%s)\n",mysql_error(sock)); fprintf(fplog,"Error: %s (%s)\n",query,mysql_error(sock)); //־ } } else cout<<"ȡɾ"<48 && c<49+num_fields) { cout<<"\nҪҵ"<>info[0]; char temp[128]; sprintf(temp,"where %s='",column[c-49]); strcat(temp,info[0]); strcat(temp,"'"); QueryDatabase(temp); } } void Modify() { cout<<"ѡҪ޸ĵ:\n"; for(int i=0; i48 && c<49+num_fields) { cout<<"\nԵ"<>info[0]; sprintf(temp,"where %s='%s'",column[c-49],info[0]); if(QueryDatabase(temp)) { cout<<"ѡҪ޸ĵ:\n"; for(int i=0; i48 && c<49+num_fields) { cout<<"\nµ"<>info[0]; sprintf(query, "update %s set %s='%s' %s",tableName,column[c-49],info[0],temp); printDateTime(fplog); if(mysql_query(sock, query)) { //ִSQL printf("޸ʧ (%s)\n",mysql_error(sock)); fprintf(fplog,"Error: %s (%s)\n",query,mysql_error(sock)); //־ } else { puts("޸ijɹ"); fprintf(fplog,"%s\n",query); //־ } } } else cout<<"δ޸޸"<48 && c<49+num_fields) { char temp[128], way[5]="asc"; cout<<"\r"<name); puts(""); } puts("\n"); return result; } //ѯ bool QueryDatabase(const char*s,int show,const char* todo) { int result = 1; sprintf(query, "%s from %s ",todo,tableName); if(s) strcat(query,s); if(mysql_query(sock, query)) { //ִSQL printf("Query failed (%s)\n",mysql_error(sock)); return 0; } else if(strcmp(todo,"delete")==0) return 1; //ȡ if (!(res=mysql_store_result(sock))) { //sql󷵻صĽ printf("Couldn't get result from %s\n", mysql_error(sock)); return 0; } //ӡ int affect = mysql_affected_rows(sock); if(show) { printf(">>>ѯ %d <<<\n",affect); //ȡֶεϢ if(affect>0) { for(int i=0; i