赞
踩
MYSQL* mysql_init(MYSQL *mysql);
返回一个MYSQL 句柄,对应这个句柄MySQL会在数据库内部分配一个对象并开辟内存,用于存储关联这个连接的处理信息。
后续所有的对这条数据库连接的操作都是通过这个句柄,类似于socket()返回的sockfd。
如果MySQL内部内存不足,则返回NULL。
int mysql_options(MYSQL* mysql, enum mysql_option option, const void* arg);
设置额外的连接选项,用于控制连接行为。
在 mysql_init
之后、mysql_connect
之前 进行调用。
option
参数用于指定要设置的选项类型;
arg
参数用于设置此选项的值。
常用的选项有:
MYSQL_OPT_RECONNECT
:当发现连接断开时,自动进行重连(例如超8小时无活动,连接被MySQL server断开后,再次进行访问时发现连接已断开,会自动进行重连)
MYSQL_SET_CHARSET_NAME
:设置默认的charset
MYSQL* mysql_real_connect( MYSQL* mysql,
const char* host, const char* user, const char* passwd,
const char* db, unsigned int port, const char* unix_socket, unsigned long client_flag);
用于向MySQL server发起连接,后续所有的对数据库的操作都需要先建立连接。
int CDBConn::Init() { m_mysql = mysql_init(NULL); if(!m_mysql) { return -1; } my_bool reconnect = true; mysql_options(m_mysql, MYSQL_OPT_RECONNECT, &reconnect); mysql_options(m_mysql, MYSQL_OPT_CHARSET_NAME, "utf8mb4"); if(mysql_real_connect(m_mysql, m_pDBPool->GetDBServerIP(), m_pDBPool->GetUsername(), m_pDBPool->GetPassword(), m_pDBPool->GetDBName(), m_pDBPool->GetDBServerPort(), NULL, 0) ) { return -1; } return 0; }
int mysql_ping(MYSQL* mysql);
检查与MySQL的连接是否正常。如果连接已经断开,且已设置了自动重连 MYSQL_OPT_RECONNECT
选项,则发起自动重连;
如果没有开启自动重连选项,则返回error。
int mysql_real_query(MYSQL* mysql, const char* stmt_str, unsigned long length);
执行参数 stmt_str
传入的查询语句,其中不包含 “;” SQL语句结束符。
MYSQL_RES* mysql_store_result(MYSQL* msyql);
在调用 mysql_real_query
之后,必须 调用 mysql_store_result
用于存放查询结果。
且在使用完毕后,必须 调用 mysql_free_result
去释放 mysql_store_result
分配的内存(用于保存查询结果的内存)。
void mysql_free_result(MYSQL_RES *result);
用于释放前面 mysql_store_result
分配的内存。
CResultSet* CDBConn::ExcuteQuery(const char* sql_query) { mysql_ping(m_mysql); if(mysql_real_query(m_mysql, sql_query, strlen(sql_query))) { printf("mysql_real_query failed: %s, sql: %s\n", mysql_error(m_mysql), sql_query); return NULL; } MYSQL_RES* res = mysql_store_result(m_mysql); if(!res) { printf("mysql_store_result failed: %s\n", mysql_error(m_mysql)); return NULL; } //将查询到的结果MYSQL_RES封装成CResultSet对象返回给上级调用函数,待外层函数使用完毕后再调用 mysql_free_result 去释放这块内存 CResultSet* result_set = new CResultSet(res); return result_set; }
unsigned int mysql_num_fields(MYSQL_RES* result);
返回查询结果集中的列的数目。
MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES* result);
返回查询结果集中所有 MYSQL_FIELD 结构的数组。数组中的每个结构体表示一个列的字段定义。“对一个列的属性描述”,包括列名、列数据类型等
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
检索查询结果集(MYSQL_RES) 中的下一行。
在 mysql_store_result 之后使用时,如果没有要检索的行,或者检索出错,mysql_fetch_row()返回NULL;
行内值的数据由 mysql_num_fields() 给出(即列的数目),可通过 row[column_index] 访问这些指针(从 row[0] 到 row[mysql_num_fields()-1])
//将mysql_store_result返回的MYSQL_RES查询结构进行解析、分解后,存储在CResultSet对象中: class CResultSet { public: CResultSet(MYSQL_RES* res); virtual ~CResultSet(); bool Next(); int GetInt(const char* key); char* GetString(const char* key); private: int _GetIndex(const char* key); private: MYSQL_RES* m_res; MYSQL_ROW m_row; map<string, int> m_key_map; };
my_ulonglong mysql_affected_rows(MYSQL *mysql);
返回上次UPDATE更改的行数,上次DELETE删除的行数,或者上次INSERT语句插入的行数。
对于UPDATE、DELETE、INSERT语句,可以在 msyql_query() 后立刻调用;
对于SELECT语句,mysql_affected_rows() 的工作方式与mysql_num_rows类似。
//例如 char* sql_query = "update [table_name] set [change_value] where [select_option];" bool CDBConn::ExcuteUpdate(const char* sql_query) { mysql_ping(m_mysql); if(mysql_real_query(m_mysql, sql_query, strlen(sql_query))) { printf("mysql_real_query failed: %s\n", mysql_error(m_mysql)); return false; } //使用msyql_affected_rows检查UPDATE等语句是否正确生效: if(mysql_affected_rows(m_mysql) > 0) { return true; } else { return false; } }
PrepareStatement主要是使用【预编译】防止SQL注入。
预编译语句就是将这类语句中的值用“占位符”(?) 替代,可以视为将sql语句“模板化”或者“参数化”。
一次编译,多次运行,省去了解析优化等过程。
预编译 的作用:
(1)预编译阶段可以优化sql的执行;
(2)防止SQL注入:
使用预编译,而其后注入的参数将不会再进行SQL编译,也就是说其后注入进来的参数将不会认为它是一条SQL语句,
而默认其是一个参数,参数中的 or 或者 and 等就不是SQL语句保留字了。
创建 MYSQL_STMT 句柄
MYSQL_STMT* mysql_stmt_init(MYSQL *mysql);
描述: 创建 MYSQL_STMT 句柄。对于该句柄,应该用 mysql_stmt_close(MYSQL_STMT*); 释放。
返回值:成功时返回指向MYSQL_STMT结构的指针;失败时返回NULL。
作用相当于是注册一条带有“?”参数标记符 的SQL语句,这里应该就是【预编译】的操作
int mysql_stmt_prepare(MYSQL_STMT* stmt, const char* query, unsigned long length);
入参:
给定mysql_stmt_init返回的MYSQL_STMT 句柄,以及待执行的SQL语句(字符串、字符串长度)。
通过将问号字符 “?” 嵌入到SQl字符串的恰当位置,应用程序可包含SQL语句中的一个或多个参数标记符。
标记符仅在SQL语句中的特定位置时才是合法的。
执行语句之前,必须使用 mysql_stmt_bind_param(),将“参数标记符”(?) 与 “应用程序变量” 绑定到一起。
(mysql_stmt_bind_param 相当于是一个传参的过程,?是形参,应用程序传入的变量是实参。)
使用举例:
mysql_stmt_prepare( m_stmt, sql.c_str(), sql.size() );
string sql = "insert into IMMessage_x (related, fromId, toId, msgId, content, status, type, created, updated) values (?,?,?,?,?,?,?,?,?)";
unsigned long mysql_stmt_param_count(MYSQL_STMT* stmt);
返回预处理语句中参数标记符的数目。
my_bool mysql_stmt_bind_param(MYSQL_STMT* stmt, MYSQL_BIND* bind);
用于为SQL语句中的 “参数标记符”(?) 绑定数据(“实参”),以传递给 mysql_stmt_prepare中的?位置。
注入此函数需要使用 MYSQL_BIND* 为元素类型的数组进行入参,所以在调用函数之前需要先 new MYSQL_BIND[param_count] 构造一个数组。
int mysql_stmt_excute(MYSQL_STMT* stmt);
执行与语句相关的预处理查询。
将当前绑定的参数标记符的值发送给服务器,服务器用新提供的数据替换标记符。
如果语句是insert/update/delete(增删改),通过调用 mysql_stmt_affected_rows() 确认更改/插入/删除的总行数;
如果语句是 select,则需要调用 msyql_stmt_fetch() 来获取数据。
my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT* stmt);
返回上次执行语句更改、删除或插入的总行数。
同mysql_fetch_row / mysql_fetch_fields 的用法。
my_ulonglong mysql_stmt_insert_id(MYSQL_STMT* stmt);
返回预处理“INSERT”或者“UPDATE” 语句为 AUTO_INCREMENT列生成的值。
在包含
也就是说,如果一个表中有某个列的属性是AUTO_INCREMENT自增的,那么当对这个表进行一次INSERT或者UPDATE后,
调用mysql_stmt_insert_id()这个函数就可以得到INSERT操作新增的行元素的自增一列的值。
待补充。。。。。。
MYSQL_STMT* m_stmt = mysql_stmt_init(MYSQL* m_mysql); mysql_stmt_prepare(m_stmt, sql.c_str(), sql.size()); //sql="insert into ... values (???)" mysql_stmt_param_count(m_stmt); //只是一个安全校验 MYSQL_BIND* m_param_bind = new MYSQL_BIND[m_param_cnt]; //new一块堆内存 m_param_bind[index].buffer_type = MYSQL_TYPE_STRING; m_param_bind[index].buffer = (char*)value.c_str(); m_param_bind[index].buffer_length = value.size(); /* m_param_bind[index].buffer_type = MYSQL_TYPE_LONG; m_param_bind[index].buffer = &value; */ mysql_stmt_bind_param(m_stmt, m_param_bind); mysql_stmt_excute(m_stmt); mysql_stmt_affected_rows(); / mysql_stmt_fetch_fields();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。