c++操作数据库(CRUD)

c++操作数据库

1. 添加mysql动态链接库到环境变量LD_LIBRARY_PATH

1.1 查看mysql的头文件以及动态链接库目录

在这里插入图片描述

whereis mysql 

首先使用 命令找到mysql相关目录,然后查看各个目录内容,即可找到mysql的头文件目录和动态链接库目录

1.2 修改环境变量LD_LIBRARY_PATH

LD_LIBRARY_PATH 是主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径。

env|grep LD_LIBRARY_PATH

使用命令查看LD_LIBRARY_PATH的内容

vim ~/.bashrc

使用命令查看配置文件内容,在export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:后添加mysql头文件和动态库目录
在这里插入图片描述

2. 配置框架以及编写makefile文件

2.1 导入框架的_mysql.cpp和_mysql.h的操作数据库的文件

在这里插入图片描述

2.2 编写makefile

# mysql头文件存放的目录
MYSQLINCL = -I/usr/include/mysql

# mysql库文件存放的目录
MYSQLLIB = -L/usr/lib64/mysql

# 需要连接的mysql库
MYSQLLIBS = -lmysqlclient

CFLAGS = -g -Wno-write-strings

all:createtable

createtable:createtable.cpp _mysql.h _mysql.cpp
        g++ $(CFLAGS) -o createtable createtable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

clean:
        rm -rf createtable

3 插入表操作

函数流程:
1.首先创建数据库连接类

connection conn; 

2.调用函数链接数据库

conn.connecttodb("192.168.117.128,root,chenliang123789,testDatabase,3306", "utf8")

参数分别为:目标主机ip,用户名,密码,数据库名,端口,编码方式
3.创建sql语句操作对象

sqlstatement stmt(&conn);

4.编写sql语句

sqlstatement stmt(&conn); // 操作SQL语句对象
  // 准备超女表, 编号id,姓名name,体重weight,报名时间btime,说明memo,图片pic
    stmt.prepare("create table girls(id      bigint(10),\
                   name    varchar(30),\
                   weight  decimal(8,2),\
                   btime   datetime,\
                   memo    longtext,\
                   pic     longblob,\
                   primary key (id))");

5.执行sql语句

stmt.execute();

最终代码:

/*
  程序名:createtable.cpp 此程序演示开发矿框架操作MySQL数据库(创建表)
*/

#include "_mysql.h" // 开发框架操作MySQL的头文件

int main(int argc, char* argv[]){

  connection conn;  // 数据库连接类

  // 登录数据库,返回值:0-成功,其他为失败,存放了MySQL的错误代码
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中
  if(conn.connecttodb("192.168.117.128,root,chenliang123789,testDatabase,3306", "utf8") != 0){
    printf("connect database failed.\n %s \n", conn.m_cda.message);
        return -1;
  }
  // printf("连接成功!\n");

  sqlstatement stmt(&conn); // 操作SQL语句对象
  // 准备超女表, 编号id,姓名name,体重weight,报名时间btime,说明memo,图片pic
    stmt.prepare("create table girls(id      bigint(10),\
                   name    varchar(30),\
                   weight  decimal(8,2),\
                   btime   datetime,\
                   memo    longtext,\
                   pic     longblob,\
                   primary key (id))");
  // 执行SQL语句,判断返回值,0-成功,其他失败
  // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中
  if(stmt.execute()!=0){
    printf("stmt.extcute() failed.\n %s \n %d \n %s\n",stmt.m_sql,stmt.m_cda.rc,stmt.m_cda.message);
        return -1;
  }

  return 0;
}

4. 向表中插入数据

1 定义超女信息的结构,与表中字段对应

  struct st_girls{
  
    long id;         // 超女编号
	char name[31];   // 姓名
	double weighr;   // 体重
	char btime[20];  // 报名时间
  }

2 编写sql语句

  stmt.prepare("\
	insert into table girls(id, name, weight, btime)values(:1, :2, :3, str_to_date(:4, '%%Y-%%m-%%d %%H:%%i:%%s'))");

注意:
1)第四个参数在转换输出格式为日期格式,在此函数中%需要转义故写成%%

2)SQL语句的参数序号从1开始,连续,递增,参数也可以用?表示,但是?的兼容性不太好

 stmt.prepare("\
	insert into table girls(id, name, weight, btime)values(?, ?, ?, str_to_date(?, '%%Y-%%m-%%d %%H:%%i:%%s'))");

3)SQL语句中,右值才可以作为参数,表名,字段名,关键字,函数名等都不能作为参数

4)参数可以参与运算

 stmt.prepare("\
	insert into table girls(id, name, weight, btime)values(:1+1, :2, :3+45.25, str_to_date(:4, '%%Y-%%m-%%d %%H:%%i:%%s'))");

5)如果SQL语句主体没有改变,只需要prepare()一次即可

3.绑定sql语句中的变量

  stmt.bindin(1, &stgirls.id);
  stmt.bindin(2, stgirls.name, 30);
  stmt.bindin(3, &stgirls.weight);
  stmt.bindin(4, stgirls.btime, 19);

注意:绑定第二和四个参数时,函数的第三个参数为字符串长度,由于c语言中字符串末尾存在/0,故此参数比结构体中字符串的长度少1

  1. 向表中插入5条测试数据
  // 模拟超女信息,向表中插入5条测试数据
  for(int i = 0 ; i < 5 ; i++){
	memset(&stgirls, 0, sizeof(st_girls));
      
    // 为结构体变量的成员赋值
    stgirls.id = i+1; //超女编号 
    sprintf(stgirls.name, "西施%05dgirl", i+1); //姓名
    stgirls.weight = 45.25+i; //体重
    sprintf(stgirls.btime, "2022-10-31 10:33:%02d", i); // 报名时间

    if(stmt.execute() != 0){
	  printf("stmt.execute() failed.\n%s\n%s\n", stmt.m_sql,stmt.m_cda.message);
	  return -1;
	}	
	printf("成功插入了%ld条记录\n", stmt.m_cda.rpc);// stmt.m_cda.rpc中存放了SQL执行影响的记录数
  }

5 提交数据库事务

conn.commit();// 提交数据库事务

最终代码:

/*
  程序名:inserttable.cpp 此程序演示开发框架操作MySQL数据库(向表中插入数据)
*/

#include "_mysql.h" // 开发框架操作MySQL的头文件

int main(int argc, char* argv[]){

  connection conn;  // 数据库连接类
  
  // 登录数据库,返回值:0-成功,其他为失败,存放了MySQL的错误代码
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中
  if(conn.connecttodb("192.168.117.128,root,chenliang123789,testDatabase,3306", "utf8") != 0){
    printf("connect database failed.\n %s \n", conn.m_cda.message);
	return -1;
  }
  // printf("连接成功!\n");
  
  // 定义超女信息的结构,与表中字段对应
  struct st_girls{
  
    long id;         // 超女编号
	char name[31];   // 姓名
	double weight;   // 体重
	char btime[20];  // 报名时间
  }stgirls;
  
  sqlstatement stmt(&conn); // 操作SQL语句对象
  
  stmt.prepare("\
	insert into table girls(id, name, weight, btime)values(:1, :2, :3, str_to_date(:4, '%%Y-%%m-%%d %%H:%%i:%%s'))");
	
  stmt.bindin(1, &stgirls.id);
  stmt.bindin(2, stgirls.name, 30);
  stmt.bindin(3, &stgirls.weight);
  stmt.bindin(4, stgirls.btime, 19);
  
  // 模拟超女信息,向表中插入5条测试数据
  for(int i = 0 ; i < 5 ; i++){
	memset(&stgirls, 0, sizeof(st_girls));
      
    // 为结构体变量的成员赋值
    stgirls.id = i+1; //超女编号 
    sprintf(stgirls.name, "西施%05dgirl", i+1); //姓名
    stgirls.weight = 45.25+i; //体重
    sprintf(stgirls.btime, "2022-10-31 10:33:%02d", i); // 报名时间

    if(stmt.execute() != 0){
	  printf("stmt.execute() failed.\n%s\n%s\n", stmt.m_sql,stmt.m_cda.message);
	  return -1;
	}	
	printf("成功插入了%ld条记录\n", stmt.m_cda.rpc);// stmt.m_cda.rpc中存放了SQL执行影响的记录数
  }
  printf("insert table girls ok\n");
  
  conn.commit();// 提交数据库事务

  return 0;
}

6.修改makefile文件增加编译指令

# mysql头文件存放的目录
MYSQLINCL = -I/usr/include/mysql

# mysql库文件存放的目录
MYSQLLIB = -L/usr/lib64/mysql

# 需要连接的mysql库
MYSQLLIBS = -lmysqlclient

CFLAGS = -g -Wno-write-strings

all:createtable inserttable

createtable:createtable.cpp _mysql.h _mysql.cpp
	g++ $(CFLAGS) -o createtable createtable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc
inserttable:inserttable.cpp _mysql.h _mysql.cpp
	g++ $(CFLAGS) -o inserttable inserttable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

clean:
	rm -rf createtable inserttable

注意:
报错:Incorrect string value: ‘\xE8\xA5\xBF\xE6\x96\xBD…’ for column ‘name’ at row 1
需要修改字符集
方式1:

alter table girls character set utf8;

方式2:

alter table girls change name name varchar(50) character set utf8;

在这里插入图片描述

5.修改表中数据

  1. 修改SQL语句
    stmt.prepare("\
	update girls set name = :1, weight = :2, btime=str_to_date(:3, '%%Y-%%m-%%d %%H:%%i:%%s') where id=:4");

2.绑定参数

  stmt.bindin(1, stgirls.name, 30);
  stmt.bindin(2, &stgirls.weight);
  stmt.bindin(3, stgirls.btime, 19);
  stmt.bindin(4, &stgirls.id);

注意参数顺序

3.执行SQL

// 模拟超女信息,修改表中数据
  for(int i = 0 ; i < 5 ; i++){
	memset(&stgirls, 0, sizeof(st_girls));
      
    // 为结构体变量的成员赋值
    stgirls.id = i+1; //超女编号 
    sprintf(stgirls.name, "貂蝉%05dgirl", i+1); //姓名
    stgirls.weight = 55.25+i; //体重
    sprintf(stgirls.btime, "2021-10-31 10:33:%02d", i); // 报名时间

    if(stmt.execute() != 0){
	  printf("stmt.execute() failed.\n%s\n%s\n", stmt.m_sql,stmt.m_cda.message);
	  return -1;
	}	
	printf("成功修改了%ld条记录\n", stmt.m_cda.rpc);// stmt.m_cda.rpc中存放了SQL执行影响的记录数
  }
  printf("insert table girls ok\n");
  
  conn.commit();// 提交数据库事务

在这里插入图片描述

4.示例:使用不传递参数的方法
功能:修改id为2和3的记录

stmt.prepare("update girls set name = '冰冰', weight = 45, btime=now() where id in (2,3)");
stmt.execute();
conn.commit();

6. 查询表

  1. 构建SQL语句
  stmt.prepare("\
  select id, name, weight, date_format(btime, '%%Y-%%m-%%d %%H:%%i:%%s' from girls where id in (2,3,4))");

注意:
1)结果集中的字段,调用bindout()绑定变量的地址
2) bindout()方法的返回值固定为0
3) 调用execute()方法执行SQL语句,然后再循环调用next()方法获取结果集中的记录
4) 每调用一次next()方法,从结果集中获取一条记录,字段内容保存在已绑定的变量中

  1. 绑定结果集与变量的地址
  stmt.bindout(1, &stgirls.id);
  stmt.bindout(2, stgirls.name, 30);
  stmt.bindout(3, &stgirls.weight);
  stmt.bindout(4, stgirls.btime, 19);

3.执行SQL语句,通过next()方法从结果集中获得数据

// 执行SQL语句,一定要判断返回值,0-成功,其他-失败
  if(stmt.execute() != 0){
    printf("stmt.execute() failed.\n%s\n%s\n", stmt.m_sql, stmt.m_cda.message);
	return -1;
  }
  
  //本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集
  while(true){
    memset(&stgirls, 0, sizeof(st_girls));
	
	//从结果集中获取一条记录,判断返回值,0-成功,1403-无记录,其他-失败
	if(stmt.next() != 0) break;
	
	// 把获取到的记录的值打印出来
	printf("id=%ld,name=%s,weight=%.02f,btime=%s\n",stgirls.id,stgirls.name,stgirls.weight,stgirls.btime);
  }
  
  // stmt.m_cda.rpc中保存了SQL执行后被影响的记录数
  printf("本次查询了girls表%ld条记录\n",stmt.m_cda.rpc);

4.编写makefile增加编译指令在这里插入图片描述

7.删除表中记录

1.编写SQL语句,绑定变量
2.执行SQL语句

/*
  程序名:deletetable.cpp 此程序演示开发矿框架操作MySQL数据库(删除表中的记录)
*/

#include "_mysql.h" // 开发框架操作MySQL的头文件

int main(int argc, char* argv[]){

  connection conn;  // 数据库连接类
  
  // 登录数据库,返回值:0-成功,其他为失败,存放了MySQL的错误代码
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中
  if(conn.connecttodb("192.168.117.128,root,chenliang123789,testDatabase,3306", "utf8") != 0){
    printf("connect database failed.\n %s \n", conn.m_cda.message);
	return -1;
  }
  // printf("连接成功!\n");
  
  int iminid; // 指定待删除记录的最小id的值
  int imaxid; // 指定待删除记录的最大id的值
  
  sqlstatement stmt(&conn); // 操作SQL语句对象
  // 准备超女表, 编号id,姓名name,体重weight,报名时间btime,说明memo,图片pic
  stmt.prepare("\
  delete from girls where id>=:1 and id<=:2");
  
  stmt.bindin(1, &iminid);
  stmt.bindin(2, &imaxid);
  
  iminid = 1; // 指定待删除记录的最小id的值
  imaxid = 2; // 指定待删除记录的最小id的值
	
  
  // 执行SQL语句,一定要判断返回值,0-成功,其他-失败
  if(stmt.execute() != 0){
    printf("stmt.execute() failed.\n%s\n%s\n", stmt.m_sql, stmt.m_cda.message);
	return -1;
  }
  
  // stmt.m_cda.rpc中保存了SQL执行后被影响的记录数
  printf("本次查询了girls表%ld条记录\n",stmt.m_cda.rpc);
  
  conn.commit(); // 提交数据库事务
  
  
  return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值