数据库编程:就是在我们的应用程序中,用代码来与数据库服务器交互。SQLyog就是一个基于数据库的应用程序,它里面就用到了数据库编程的技术。
理论上,应用程序使用以下方式可以与MySQL交互:1. 创建TCP socket。2. 根据MySQL的协议,与之交互。
上述操作对于大多数来说太难了,所以,MySQL提供了一套库,程序员只需要调用这个库里的少数的几个函数,就能够与MySQL交互。这套库就称为API(Application Programming Interface)应用程序编程接口。应用程序调用API里的函数,由API内部与MySQL交互。
本文选择C的API作为介绍,C API 5.5版本,请参考官网:http://www.mysql.com。
注意:"libmys.dll文件要放在当前工程的目录下,最好和.exe文件放一起。
在项目里使用MYSQL的API的方法如下:
#include
#include
// MySQL support on Windows
#include
#include
#pragma comment(lib, "libmysql")
int main(void)
{
if (mysql_library_init(0, NULL, NULL))
{
printf("could not initialize MySQL library\n");
return -1;
}
//在这里写需要操作的代码
……
mysql_library_end();
return 0;
}
一、初始化和关闭
在使用API中的其他函数之前,需要先初始化。通常在程序启动时初始化(main函数开始处)
mysql_library_init
程序退出之前(但由于程序即将退出,所以不调用也没关系)
mysql_library_end
二、连接服务器
MYSQL:采用面向对象的设计,每个对象对应一个MySQL连接。
MYSQL conn; //创建对象conn
mysql_init (&conn); //初始化对象
mysql_real_connect (&conn, …);//进行链接
MYSQL* ret = mysql_real_connect(&conn,"127.0.0.1","root","123456","example",0,NULL,0);
// 指定IP/用户名/密码等参数,连接服务器
if (!ret) //检查返回值,链接不成功时报错
{
printf("Failed to connect to database: %s\n",
mysql_error(&conn));
}
mysql_xxx (…) 相关业务操作
mysql_close (&conn); 关闭连接
三、INSERT插入操作
mysql_query 执行SQL语句,直接把SQL语句传给服务器
mysql_affected_rows 受影响的行数
Eg:
int my_insert(MYSQL* conn)
{
// SQL语句的末尾不要加分号!
const char* sql =
" INSERT INTO `student` "
" (`id`, `name`, `birthday`, `cellphone`) "
" VALUES "
"('17', 'qian22', '1992-12-2', '18601088987')"
;
int ret = mysql_query(conn, sql);//第一个是对象的指针,第二个是SQL语句,把SQL语句传递给服务器
if(ret != 0) //检查返回值
{
printf("error: %s \n", mysql_error(conn));
return -1;
}
my_ulonglong affected_rows = mysql_affected_rows(conn); // 查找受影响的函数
printf("%d rows affected. \n", (int) affected_rows); //把结果转化为int型
}
例 3.1.4 让用户可以自行输入自己的信息,修改上述代码。
#include
#include
// MySQL support on Windows
#include
#include
#pragma comment(lib, "libmysql")
struct Student
{
int id;
char name[32];
char birthday[16];
char cellphone[12];
};
int do_insert(Student* stu)
{
MYSQL conn;
mysql_init(&conn);
// 连接服务器
if (NULL == mysql_real_connect(&conn,
"127.0.0.1","root","123456","example"
,0,NULL,0))
{
printf("Failed to connect to database: %s\n",
mysql_error(&conn));
return -1;
}
// 构造SQL语句
char sql[256]; //定义缓冲区
sprintf(sql, //sprintf来构造一个SQL语句,首先传入缓冲区地址
" INSERT INTO `student` "
" (`id`, `name`, `birthday`, `cellphone`) "
" VALUES "
"('%d', '%s', '%s', '%s')"
,stu->id
,stu->name
,stu->birthday
,stu->cellphone
);
// 执行SQL语句
int ret = mysql_query(&conn, sql);
if(ret != 0)
{
printf("error: %s \n", mysql_error(&conn));
}
else
{
my_ulonglong affected_rows = mysql_affected_rows(&conn); // a 64-bit large number
printf("%d rows affected. \n", (int) affected_rows); // cast to int
}
// 关闭连接
mysql_close(&conn);
}
int main()
{
if (mysql_library_init(0, NULL, NULL))
{
printf("could not initialize MySQL library\n");
return -1;
}
// 获取用户输入
Student stu;
printf("ID: ");
char buf[128];
gets(buf);
stu.id = atoi(buf);
printf("Name: ");
gets(stu.name);
printf("Birthday: ");
gets(stu.birthday);
printf("CellPhone: ");
gets(stu.cellphone);
// 插入数据库
do_insert(&stu);
mysql_library_end();
return 0;
}
长连接:执行完操作之后,不关闭连接,等下次继续用。
短连接:每次执行完操作之后,立即关闭连接。若下次需要,则创建新的连接。
推荐使用短连接,不要长期占着一个连接。
四、SELECT查询操作
查询操作有2个返回值,需要了解一下:
1. 成功or失败
2. 如果成功,则返回一个ResultSet(即符合条件的行)
整体结构如下:
const char* sql = … 拼凑SQL语句
mysql_query(&conn, sql) 执行SQL语句
// 保存结果
MYSQL_RES * result = mysql_store_result(conn);//返回一个指针
if ( result )
{
… 处理每一行数据…
mysql_free_result(result) ; // 释放内存
}
//从结果集中取出每一行的数据
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)))
{
unsigned long *lengths = mysql_fetch_lengths(result);
for(int i = 0; i < num_fields; i++)
{
char* field = row[i]; // 字段
unsigned int field_length = lengths[i]; // 字段长度
}
}
MySQL返回来的值都是字符串类型,需要还原每个字段。
1. tinyint, samllint, mediumint, int
调用AfMysql::AsInt()
2. bitint
调用AfMysql::AsBigInt()
3. char, varchar, text
调用AfMysql::AsString(),以std::string保存
4. date, time, datetime
调用AfMysql::AsDate(), AsTime()或AsDateTime()
注意:下面取数据的操作具有更好的交互性。
1. mysql_use_result: 初始化操作
2. mysql_fetch_row: 从服务器获取一行