C++学习日志之二—贪吃蛇网游化框架搭建4数据库连接
2017-06-20 19:47
766 查看
数据库采用开源的MySQL 5.7,使用windows平台的ODBC连接,MySQL安装部分就直接略过了,安装完成之后,打开一个Query创建一个snakes数据库以及相应的表:
这样就创建了两个相互关联的表usersdata和snakesdata,前者保存用户账户和密码,后者保存用户的游戏数据,这里创建一个测试账户,用户名aa,密码bb:
到这里在MySQL里的工作就基本完成了,之后在window下搜索ODBC数据源,在用户DSN中加入snakes数据库,设置好账户和密码,确定后数据源添加成功:
下面在服务端中添加与数据库连接以及操作数据库的相关代码,通过ODBC连接和操作数据库的优势在于可使用标准SQL语句对任意的数据库进行操作,msdn中有关于ODBC操作数据库的详细指导:https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server
主要代码如下:
首先分配一个环境句柄,设置环境属性,分配一个连接句柄,调用SQLconnect函数进行连接,结合连接句柄分配一个语句句柄,完成之后就可以通过该语句句柄调用SQLexecDirect或SQLexecute函数对数据库进行相应的操作。先分别定义一个对数据库进行读写的函数:
两个函数的逻辑基本一致,先调用sprintf函数生成要执行的SQL语句,再调用SQLExecDirect函数对语句进行执行,在之后的程序运行过程中,当客户端发送账户数据时,服务端调用readdb从数据库读取数据,若账户验证成功则加载游戏数据到缓存中,若密码也验证成功则将缓存中的游戏数据发送到客户端,客户端读取相应的数据后开始游戏;而每当客户端关闭连接后,需要调用writedb函数将缓存中数据写入进数据库。
create DATABASE snakes; use snakes; CREATE TABLE usersdata ( users varchar(20) NOT NULL, codes` varchar(20) DEFAULT '0000', PRIMARY KEY (users) ) ENGINE=InnoDB DEFAULT CHARSET=utf8' create table snakesdata ( food varchar(4), body varchar(200), direction varchar(3), score varchar(3), record varchar(3), user_id varchar(20) NOT NULL PRAMARY KEY, FOREIGN KEY (user_id) REFERENCES usersdata (users) ON DELETE CASCADE ON UPDATE CASCADE );
这样就创建了两个相互关联的表usersdata和snakesdata,前者保存用户账户和密码,后者保存用户的游戏数据,这里创建一个测试账户,用户名aa,密码bb:
insert into usersdata values ('uaa','bb'); insert into snakesdata (user_id) values ('uaa');
到这里在MySQL里的工作就基本完成了,之后在window下搜索ODBC数据源,在用户DSN中加入snakes数据库,设置好账户和密码,确定后数据源添加成功:
下面在服务端中添加与数据库连接以及操作数据库的相关代码,通过ODBC连接和操作数据库的优势在于可使用标准SQL语句对任意的数据库进行操作,msdn中有关于ODBC操作数据库的详细指导:https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server
主要代码如下:
SQLHENV henv = SQL_NULL_HENV;//定义环境句柄 SQLHDBC hdbc1 = SQL_NULL_HDBC;//定义数据库连接句柄 SQLHSTMT hstmt1 = SQL_NULL_HSTMT;//定义语句句柄 short connecttodb() { RETCODE retcode;//错误返回码 retcode = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);//allocate environment handle if (retcode < 0)//错误处理 { printf("allocate ODBC Environment handle errors.\n"); return 0; } retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);//set environment handle attributes if (retcode < 0) //错误处理 { printf("the ODBC is not version3.0\n "); return 0; } retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);//allocate connection handle based on allocated environment handle if (retcode < 0) //错误处理 { printf("allocate ODBC connection handle errors.\n"); return 0; } char* szDSN = "mysqltest";//添加数据源时,为其起的名字 char* szUID = "root"; char* szAuthStr = "VIvi3154"; retcode = SQLConnect(hdbc1, (SQLCHAR*)szDSN, (SWORD)strlen(szDSN), (SQLCHAR*)szUID, (SWORD)strlen(szUID), (SQLCHAR*)szAuthStr, (SWORD)strlen(szAuthStr)); if (retcode < 0) //错误处理 { printf("connect to ODBC datasource errors.\n"); return 0; } retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1); //allocte s if (retcode < 0) { printf("allocate ODBC statement handle errors.\n"); return 0; } return 1; }
首先分配一个环境句柄,设置环境属性,分配一个连接句柄,调用SQLconnect函数进行连接,结合连接句柄分配一个语句句柄,完成之后就可以通过该语句句柄调用SQLexecDirect或SQLexecute函数对数据库进行相应的操作。先分别定义一个对数据库进行读写的函数:
char body[8] = { 'b',20,20,20,21,20,22 }; char food[4] = { 'f',14,18 };//横坐标一定为偶数 char direction[3]="dd"; char score[3] = { 's',0 }; char record[3] = { 'r',1 }; short readdb(const char *user) { char buff[200]; sprintf(buff, "select users,codes,body,food,direction,score,record from usersdata join snakesdata on users=user_id where users='%s';" , user); RETCODE retcode; while ((retcode = SQLExecDirect(hstmt1, buff, SQL_NTS)) < 0) { if (retcode = SQL_ERROR) { SQLSMALLINT errmsglen; SQLINTEGER errnative; UCHAR errmsg[255]; UCHAR errstate[5]; SQLGetDiagRec(SQL_HANDLE_STMT, hstmt1, 1, errstate, errnative, errmsg, sizeof(errmsg), &errmsglen); if(strcmp("42S02", errstate)==0)//读取不到该数据,即账号不存在 return 0; } printf("readdata from database error,press any key to retry...\n"); system("pause>>nul"); } return 1; } void writedb(user) { char buff[1000]; sprintf(buff, "update snakesdata set body ='%s',food='%s',direction='%s',score='%s',record='%s' where user_id='%s'", body, food, direction, score, record, user); RETCODE retcode; while ((retcode = SQLExecDirect(hstmt1, buff, SQL_NTS)) < 0) { printf("senddata to database error,press any key to retry...\n"); system("pause>>nul"); } } void reset(const char *user) { writedb(user); }
两个函数的逻辑基本一致,先调用sprintf函数生成要执行的SQL语句,再调用SQLExecDirect函数对语句进行执行,在之后的程序运行过程中,当客户端发送账户数据时,服务端调用readdb从数据库读取数据,若账户验证成功则加载游戏数据到缓存中,若密码也验证成功则将缓存中的游戏数据发送到客户端,客户端读取相应的数据后开始游戏;而每当客户端关闭连接后,需要调用writedb函数将缓存中数据写入进数据库。
相关文章推荐
- C++学习日志之二—贪吃蛇网游化框架搭建2
- 关于后盾网yii框架的学习小结(6)--数据库连接配置与模型定义与后台登陆验
- C/C++连接数据库MySQL(自己写的一个通讯录软件,供大家学习交流)
- 【J2EE核心开发学习笔记 010】struts2的搭建及连接数据库实现用户注册与登录
- java ee SSM框架连接数据库四个配置文件之二: mybatis-config.xml文件配置
- NHibernate学习之二——.cfg.xml配置大全(数据库连接配置)
- ssm框架学习---传统使用jdbc连接数据库的问题
- 关于后盾网yii框架的学习小结(6)--数据库连接配置与模型定义与后台登陆验
- [我的PHP之旅] YII框架学习 03.连接数据库(使用ActiveRecord)
- 黑马程序员 java基础 连接数据库学习日志
- solr搜索引擎框架搭建,建立多核(多core),与数据库连接,案例分析及动态配置数据库
- C++与数据库连接
- C++学习日志1-基本类型
- C++学习摘要之二:构造函数和析构函数
- ODBC数据库连接------java学习笔记之3
- ADO.NET的学习笔记(一)--数据库连接及常用的数据库访问方式
- 可重用的数据库连接框架
- ASP.NET连接数据库SQL2005 学习总结
- SQL Server Mobile 学习(二):通过 VS2005 创建和连接及操作 SQL Server Mobile 数据库
- SQL Server Mobile 学习(二):通过 VS2005 创建和连接及操作 SQL Server Mobile 数据库