游戏服务端之C++封装Mysql

很多缺少实际工作经验的同学会认为,操作MySQL还需要封装?!直接写sql语句操作就可以了。其实封装Mysql有以下的好处:

1、更加安全。即使你是相当谨慎的一个程序员,就算在几百处甚至几千处地方写sql操作Mysql也避免不了会出现写错表名,字段名写错了或者写少写多了,符号写错等等。封装可以解决这些问题。

2、更好的移植性。封装其实就是一些共性的集合,这样当然具有更好的移植性了(这样能方便像我一样的搬运工搬代码了)。

3、更好的可读性。封装一般具有更好的可读性,当然在我接触过的一些代码中,封装了之后,可读性更差了;其可读性主要是封装得难以理解,在看不到源代码的时候,根本不知道这些代码有什么作用。

4、能提高程序效率。我们都知道,IO操作的效率是比较低下,读写数据库也属于IO操作的范畴。一般提高读写Mysql的效率在于在一次IO操作中尽量操作更多的数据。例如批量插入数据(INSERT)。当然不用封装也可以批量操作,只是比较困难。

5、更加容易维护。可以想像一下,当你数据库表结构发生变化的时候,如果你用浅白的sql操作Mysql,你要在每一个使用过的地方都要修改,不但增加了工作量,而且更容易出错。

6、更有效率。这里的效率是开发效率,统合以上几点,不难知道封装能具有更好的开发效率。

(PS:上述的封装是指好的封装,差的封装有可能适得其反)

下面先看一下用例,以查找为例:

数据库表new_table的所有数据


代码的调用

    #include <stdio.h>  
    #include <time.h>  
      
    #include "globalvariable.h"  
    #include "luaengine.h"  
    #include "gamesocket.h"  
    #include "log.h"  
    #include "dll.h"  
    #include "MyDll.h"  
    #include "gametime.h"  
    #include "frame.h"  
    #include "datatable.h"  
    #include "showcrash.h"  
    #include "globalfunction.h"  
      
    int main()  
    {  
        GameMysql::ALLROWS rows;  
        int fieldlen = Table::new_table.Find(rows);  
      
        for (int i = 0; i < rows.length; ++i)  
        {  
            for(int j =0; j< fieldlen; ++j)  
            {  
                 printf("%s\t",rows.row[i][j]);  
            }  
            printf("\n");  
        }  
        GameMysql::ClearAllRows(rows);  
      
        printf("\nadd a condition.....\n");  
        Table::new_table.SetSelectCondition(Table::NEW_TABLE::Fields[Table::NEW_TABLE::Age],99,GameMysql::EQ);  
        fieldlen = Table::new_table.Find(rows);  
      
        for (int i = 0; i < rows.length; ++i)  
        {  
            for(int j =0; j< fieldlen; ++j)  
            {  
                 printf("%s\t",rows.row[i][j]);  
            }  
            printf("\n");  
        }  
        GameMysql::ClearAllRows(rows);  
      
        printf("\nadd more a condition.....\n");  
        Table::new_table.SetSelectCondition(Table::NEW_TABLE::Fields[Table::NEW_TABLE::Age],99,GameMysql::EQ,false);  
        Table::new_table.SetSelectCondition(Table::NEW_TABLE::Fields[Table::NEW_TABLE::School],"XX大学",GameMysql::EQ);  
        fieldlen = Table::new_table.Find(rows);  
      
        for (int i = 0; i < rows.length; ++i)  
        {  
            for(int j =0; j< fieldlen; ++j)  
            {  
                 printf("%s\t",rows.row[i][j]);  
            }  
            printf("\n");  
        }  
        return 0;  
      
    }  




下这里定义了表的结构

    #ifndef DATATABLE_H  
    #define DATATABLE_H  
    #include "gamemysql.h"  
      
    namespace Table  
    {  
        GameMysql new_table("new_table");  
        namespace NEW_TABLE  
        {  
            enum Field  
            {  
                Name,  
                Age,  
                School  
            };  
            const char * Fields[] = {"name","age","school"};  
        }  
      
        GameMysql gametime("gametime");  
        namespace GAMETIME  
        {  
            enum Field  
            {  
                OpenServerTime,  
                ActiveDate,  
                PetLiveTime,  
                Time  
            };  
            const char * Fields[] = {"openservertime","activedate","petlivetime","time"};  
        }  
    }  
      
      
    #endif // DATATABLE_H  

在这里设置查询条件,一般在游戏当中,只保存整型和字符串。

    void GameMysql::SetSelectCondition( string field, int val, unsigned int r, bool isend /*= true*/ ,unsigned int c)  
    {  
        CHECKRELATION(r);  
        CHECKCONNECT(c);  
        SETTEMP(connect[c]);  
        static char str_val[32];  
        sprintf(str_val,"%d",val);  
      
        m_condition[GameMysql::SELECT] =  m_condition[GameMysql::SELECT] + field + relation[r] +str_val + temp;  
    }  
      
    void GameMysql::SetSelectCondition( string field, string val, unsigned int r, bool isend /*= true*/ ,unsigned int c)  
    {  
        CHECKRELATION(r);  
        CHECKCONNECT(c);  
        SETTEMP(connect[c]);  
      
        m_condition[GameMysql::SELECT] =  m_condition[GameMysql::SELECT] + field + relation[r] + "'" + val + "'" + temp;  
    }  

最后就是执行查询了

    unsigned int  GameMysql::Find(ALLROWS &rows)  
    {  
        HANDLEERROR(0);  
        if (m_findval == "") m_findval = "*";  
      
        if (m_condition[GameMysql::SELECT] == "" )  
        {  
            m_sql[GameMysql::SELECT] = "SELECT " + m_findval + " FROM " + m_tablename;  
        }  
        else  
        {  
            m_sql[GameMysql::SELECT] = "SELECT " + m_findval + " FROM " + m_tablename  + " WHERE " + m_condition[GameMysql::SELECT];  
            m_condition[GameMysql::SELECT] = "";  
        }  
      
      
        static unsigned int field_len = 0;  
      
        if (0 != mysql_query(g_db_handle,m_sql[GameMysql::SELECT] .c_str()))  
        {  
            printf("Mysql Find Rows Error...\n");  
            field_len = 0;  
            rows.length = 0;  
        }  
        else  
        {  
            m_data_res = mysql_store_result(g_db_handle);  
            static MYSQL_ROW row;  
            while((row = mysql_fetch_row(m_data_res)) != NULL)  
            {  
                rows.row.push_back(row);  
            }  
            field_len = mysql_num_fields(m_data_res);  
            rows.length = mysql_num_rows(m_data_res);  
      
            mysql_free_result(m_data_res);  
        }  
        m_findval = "";  
        return field_len;  
    }  

当然以上只是提供对Mysql封装的一个思路,也许你有更好的思路!也许之后我不再认为这是一种好设计!

原文地址:http://blog.csdn.net/yitouhan/article/details/17187569

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值