用C++封装一个mysqlAPI

测试环境声明:CentOS6.5、mysql 5.1
在写代码之前我们应先学习一下mysql中的数据类型以及基本的函数,如下列举了我们今天要使用数据类型和函数的介绍:
mysql中的基本数据类型:
- MYSQL
该结构代表1个数据库连接的句柄。几乎所有的MySQL函数均使用它。不应尝试拷贝MYSQL结构。不保证这类拷贝结果会有用。
- MYSQL_RES
该结构代表返回行的查询结果(SELECT, SHOW, DESCRIBE, EXPLAIN),一般将查询返回的信息称为“结果集”。
- MYSQL_ROW
这是1行数据的“类型安全”表示。它目前是按照计数字节字符串的数组实施的。(如果字段值可能包含二进制数据,不能将其当作由Null终结的字符串对待,这是因为这类值可能会包含Null字节)。行是通过调用mysql_fetch_row()获得的。
- MYSQL_FIELD
该结构包含关于字段的信息,如字段名、类型和大小。通过重复调用mysql_fetch_field(),可为每个字段获得MYSQL_FIELD结构。字段值不是该结构的组成部份,它们包含在MYSQL_ROW结构中。

要使用的几个函数介绍:

MYSQL *mysql_init(MYSQL *mysql);

描述:
分配或初始化与mysql_real_connect()相适应的MYSQL对象。如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时。将释放该对象。
返回值:
初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL。

void mysql_close(MYSQL *mysql);

描述:
关闭前面打开的连接。如果句柄是由mysql_init()或mysql_connect()自动分配的,mysql_close()还将解除分配由mysql指向的连接句柄。
返回值:
无。

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *dbname, unsigned int port, const char *unix_socket, unsigned long client_flag);

描述:
mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。在你能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect()必须成功完成。
参数的指定方式如下:
第1个参数应是已有MYSQL结构的地址。调用mysql_real_connect()之前,必须调用mysql_init()来初始化MYSQL结构。
“host”的值必须是主机名或IP地址。如果“host”是NULL或字符串”localhost”,连接将被视为与本地主机的连接。如果操作系统支持套接字(Unix)或命名管道(Windows),将使用它们而不是TCP/IP连接到服务器。
“user”参数包含用户的MySQL登录ID。如果“user”是NULL或空字符串”“,用户将被视为当前用户。在UNIX环境下,它是当前的登录名。在Windows ODBC下,必须明确指定当前用户名。
“passwd”参数包含用户的密码。如果“passwd”是NULL,仅会对该用户的(拥有1个空密码字段的)用户表中的条目进行匹配检查。这样,数据库管理员就能按特定的方式设置MySQL权限系统,根据用户是否拥有指定的密码,用户将获得不同的权限。
(调用mysql_real_connect()之前,不要尝试加密密码,密码加密将由客户端API自动处理。)
“dbname”是数据库名称。如果dbname为NULL,连接会将默认的数据库设为该值。
如果“port”不是0,其值将用作TCP/IP连接的端口号。注意,“host”参数决定了连接的类型。
如果unix_socket不是NULL,该字符串描述了应使用的套接字或命名管道。注意,“host”参数决定了连接的类型。
client_flag的值通常为0。当然,也能将其设置为其他标志的组合,这里不做说明,想深入了解的可以自己查阅相关资料。
对于某一参数,如果在选项文件中未发现值,将使用它的默认值。
以上每个参数指定的默认值为:
· 对于host,指定NULL值或空字符串(“”)。
· 对于user,指定NULL值或空字符串。
· 对于passwd,指定NULL值。(对于密码,mysql_real_connect()调用中的空字符串的值不能被选项文件中的字符串覆盖,这是因为,空字符串明确指明MySQL账户必须有空密码)。
· 对于dbname,指定NULL值或空字符串
· 对于port,指定“0”值。
· 对于unix_socket,指定NULL值。
返回值:
如果连接成功,返回MYSQL*连接句柄。如果连接失败,返回NULL。对于成功的连接,返回值与第1个参数的值相同。

int mysql_query(MYSQL *mysql, const char *query);

描述:
执行由“Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含多条由分号隔开的语句。
返回值:
如果查询成功,返回0。如果出现错误,返回非0值。

MYSQL_RES *mysql_store_result(MYSQL *mysql)

描述:
对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()或mysql_use_result() 。
对于其他查询,不需要调用mysql_store_result()或mysql_use_result(),但是如果在任何情况下均调用了mysql_store_result(),它也不会导致任何伤害或性能降低。通过检查mysql_store_result()是否返回0,可检测查询是否没有结果集。
如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。
mysql_store_result()将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中。
如果查询未返回结果集,mysql_store_result()将返回Null指针(例如,如果查询是INSERT语句)。
如果读取结果集失败,mysql_store_result()还会返回Null 指针。通过检查mysql_error()是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0,可以检查是否出现了错误。
如果未返回行,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。
一旦调用了mysql_store_result()并获得了不是Null指针的结果,可调用mysql_num_rows()来找出结果集中的行数。
可以调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()和mysql_row_tell()来获取或设置结果集中的当前行位置。
一旦完成了对结果集的操作,必须调用mysql_free_result()。
返回值:
具有多个结果的MYSQL_RES结果集合。如果出现错误,返回NULL。

void mysql_free_result(MYSQL_RES *result);

描述:
释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为结果集分配的内存。完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。释放完成后,不要尝试访问结果集。
返回值:
无。

unsigned int mysql_num_fields(MYSQL_RES *result)

要想传递MYSQL*参量取而代之,请使用无符号整数mysql_field_count(MYSQL *mysql)。
描述:
返回结果集中的行数。
注意,你可以从指向结果集的指针或指向连接句柄的指针获得行数。如果mysql_store_result()或mysql_use_result()返回NULL,应使用连接句柄(因而没有结果集指针)。在该情况下,可调用mysql_field_count()来判断mysql_store_result()是否生成了非空结果。这样,客户端程序就能采取恰当的行动,而不需要知道查询是否是SELECT语句(或类似SELECT的语句)。在下面的示例中,介绍了执行该操作的方式。
返回值:
表示结果集中行数的无符号整数。

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

描述:
检索结果集的下一行。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。
行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],访问这些值的指针。行中的NULL值由NULL指针指明。
可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,字段为NULL,否则字段为空。
返回值:
下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);

描述:
返回采用MYSQL_FIELD结构的结果集的列。重复调用该函数,以检索关于结果集中所有列的信息。未剩余字段时,mysql_fetch_field()返回NULL。
每次执行新的SELECT查询时,将复位mysql_fetch_field(),以返回关于第1个字段的信息。调用mysql_field_seek()也会影响mysql_fetch_field()返回的字段。
如果调用了mysql_query()以在表上执行SELECT,但未调用mysql_store_result(),如果调用了mysql_fetch_field()以请求BLOB字段的长度,MySQL将返回默认的Blob长度(8KB)。之所以选择8KB是因为MySQL不知道BLOB的最大长度。应在日后使其成为可配置的。一旦检索了结果集,field->max_length将包含特定查询中该列的最大值的长度。
返回值:
当前列的MYSQL_FIELD结构。如果未剩余任何列,返回NULL。
sql_api.h

#include
#include"/usr/include/mysql/mysql.h"
#include
#include
using namespace std;

class sql_api
{
public:
    sql_api();
    ~sql_api();
    bool sql_connect(string host,string user,string password,string dbname);
    bool Insert(const char * str);
    bool Delete(const char *str);
    bool Update(const char *str);
    bool Select();
private:
    MYSQL * conn;//mysql连接
};

sql_api.cpp

#include"sql_api.h"

sql_api::sql_api()
{
    conn = mysql_init(NULL);
}   
sql_api::~sql_api()
{
    mysql_close(conn);
}
bool sql_api::sql_connect(string host,string user,string password,string dbname)
{
    conn = mysql_real_connect(conn,host.c_str(),user.c_str(),password.c_str(), dbname.c_str(),0,NULL,0);
    if(conn ==NULL)
    {
        cout<<"mysql_real_connect is failed"<return false;
    }
        return true;
}
//插入数据
bool sql_api::Insert(const char *info)
{
    string sql ="INSERT INTO myhttp_info(id,name,age,sex,school)values(";
    sql += info;
    sql += ");";
    cout<int ret =mysql_query(conn,sql.c_str());
    if(ret != 0)
    {
        return false;
    }
    return true;
} 
//删除数据
bool sql_api::Delete(const char *info)
{
    string sql ="DELETE FROM myhttp_info WHERE(";
    sql += info;
    sql += ");";
    cout<int ret =mysql_query(conn,sql.c_str());
    if (ret != 0)
    {
        return false;
    }
    return true;
}
//修改数据
bool sql_api::Update(const char * info)
{
    string sql = "UPDATE myhttp_info SET ";
    sql += info;
    sql += ';';
    cout<int ret =mysql_query(conn,sql.c_str());
    if(ret != 0)
    {
        return false;
    }
    return true;
}
//查找数据
bool sql_api::Select()
{
    string sql="SELECT * FROM myhttp_info;";
    int ret = mysql_query(conn,sql.c_str());
    if (ret != 0)
    {
        return false;
    }
        MYSQL_RES *res =mysql_store_result(conn);
        //"id" "name" "age" "sex" "school"
        if (res == NULL)
        {
            return false;
        }
        int num_fields =mysql_num_fields(res);//行数
        MYSQL_FIELD *field ;//
        MYSQL_ROW rows;//结果集的下一行
        while(field = mysql_fetch_field(res))
        {
            cout<name<<' ';
        }
        cout<while(rows = mysql_fetch_row(res))
        {   
            int i=0;
            for(i=0;icout<' ';
            }
            cout<return true;
}

int main()
{
    sql_api my_api;
    if(!my_api.sql_connect("127.0.0.1","root","qaz","myhttp"))
    {
        return -1;
    }
    my_api.Select();
    my_api.Insert("1,'张三',20,'男','SUST'");
    my_api.Insert("2,'李四',21,'男','XATU'");
    my_api.Insert("3,'王五',20,'男','清华'");
    my_api.Insert("4,'小红',20,'男','北大'");
    my_api.Insert("5,'小明',19,'女','西工大'");
    my_api.Insert("6,'小李',22,'男','交大'");
    my_api.Select();
    my_api.Update("age=30 where name ='王五'");
    my_api.Select();
    my_api.Update("school ='xatu' where id =2");
    my_api.Select();
    my_api.Update("sex ='女' where name ='小红'");
    my_api.Select();
    my_api.Delete("name ='张三'");
    my_api.Select();
    my_api.Delete("school ='西工大'");
    my_api.Select();
    return 0;
}

执行过程:
g++ -o sql_api sql_api.cpp -L /usr/lib/mysql -lmysqlclient

运行结果:
用C++封装一个mysqlAPI_第1张图片

代码已托管至github,需要源代码可自行下载:
https://github.com/Sunxy7/PracticeCode/tree/master/sql_api

你可能感兴趣的:(C++,MySql)