1. 链接Mysql
#include <winsock.h>
#include "mysql.h"
#include <stdlib.h>
#include <string>
using std::cout;
using std::string;
int main()
{
string host("localhost");
string useName("root");
string passWord("");
string dbName("fmos");
int port = ;
//
MYSQL *pConn;
pConn = mysql_init(NULL);
//第2、3、4、5参数的意思分别是:服务器地址、用户名、密码、数据库名,第6个为mysql端口号(0为默认值3306)
//或者pConn=mysql_real_connect(....)
if (mysql_real_connect(pConn, host.c_str(), useName.c_str(), passWord.c_str(), dbName.c_str(), port, NULL, ) == NULL)
{
string error = std::string(mysql_error(pConn));//可以获取失败的原因,是char *型的。
cout<<"失败"<<endl;
}
else {
cout<<"成功"<<endl;
}
//凡是返回指针或者引用的函数,都要特别注意,因为通常要自己销毁,所以,mysql提供了销毁的函数
mysql_close(pConn);
return re;
}
2. mysql查询
void Query(MYSQL* connect)
{
char * sql = "select * from fmos_project;"
int ret=;
ret = mysql_query(connect,sql);//只要是sql语句就可以了
//不等于0表示失败,很奇怪
if(ret!=)
{
string error = string( mysql_error(connect));
return;
}
//mysql_use_result来获取记录,查询结果是暂时存在服务器的
//mysql_store_result是一次性查到本地,其他没有区别
MYSQL_RES* result = mysql_store_result(connect);
if(result==NULL)
{
string error = string( mysql_error(connect));
return; }
MYSQL_ROW row;// MYSQL_ROW的原型是一个char**。char * a ,a能指向一堆char;而char** aa,aa能指向一堆char*。
while( row = mysql_fetch_row(result))//一行行获取数据 , if和while都是判断()内是否非0
{
unsigned int columnCount = mysql_field_count(connect);//result->field_count;这个是什么?
for (int i = ; i < columnCount; i++) {
std::cout << row[i] << " ";//row[i]实际上是char*类型
}
std::cout << std::endl; }
mysql_free_result(result);//不要忘记释放指针。
}
为什么要用二级指针char**,因为返回的是一个表,实际上,应该是这样:
每一行,"id1" "a1" "b1" 。每一个属性值是char*,所以一整行是char**
3. 获取列数
void getFiled(MYSQL* connect, MYSQL_RES* result) { unsigned int c = mysql_field_count(connect);//从句柄中获取多少列 unsigned int cr = mysql_num_fields(result);//从查询结果中获取多少列,如果查询结果为空,就没有了 }
4. 获取表头
void getFiled(MYSQL_RES* result) { unsigned int num_fields=mysql_num_fields(result); MYSQL_FIELD *fields = mysql_fetch_fields(result); //MYSQL_FIELD 这是一个结构体,指向结构体的指针fields,也可以认为是指向结构体数组首地址的指针。
for(unsigned int i=;i<num_fields;i++) { std::cout<<fields[i].name; } }
5. 预处理API函数
第一步: 告诉mysql服务器,有一条sql语句要执行;第二步:发送参数
好处:如果一条语句是经常使用的,如果提前将SQL写好,运行时只要发参数,能加快速度。
1. 使用msql_stmt_init();准备好环境,有点像准备好MYSQL*
2. 使用mysql_stmt_prepare()放语句
3. 使用mysql_stmt_bind_param();添加参数
3. 使用mysql_stmt_start();执行语句
#define INSERT_SQL “INSERT INTO text_table(col1,col2,col3) VALUES(?,?,?)” int main() { MYSQL *mysql = mysql_init(NULL); char * error; int ret=; if(mysql==NULL) { error = mysql_error(mysql); return ; } mysql = mysql_read_connect(mysql,"localhost","root","","mydb",,NULL,); if(mysql==NULL) { error = mysql_error(mysql); return ; } //1. 初始化一个预处理环境句柄 MYSQL_STMT *stmt=mysql_stmt_init(mysql);//MYSQL_STMT是一个结构体 if(!stmt)//stmt首先转换为bool,不等于0为true,再!运算 { return; } //2. 准备好语句。 注意这里,执行结果返回非0,就是失败;返回0才是成功。 这句只执行一次就够了。
if(mysql_stmt_prepare(stmt,INSERT_SQL ,strlen(INSERT_SQL))) { error = msql_stmt_error(stmt); return; } // 准备好参数 MYSQL_BIND bind=new MYSQL_BIND[]; //MYSQL_BIND的成员时指针类型的,因为 值要指向字符串的时候,只能指针了
//int 的列 int value = ; bind[].buffer_type=MYSQL_TYPE_LONG; bind[].buffer = (char*)&value;//char*转换也能代表内存首地址 bind[].is_null = ; bind[].lenght = ;//不是字符串就写为0,就是空指针 //string的列 char *str_data = "aaaaa"; int sting_size = ; bool isnull = false;
bind[].buffer_type = MYSQL_STYPE_STRING; bind[].buffer =(char*)str_data; bind[].is_null = &isnull; //这个也是指针 bind[].lenght = &sting_size ;//长度也是指针
// time列
MYSQL_TIME ts;
ts.year = 1991;
ts.mouth = 12;
ts.day = 14;
ts.hour = 18;
ts.minute = 45;
ts.second = 20;
bind[].buffer_type = MYSQL_STYPE_DATE; bind[].buffer =(char*)&ts; bind[].is_null = 0; //同理,非字符串也填0就可以了 bind[].lenght = 0 ;//同理,非字符串也填0就可以了 //3. 放参数 if(mysql_stmt_bind_param(stmt,bind)) { error = msql_stmt_error(stmt); return; } //4. 执行 if(mysql_stmt_execute(stmt)) { error = msql_stmt_error(stmt); return; } delete[] bind; //检查执行结果 affected_rows = mysql_stmt_affected_rows(stmt); if(!affected_rows) { error="执行失败";
} mysql_close(myql); }
6. mysql事务
void tran()
{
}