一、初识与mysql相关的部分数据类型和api
1.1) MYSQL:该结构代表一个数据库的连接句柄,一般我们都不去复制它
MYSQL_RES:查询返回的结果集
MYSQL_ROW:一行数据的表示,通过调用mysql_fetch_row()获得的。
MYSQL_FIELD:该结构包含字段信息,如字段名、类型和大小等。字段指不包含在这一结构中,其值位于MYSQL_ROW结构中。
1.2) 部分api
1)
MYSQL *mysql_init(MYSQL *mysql)
描述
分配或初始化与mysql_real_connect()相适应的MYSQL对象。如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时。将释放该对象。
返回值
初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL。
2)
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数据库建立连接。必须在mysql_init调用成功之后才可以调用该函数。
参数解析:
mysql:mysql_init成功返回的句柄
host:主机名或者ip地址,该参数为NULL或者"localhost"表示本机。
user:db用户名
passwd:db密码
db:要访问的db名字,如果db为NULL,连接会将默认的数据库设为该值
port:若“port”不是0,其值将用作TCP/IP连接的端口号。注意,“host”参数决定了连接的类型。
client_flag:通常为0
unix_socket: 可以取NULL,该字符串描述了应使用的套接字或命名管道
3)
int mysql_query(MYSQL *mysql, const char *q)
描述
执行由“Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含多条由分号隔开的语句,参数q为sql语句。返回值,0-成功,非0-失败。
4)
int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)
描述
执行由“query”指向的SQL查询,它应是字符串长度字节“long”。对于包含二进制数据的查询,必须使用mysql_real_query()而不是mysql_query(),这是因为,二进制数据可能会包含‘\0’字符。此外,mysql_real_query()比mysql_query()快,这是因为它不会在查询字符串上调用strlen()。
5)
MYSQL_RES *mysql_store_result(MYSQL *mysql)
描述
对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),调用mysql_store_result()获取结果集,如果查询未返回结果集或读取失败,mysql_store_result()将返回Null指针。
6)
my_ulonglong mysql_affected_rows(MYSQL *mysql)
描述
返回受影响的行数
7)
unsigned int mysql_field_count(MYSQL *mysql)
描述
返回作用在连接上的最近查询的列数。
8)
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)
描述
对于结果集,返回所有MYSQL_FIELD结构的数组。每个结构提供了结果集中1列的字段定义。
返回值
关于结果集所有列的MYSQL_FIELD结构的数组。
9)
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
描述
检索结果集的下一行。在mysql_store_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。通过检查字段值的指针,能够区分它们。
返回值
下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。
10)
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的语句)。
没有实际的代码,终归是纸上谈兵,也不能加深我们的理解,下边请看代码实例。
// ------------------databasemysql.h
#ifndef DATABASEMYSQL
#define DATABASEMYSQL
#include
#include
using std::string;
class DataseMysql
{
public:
struct DatabaseInfo
{
string strHost;
string strUser;
string strPwd;
string strDBName;
};
public:
DataseMysql();
~DataseMysql();
bool Init(MYSQL* mysql, const string& host, const string& user, const string& passwd, const string& database);
bool QuerySql(const char* sql);
private:
// 句柄
MYSQL * m_pMysql;
// 结果集
MYSQL_RES* m_pMysqlRes;
// 行
MYSQL_ROW m_row;
// field
MYSQL_FIELD * m_pMysqlField;
bool m_bInit;
};
#endif // DATABASEMYSQL
// ------------------databasemysql.cpp
#include "databasemysql.h"
#include
#include
using namespace std;
DataseMysql::DataseMysql(void)
{
m_bInit = false;
m_pMysql = NULL;
m_pMysqlRes = NULL;
m_pMysqlField = NULL;
}
DataseMysql::~DataseMysql(void)
{
if (m_pMysql != NULL)
{
if (m_bInit)
{
mysql_close(m_pMysql);
}
}
}
bool DataseMysql::Init(MYSQL *mysql, const string &host, const string &user, const string &passwd, const string &database)
{
if (m_bInit)
{
mysql_close(m_pMysql);
}
m_pMysql = mysql_init(mysql);
if (!m_pMysql)
{
cout << "mysql init failed." << endl;
return false;
}
MYSQL* pMysql = NULL;
pMysql = mysql_real_connect(m_pMysql, host.c_str(), user.c_str(), passwd.c_str(), database.c_str(), 0, NULL, 0);
if (pMysql == m_pMysql)
{
cout << "connect succeed." << endl;
mysql_query(pMysql, "set names utf8");
return true;
}
else
{
cout << "failed: " << ", error: " << mysql_error(m_pMysql) << endl;
return false;
}
}
bool DataseMysql::QuerySql(const char *sql)
{
int ret = 0;
int len = strlen(sql);
ret = mysql_real_query(m_pMysql, sql, len);
if (ret)
{
cout << "DataseMysql::QuerySql failed." << endl;
return false;
}
m_pMysqlRes = mysql_store_result(m_pMysql);
if (!m_pMysqlRes)
{
cout << "m_pMysqlRes is null." << endl;
return false;
}
my_ulonglong rowCount = 0;
unsigned int fieldCount = 0;
rowCount = mysql_affected_rows(m_pMysql);
fieldCount = mysql_field_count(m_pMysql);
// 遍历结果集里的情况.
m_row = mysql_fetch_row(m_pMysqlRes);
while (m_row)
{
for (int i = 0; i < fieldCount; ++i)
{
cout << m_row[i] << "\t\t";
}
cout << endl;
m_row = mysql_fetch_row(m_pMysqlRes);
}
mysql_free_result(m_pMysqlRes);
}
// ------------------main.cpp
#include
#include "databasemysql.h"
using namespace std;
int main()
{
DataseMysql mysqlObj;
if (!mysqlObj.Init(NULL, "localhost", "root", "root", "test"))
{
return -1;
}
//mysqlObj.QuerySql("select * from test");
mysqlObj.QuerySql("show databases");
cout << "Hello World!" << endl;
return 0;
}
# ------------------CMakeLists.txt
project(testMysql)
cmake_minimum_required(VERSION 2.8)
#set(CMAKE_BUILD_TYPE DEBUG)
find_library(MYSQL_LIB libmysqlclient.so /usr/lib/)
if (NOT MYSQL_LIB)
message(FATAL_ERROR "mysqlclient not found")
else (MYSQL_LIB)
message("find")
endif(NOT MYSQL_LIB)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} mysqlclient)
输出结果如下:
connect succeed.
information_schema
myim
mysql
performance_schema
sanilblog
sys
test
Hello World!
这就是初识Linux c++调用mysql,由于时间关系,暂时这样了,后续有时间再进行完善。