数据库编程——MySQL API

在学习数据库编程总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

09-数据库编程day04(mysql api)

 

一、学习目标

1.mysql的约束
2.mysql的中文乱码问题
3.通过api连接mysql实现增删改查
4.了解mysql预处理api的思想和实现流程
5.mysql通过API开启事务

 

二、复习

1、Oracle

》oracle常用的数据类型?
○ number
○ varchar2
○ date
》oracle有哪些约束?
○ check
○ unique
○ 非空
○ 主键
○ 外键

》建表注意事项?
○ 第一个必须是字母
○ 表名不能超过30长度
○ 表空间+权限

--建一个表
create table t1(id number(10,2),name varchar2(30),hiredate date default sysdate);

--哪个对象的作用是简化复杂查询以及隔离数据访问? 视图,同义词

--如何避免主键冲突? 使用序列,currval,nextval

--如何提高查询效率? 创建索引,创建一个索引表
create index indexname on tablename(columnname);

--怎么批量创建同义词?
select * from tab;
create synonym syname for username.tablename;

--使用tab字典生成创建语句
select 'create synonym '||tname||' for scott.'||tname||';' from tab;


2、MySQL

》Mysql安装所需要的包哪几个?
client,server,develop

》Mysql的组织结构?
root(用户)--> 库(scott)--》表

mysql库的操作
mysql表的操作
mysql数据的操作
○mysql 的group by语法检查不严格

》mysql多表查询
○ 内连接  inner join
○ 外连接
▪ 左外 left outer join
▪ 右外 right outer join
口诀:1)--> (left|right)join 2)where -> on

 

三、MySQL剩余问题

1、MySQL相关约束

》约束的种类:
○ 主键
○ 外键
○ 非空
○ 唯一
create table myclass (
id INT(11) primary key auto_increment, (MySQL增加功能:auto_increment主键自动增长)
name varchar(20) unique,
hiredate timestamp
);

mysql> insert into myclass(name) values('yekai');
mysql> select * from myclass;

mysql> insert into myclass(name) values('fuhongxue');
mysql> insert into myclass(id,name) values(5,'luxiaojia');
mysql> select * from myclass;

mysql> insert into myclass(name) values('lixunhuan');

create table student (
id INT(11) primary key auto_increment,
name varchar(20) unique,
passwd varchar(15) not null,
classid INT(11),  
constraint stu_classid_FK foreign key(classid) references myclass(id)
);


mysql> insert into student(name,passwd,classid) values('xiaoming','123',1);
mysql> insert into student(name,passwd,classid) values('xiaoming','123',9); (name唯一,所以报错)
mysql> insert into student(name,passwd,classid) values('xiaohong','123',9);  (没有9班,所以报错)

mysql> insert into student(name,passwd,classid) values('xiaohong','123',6);
mysql> insert into student(name,passwd,classid) values('xiaohua',null,6); (密码不能为空,所以报错)

mysql> delete from myclass where id=1;(两个表创建了关联,所以删除报错)

 

2、中文乱码问题

》因素1: MySQL自身的设计

【实验步骤1】:
mysql> show variables like 'character%'; 查看所有应用的字符集

【实验步骤2】:
$ mysql -uroot -p123456 --default_character_set=gbk 指定字符集登录数据库
mysql> show variables like 'character%';
影响了与客户端相关联的 3处 (最外层)
在这种状态下执行use mydb2;
mysql> select * from employee;
查看输出,会出现乱码。


原来的三条数据,是以utf8的形式存储到数据库中,当使用gbk连接以后,数据库仍按照utf8的形式将数据返回,出错。

【实验步骤3】:
在该环境下插入带有中文的一行数据。
mysql> insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(10,'张三疯',1,'1983-09-21',15000,'2012-06-24','一个老牛');
ERROR 1366 (HY000): Incorrect string value: '\x80\xE4\xB8\xAA\xE8\x80...' for column 'resume' at row 1

字符集乱的话,报的错不可信!!!

 

》因素2:操作系统的语言集

linux操作系统 是一个 多用户的操作
[root@localhost ~]# cat /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
操作系统的菜单按照zh_CN显示,  文件存储按照utf8
linux操作系统语言环境 和 用户的配置的语言环境LANG 相互影响
[mysql01@localhost ~]$ echo $LANG
zh_CN.UTF-8

【实验步骤4】:
修改用户下的.bash_profile 中的LANG,屏蔽操作系统的LANG设置。再查数据库
mysql> select * from employee;


结论: 用户的LANG设置,影响了应用程序的语言环境,导致myql的语言环境发生了改变。
mysql> show variables like 'character%';
在此环境下,检索中文会出现乱码。

【实验步骤5】:在上述环境之下,向数据库中插入中文。
insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(5,'张三疯',1,'1987-05-21',15000,'2014-06-24','一个老牛');


数据能插入到数据库中,没 有 报 任 何 错 误!但显示不正确。

 

》因素3:文件存储格式

 

 


》适应开发环境:


 

 

四、MySQL API

1、通过api连接数据库

》依赖的文件
/usr/include/mysql/mysql.h
/usr/lib64/mysql/libmysqlclient.a
如何查找?

shell> locate mysql.h

shell> libmysqlclient.a

》开始编程:
首先要做的事登录到mysql,退出
mysql_init 初始化
mysql_real_connect 连接到数据库
mysql_close 关闭连接

》MYSQL *mysql_init(MYSQL *mysql)
成功返回MYSQL*指针,失败返回NULL
》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)
host主机ip (mysql为mysql_init返回的指针)
user用户名(数据库)
passwd  密码
db   要登录的库名
port 端口 默认填0
○ mysql 默认端口 3306
○ oracle 默认端口 1521
○ mongodb 默认端口 27017
unix_socket套接字,默认填NULL
client_flag客户端标志,一般填0
返回值:如果成功返回MYSQL* ,失败返回NULL

》关闭连接 void mysql_close(MYSQL *mysql) 传送mysql句柄

>touch 01_hello.c

>vi 01_hello.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"

#define _HOST_ "127.0.0.1"
#define _USER_ "root"  //数据库用户
#define _PASSWD_ "123"
#define _DBNAME_ "SCOTT"


int main()
{
    //1. init 
    MYSQL*mysql = mysql_init(NULL);
    if(mysql == NULL){
        printf("init err\n");
        exit(1);
    }
    //2. real_connect
    mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
    
    if(mysql == NULL){
        printf("connect err\n");
        exit(1);
    }
    printf("hello mysql!\n");
    //3. close
    mysql_close(mysql);
    return 0;
}

>gcc 01_hello.c -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
编译产生错误:

(dlopen打开一个动态库)

编译时持续报错,用man查看(gxx—使用了g++,所以添加-lstdc++;man dlclose—添加-ldl;man pthread_mutex_trylock—添加-lpthread;man clock_gettime—添加-lrt)
>gcc 01_hello.c -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -lstdc++ -ldl -lpthread -lrt

>./a.out (报错:connect err)

分析:问题出在mysql_real_connect函数,远程登录可以登录MySQL,证明前边4个参数没有问题,后边两个参数默认,也不会有问题,分析可知,第5个参数出现问题(库名大写了,应该为小写,改为scott)。更改后再次gcc编译,运行:

 

2、通过api增加数据

--连接后执行一次插入操作

》sql执行函数
int mysql_query(MYSQL *mysql, const char *query)
○ mysql连接句柄
○ query是一个sql
返回值:成功返回0,错误非0值

》练习:

(打开另一个终端,登录MySQL后执行mysql>select * from dept;)

回原终端:

>touch 02_insert.c

>vi 02_insert.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"

#define _HOST_ "127.0.0.1"
#define _USER_ "root"  //数据库用户
#define _PASSWD_ "123"
#define _DBNAME_ "scott"


int main()
{
    //1. init 
    MYSQL*mysql = mysql_init(NULL);
    if(mysql == NULL){
        printf("init err\n");
        exit(1);
    }
    //2. real_connect
    mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
    
    if(mysql == NULL){
        printf("connect err\n");
        exit(1);
    }
    printf("hello mysql!\n");
    char rSql[256]={0};
    strcpy(rSql,"insert into dept values(60,'60name','60loc')");
    if(mysql_query(mysql,rSql) != 0){
        printf("mysql_query err\n");
        exit(1);
    }
    //3. close
    mysql_close(mysql);
    return 0;
}

>touch makefile

>vi makefile

SrcFiles=$(wildcard *.c)
TargetFiles=$(patsubst %.c,%,$(SrcFiles))


IncPath=/usr/include/mysql
LibPath=/usr/lib64/mysql
PubLib=-lmysqlclient -lstdc++ -ldl -lpthread -lrt

all:$(TargetFiles)

%:%.c
    gcc -o $@ $^ -I$(IncPath) -L$(LibPath) $(PubLib)

clean:
    -rm -f $(TargetFiles)

>make -n(先找到all伪目标,然后向下找,执行%:%.c)

>make -n clean(执行删除)

>make

>./02_insert

(打开另一个终端,登录MySQL后执行mysql>select * from dept;)

 

3、通过api实现查询分析

》第三步:
实现查询select * from emp
○ 执行mysql_query
○ 显示结果集

》显示结果集的函数:
○MYSQL_RES *mysql_store_result(MYSQL *mysql)
▪ mysql 连接句柄
▪ 返回MYSQL_RES*结构指针

○ 调用mysql_free_result()释放结果集
▪ void mysql_free_result(MYSQL_RES *result)
▪ void mysql_free_result(MYSQL_RES *result)

○ 调用mysql_fetch_row()获取结果集行
▪ MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
▪ typedef char **MYSQL_ROW;

 

4、实现查询的功能

>touch 03_select.c

>vi 03_select.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"

#define _HOST_ "127.0.0.1"
#define _USER_ "root"  //数据库用户
#define _PASSWD_ "123"
#define _DBNAME_ "scott"


int main()
{
    //1. init 
    MYSQL*mysql = mysql_init(NULL);
    if(mysql == NULL){
        printf("init err\n");
        exit(1);
    }
    //2. real_connect
    mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
    
    if(mysql == NULL){
        printf("connect err\n");
        exit(1);
    }
    printf("hello mysql!\n");
    char rSql[256]={0};
    strcpy(rSql,"select * from emp");
    if(mysql_query(mysql,rSql) != 0){
        printf("mysql_query err\n");
        exit(1);
    }
    //取回结果集
    int i=0;
    MYSQL_RES * result = mysql_store_result(mysql);
    MYSQL_ROW row;
    if(result != NULL){
        //需要打印结果集
        while((row= mysql_fetch_row(result)) != NULL){//循环取一行
            for(i = 0;i< 8; i ++){
                printf("%s\t",row[i]);
            }
            printf("\n");
        } 
        //释放结果集
        mysql_free_result(result);
    }


    //3. close
    mysql_close(mysql);
    return 0;
}

>make

>./03_select

 

5、查询改进

 

6、客户端实现

 

7、字符集的问题

 

8、字符集问题处理

 

9、预处理的流程

 

10、预处理的内存映射

 

11、MySQL通过api处理事务

 

 

五、monogodb数据库

1、monogodb数据库的安装

wget  http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.10.tgz
》ubuntu安装
sudo apt-get install mongodb

 

2、monogodbc+驱动安装

》mongodb c++ 驱动安装:
○ 安装boost库准标准库
○ 安装PCRE c++的正则表达式的第三方库
○ scons 编译驱动
○ 编译驱动程序

编译testmongo.cpp

3、课后作业

 

 

 

 

在学习数据库编程总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值