• 数据库编程——MySQL API


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

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

    目录:
    一、学习目标
    二、复习
    1、Oracle
    2、MySQL
    三、MySQL剩余问题
    1、MySQL相关约束
    2、中文乱码问题
    四、MySQL API
    1、通过api连接数据库
    2、通过api增加数据
    3、通过api实现查询分析
    4、实现查询的功能
    5、查询改进
    6、客户端实现
    7、字符集的问题
    8、字符集问题处理
    9、预处理的流程
    10、预处理的内存映射
    11、MySQL通过api处理事务
    12、课后作业
    五、monogodb数据库
    1、monogodb数据库的安装
    2、monogodbc+驱动安装

    一、学习目标

    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)    
    );

    定义外键约束,名字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: 'x80xE4xB8xAAxE8x80...' 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
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        printf("hello mysql!
    ");
        //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
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        printf("hello mysql!
    ");
        char rSql[256]={0};
        strcpy(rSql,"insert into dept values(60,'60name','60loc')");
        if(mysql_query(mysql,rSql) != 0){
            printf("mysql_query err
    ");
            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
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        printf("hello mysql!
    ");
        char rSql[256]={0};
        strcpy(rSql,"select * from emp");
        if(mysql_query(mysql,rSql) != 0){
            printf("mysql_query err
    ");
            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	",row[i]);
                }
                printf("
    ");
            } 
            //释放结果集
            mysql_free_result(result);
        }
    
    
        //3. close
        mysql_close(mysql);
        return 0;
    }

    >make

    >./03_select

    5、查询改进

    >touch 04_select.c

    >vi 04_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"
    
    
    void show_result(MYSQL_RES * result)
    {
        //打印表头
        unsigned int num_fields;
        unsigned int i;
        MYSQL_FIELD *fields;
         
        num_fields = mysql_num_fields(result);
        fields = mysql_fetch_fields(result);
        for(i = 0; i < num_fields; i++)
        {
           printf("%s	", fields[i].name);
        }
        printf("
    +-------+--------+-----------+------+------------+------+------+--------+
    ");
        
        
        MYSQL_ROW row;
        num_fields = mysql_num_fields(result);//取字段个数
        while ((row = mysql_fetch_row(result)))//循环取一行
        {
           for(i = 0; i < num_fields; i++)
           {
               printf("%s	",  row[i] ? row[i] : "NULL");
           }
           printf("
    ");
        }
    }
    int main()
    {
        //1. init 
        MYSQL*mysql = mysql_init(NULL);
        if(mysql == NULL){
            printf("init err
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        printf("hello mysql!
    ");
        char rSql[256]={0};
        strcpy(rSql,"select * from emp");
        if(mysql_query(mysql,rSql) != 0){
            printf("mysql_query err
    ");
            exit(1);
        }
        //取回结果集
        int i=0;
        MYSQL_RES * result = mysql_store_result(mysql);
        MYSQL_ROW row;
        if(result != NULL){
            //需要打印结果集
            show_result(result);
            mysql_free_result(result);//释放结果集
        }
    
    
        //3. close
        mysql_close(mysql);
        return 0;
    }

    >make

    >./04_select

    6、客户端实现

    》实现客户端:
    ○ 初始化
    ○ 连接
    ○ 循环等待sql输入
    ○ 执行sql
      ▪ 如果有结果集,打印结果集
    ○ 关闭

    >touch 05_client.c

    >vi 05_client.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"
    
    
    void show_result(MYSQL_RES * result,MYSQL *mysql)
    {
        //打印表头
        unsigned int num_fields;
        unsigned int i;
        MYSQL_FIELD *fields;
         
        num_fields = mysql_num_fields(result);
        fields = mysql_fetch_fields(result);
        for(i = 0; i < num_fields; i++)
        {
           printf("%s	", fields[i].name);
        }
        printf("
    ----------------------------------------------------------
    ");//华丽分割线
        
        
        MYSQL_ROW row;
            num_fields = mysql_num_fields(result);//取字段个数
        while ((row = mysql_fetch_row(result)))//循环取一行
        {
           for(i = 0; i < num_fields; i++)
           {
               printf("%s	",  row[i] ? row[i] : "NULL");
           }
           printf("
    ");
        }
        printf("
    ----------------------------------------------------------
    ");//华丽分割线
        //3 rows in set (0.28 sec)
        printf("%ld rows in set 
    ",mysql_affected_rows(mysql));//影响的数目
    }
    int main()
    {
        //1. init 
        MYSQL*mysql = mysql_init(NULL);
        if(mysql == NULL){
            printf("init err
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        printf("welcome to mysql!
    ");
        char rSql[1024]={0};
        while(1){
            write(STDOUT_FILENO,"yoursql>",8);
            memset(rSql,0x00,sizeof(rSql));
            read(STDIN_FILENO,rSql,sizeof(rSql));//读入sql
            if(strncmp(rSql,"quit",4) == 0){
                printf("bye bye!
    ");
                break;
            }
            //执行sql
            if(mysql_query(mysql,rSql) != 0){
                printf("mysql_query err
    ");
                continue;
            }
            //取回结果集
            int i=0;
            MYSQL_RES * result = mysql_store_result(mysql);
            MYSQL_ROW row;
            if(result != NULL){
                //需要打印结果集
                show_result(result,mysql);
                mysql_free_result(result);//释放结果集
            }else{
                //Query OK, 1 row affected (0.16 sec)
                printf("Query OK, %ld row affected 
    ",mysql_affected_rows(mysql));
                //printf("%ld products updated",(long) mysql_affected_rows(&mysql));
            }
        }
    
        //3. close
        mysql_close(mysql);
        return 0;
    }

    >make

    >./05_client

    yoursql>select * from dept;

    yoursql>insert into dept values(60, '60name', '60loc');

    yoursql>select * from dept;

    yoursql>desc dept;

    yoursql>show tables;

    7、字符集的问题

    yoursql>desc dept;

    yoursql>insert into dept(deptno,dname) values(61, '财务');

    yoursql>select * from dept;

    但是,打开另一个终端登录MySQL,输入指令

    mysql>select * from dept;

    出现问题:乱码。

    问题分析:MySQL默认是以gbk格式登录的,用自己客户端传入中文,传出中文,而用原mysql读出会乱码。如何解决?

    8、字符集问题处理

    》设置字符集
    int mysql_set_character_set(MYSQL *mysql, char *csname)

    >vi 05_client.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"
    
    
    void show_result(MYSQL_RES * result,MYSQL *mysql)
    {
        //打印表头
        unsigned int num_fields;
        unsigned int i;
        MYSQL_FIELD *fields;
         
        num_fields = mysql_num_fields(result);
        fields = mysql_fetch_fields(result);
        for(i = 0; i < num_fields; i++)
        {
           printf("%s	", fields[i].name);
        }
        printf("
    ----------------------------------------------------------
    ");//华丽分割线
        
        
        MYSQL_ROW row;
            num_fields = mysql_num_fields(result);//取字段个数
        while ((row = mysql_fetch_row(result)))//循环取一行
        {
           for(i = 0; i < num_fields; i++)
           {
               printf("%s	",  row[i] ? row[i] : "NULL");
           }
           printf("
    ");
        }
        printf("
    ----------------------------------------------------------
    ");//华丽分割线
        //3 rows in set (0.28 sec)
        printf("%ld rows in set 
    ",mysql_affected_rows(mysql));//影响的数目
    }
    int main()
    {
        //1. init 
        MYSQL*mysql = mysql_init(NULL);
        if(mysql == NULL){
            printf("init err
    ");
            exit(1);
        }
        //2. real_connect
        mysql = mysql_real_connect(mysql,_HOST_,_USER_,_PASSWD_,_DBNAME_,0,NULL,0);
        
        if(mysql == NULL){
            printf("connect err
    ");
            exit(1);
        }
        
        mysql_set_character_set(mysql, "utf8");//设置字符集
        
        printf("welcome to mysql!
    ");
        char rSql[1024]={0};
        while(1){
            write(STDOUT_FILENO,"yoursql>",8);
            memset(rSql,0x00,sizeof(rSql));
            read(STDIN_FILENO,rSql,sizeof(rSql));//读入sql
            if(strncmp(rSql,"quit",4) == 0){
                printf("bye bye!
    ");
                break;
            }
            //执行sql
            if(mysql_query(mysql,rSql) != 0){
                printf("mysql_query err
    ");
                continue;
            }
            //取回结果集
            int i=0;
            MYSQL_RES * result = mysql_store_result(mysql);
            MYSQL_ROW row;
            if(result != NULL){
                //需要打印结果集
                show_result(result,mysql);
                mysql_free_result(result);//释放结果集
            }else{
                //Query OK, 1 row affected (0.16 sec)
                printf("Query OK, %ld row affected 
    ",mysql_affected_rows(mysql));
                //printf("%ld products updated",(long) mysql_affected_rows(&mysql));
            }
        }
    
        //3. close
        mysql_close(mysql);
        return 0;
    }

    >make

    >./05_client.c

    现在两端看到的一致了,都是乱码,然后删除数据,重新插入。

    yoursql>delete from dept where deptno=61;

    yoursql>insert into dept values(61,'财务', '北京');

    9、预处理的流程

    对于多次执行的语句,预处理执行比直接执行快,主要原因在于,仅对查询执行一次解析操作。在直接执行的情况下,每次执行语句时,均将进行查询。此外,由于每次执行预处理语句时仅需发送参数的数据,从而减少了网络通信量。

    预处理语句的另一个优点是,它采用了二进制协议,从而使得客户端和服务器之间的数据传输更有效率。

    下述语句可用作预处理语句:CREATE TABLE、DELETE、DO、INSERT、REPLACE、SELECT、SET、UPDATE、以及大多数SHOW语句。在MySQL 5.1中,不支持其他语句。

    》预处理流程图:

    》可分析代码:(07_prepare_insert.c)

    #include <stdio.h>
    #include "mysql.h"
    #include <stdlib.h>
    #include <string.h>
    
    #define _HOST_ "localhost"  //主机
    #define _USER_ "root"       //mysql用户,非主机
    #define _PASSWD_ "123"   //密码
    #define _DBNAME_ "scott"    //库名
    
    #define STRING_SIZE 50
     
    #define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
    #define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,
                                                     col2 VARCHAR(40),
                                                     col3 SMALLINT,
                                                     col4 TIMESTAMP)"
    #define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"
    void prepare_insert(MYSQL *mysql);
    
    int main()
    {
        //1.初始化
        MYSQL * mysql = NULL;
        mysql = mysql_init(NULL) ;
        if(mysql == NULL )
        {
            printf("mysql init err
    ");
            exit(1);
        }
        //2.连接
        mysql = mysql_real_connect(mysql, _HOST_,_USER_, _PASSWD_,_DBNAME_, 0, NULL,0);
        if(mysql == NULL)
        {
            printf("mysql_real_connect connect err
    ");
            exit(1);
        }
        printf("welcome to mysql 
    ");
        prepare_insert(mysql);
        //3.关闭
        mysql_close(mysql);
        return 0;
    }
    
    
    
    
    void prepare_insert(MYSQL *mysql)
    {
        MYSQL_STMT    *stmt;//预处理的句柄
        MYSQL_BIND    bind[3];//绑定变量 
        my_ulonglong  affected_rows;
        int           param_count;
        short         small_data;
        int           int_data;
        char          str_data[STRING_SIZE];
        unsigned long str_length;
        my_bool       is_null;
         
        if (mysql_query(mysql, DROP_SAMPLE_TABLE))//删除表
        {
          fprintf(stderr, " DROP TABLE failed
    ");
          fprintf(stderr, " %s
    ", mysql_error(mysql));
          exit(0);
        }
         
        if (mysql_query(mysql, CREATE_SAMPLE_TABLE))//创建表
        {
          fprintf(stderr, " CREATE TABLE failed
    ");
          fprintf(stderr, " %s
    ", mysql_error(mysql));
          exit(0);
        }
         
        /* Prepare an INSERT query with 3 parameters */
        /* (the TIMESTAMP column is not named; the server */
        /*  sets it to the current date and time) */
        stmt = mysql_stmt_init(mysql); //预处理的初始化
        if (!stmt)
        {
          fprintf(stderr, " mysql_stmt_init(), out of memory
    ");
          exit(0);
        }
        if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE))) //insert 语句 的预处理 
        {
          fprintf(stderr, " mysql_stmt_prepare(), INSERT failed
    ");
          fprintf(stderr, " %s
    ", mysql_stmt_error(stmt));
          exit(0);
        }
        fprintf(stdout, " prepare, INSERT successful
    ");
         
        /* Get the parameter count from the statement */
        param_count= mysql_stmt_param_count(stmt);//获得参数个数 
        fprintf(stdout, " total parameters in INSERT: %d
    ", param_count);
         
        if (param_count != 3) /* validate parameter count */
        {
          fprintf(stderr, " invalid parameter count returned by MySQL
    ");
          exit(0);
        }
         
        /* Bind the data for all 3 parameters */
         
        memset(bind, 0, sizeof(bind));
         
        /* INTEGER PARAM */
        /* This is a number type, so there is no need to specify buffer_length */
        bind[0].buffer_type= MYSQL_TYPE_LONG;
        bind[0].buffer= (char *)&int_data;//内存地址的映射 
        bind[0].is_null= 0;
        bind[0].length= 0;
         
        /* STRING PARAM */
        bind[1].buffer_type= MYSQL_TYPE_STRING;
        bind[1].buffer= (char *)str_data;//char 100 
        bind[1].buffer_length= STRING_SIZE;
        bind[1].is_null= 0;
        bind[1].length= &str_length;
         
        /* SMALLINT PARAM */
        bind[2].buffer_type= MYSQL_TYPE_SHORT;
        bind[2].buffer= (char *)&small_data;
        bind[2].is_null= &is_null;//是否为null的指示器 
        bind[2].length= 0;
         
        /* Bind the buffers */
        if (mysql_stmt_bind_param(stmt, bind)) //绑定变量 参数绑定
        {
          fprintf(stderr, " mysql_stmt_bind_param() failed
    ");
          fprintf(stderr, " %s
    ", mysql_stmt_error(stmt));
          exit(0);
        }
         
        //第一波赋值 
        int_data= 10;             /* integer */
        strncpy(str_data, "MySQL", STRING_SIZE); /* string  */
        str_length= strlen(str_data);
         
        /* INSERT SMALLINT data as NULL */
        is_null= 1;//指示插入的第三个字段是否为null 
         
        /* Execute the INSERT statement - 1*/
        if (mysql_stmt_execute(stmt)) //预处理的执行,第一次执行 
        {
          fprintf(stderr, " mysql_stmt_execute(), 1 failed
    ");
          fprintf(stderr, " %s
    ", mysql_stmt_error(stmt));
          exit(0);
        }
         
        /* Get the total number of affected rows */
        affected_rows= mysql_stmt_affected_rows(stmt);//预处理的影响条数
        fprintf(stdout, " total affected rows(insert 1): %lu
    ",
                        (unsigned long) affected_rows);
         
        if (affected_rows != 1) /* validate affected rows */
        {
          fprintf(stderr, " invalid affected rows by MySQL
    ");
          exit(0);
        }
         
        //第二波赋值 
        int_data= 1000;
        strncpy(str_data, "The most popular Open Source database", STRING_SIZE);
        str_length= strlen(str_data);
        small_data= 1000;         /* smallint */
        is_null= 1;               /* reset */
         
        /* Execute the INSERT statement - 2*/
        if (mysql_stmt_execute(stmt))//第二次执行
        {
          fprintf(stderr, " mysql_stmt_execute, 2 failed
    ");
          fprintf(stderr, " %s
    ", mysql_stmt_error(stmt));
          exit(0);
        }
         
        /* Get the total rows affected */
        affected_rows= mysql_stmt_affected_rows(stmt);
        fprintf(stdout, " total affected rows(insert 2): %lu
    ",
                        (unsigned long) affected_rows);
         
        if (affected_rows != 1) /* validate affected rows */
        {
          fprintf(stderr, " invalid affected rows by MySQL
    ");
          exit(0);
        }
         
        /* Close the statement */
        if (mysql_stmt_close(stmt))
        {
          fprintf(stderr, " failed while closing the statement
    ");
          fprintf(stderr, " %s
    ", mysql_stmt_error(stmt));
          exit(0);
        }
    
    }
    07_prepare_insert.c

    10、预处理的内存映射

    》预处理内存映射图:

    >make

    >./07_prepare_insert

    打开另一个客户端,登录MySQL查看(mysql>select * from test_table)

    vi 07_prepare_insert.c更改165行的代码为:is_null= 0; 然后重新编译执行,并在另一个客户端查看。

    11、MySQL通过api处理事务

    》分析代码(06_client_format.c):

    //编写客户端  
    #include <stdio.h>
    #include "mysql.h"
    #include <stdlib.h>
    #include <string.h>
    
    #define _HOST_ "localhost"  //主机
    #define _USER_ "root"       //mysql用户,非主机
    #define _PASSWD_ "123"   //密码
    #define _DBNAME_ "scott"    //库名
    
    #define _MAX_COLS_  30 
    
    //定义格式化输出结构体
    typedef struct _strFormat{
        int length;  // 每个字段(列)最终显示的长度
        char sfm[10]; // 每个列的展示串的格式化效果
        char Column[100]; // 列显示效果 | empno 
        char splitLine[100]; // 华丽的分割线显示效果  +-------
    }strFormat;
    
    /*
    +-------+--------+-----------+------+------------+------+------+--------+
    | empno | ename  | job       | mgr  | hiredate   | sal  | comm | deptno |
    +-------+--------+-----------+------+------------+------+------+--------+
    |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800 | NULL |     20 |
    */
    
    //显示结果集
    void show_result(MYSQL_RES *result,MYSQL * mysql)
    {
        //展示result的结果
        if(result != NULL)
        {
            //代表结果集中有记录
            if(result->row_count == 0)
            {
                printf("Empty set
    ");
                return;    
            }
            //打印表头
            unsigned int num_fields;
            strFormat fm[_MAX_COLS_];
            bzero(&fm,sizeof(strFormat)*_MAX_COLS_);
            unsigned int i,j ;
            MYSQL_FIELD *fields;
            //printf("-------------------------------------------------------------------------
    ");
            num_fields = mysql_num_fields(result);
            fields = mysql_fetch_fields(result);//取回表头,即各个列名
            //以下循环为生成之前定义结构体对应的各个列的标准格式化
            for(i = 0; i < num_fields; i++)
            {
                fm[i].length = fields[i].name_length > fields[i].max_length ? fields[i].name_length:fields[i].max_length;//每个字段有多个长度,取名字长度和内容最长 两者之间的最大值
                fm[i].splitLine[0]='+';
                   for(j = 1 ; j < fm[i].length+3; j ++)
                   {
                       fm[i].splitLine[j]='-';
                   }
                if(i == num_fields -1)//最后一个字段需要特别处理一下,需要用"|" 作为结束
                {
                    sprintf(fm[i].sfm,"| %c-%ds |",'%',fm[i].length); // %-17c 
                    fm[i].splitLine[j]='+';
                }
                else 
                {
                    sprintf(fm[i].sfm,"| %c-%ds ",'%',fm[i].length);//得到的目标 是 "| %-8s "
                }
                sprintf(fm[i].Column,fm[i].sfm,fields[i].name);
            }
            for(j = 0 ; j < 3; j ++ )//此处为打印表头,注意,表头三行,华丽的分割线中间是列名
            {
                if(j == 1)//处理列名
                {
                    for(i = 0; i < num_fields; i++)
                    {
                        printf("%s",fm[i].Column);
                    }
                }
                else//处理华丽分割线
                {
                    for(i = 0; i < num_fields; i++)
                    {
                        printf("%s",fm[i].splitLine);
                        
                    }
                }
                printf("
    ");
            }
            
            //printf("-------------------------------------------------------------------------
    ");
            MYSQL_ROW row;
            num_fields = mysql_num_fields(result);
            while ((row = mysql_fetch_row(result)))//循环展示每一行的的内容
            {
               for(i = 0; i < num_fields; i++)//针对每一行,展示每一列,使用之前得到的输出格式化串
               {
                   
                       printf(fm[i].sfm, row[i] ? row[i] : "NULL");
               }
               printf("
    ");
            }
            for(i = 0; i < num_fields; i++)
            {
                printf("%s",fm[i].splitLine);
            }
            printf("
    %ld rows in set 
    ",(long) mysql_affected_rows(mysql));
    
        }
    }
    int main()
    {
        //1.初始化
        MYSQL * mysql = NULL;
        mysql = mysql_init(NULL) ;
        if(mysql == NULL )
        {
            printf("mysql init err
    ");
            exit(1);
        }
        //2.连接
        mysql = mysql_real_connect(mysql, _HOST_,_USER_, _PASSWD_,_DBNAME_, 0, NULL,0);
        if(mysql == NULL)
        {
            printf("mysql_real_connect connect err
    ");
            exit(1);
        }
        mysql_set_character_set(mysql, "utf8");//设置字符集
        printf("welcome to mysql 
    ");
        char rSql[512];
        while(1)//管理台
        {
            printf("yekaisql>");
            memset(rSql,0x00,sizeof(rSql));
            fgets(rSql,sizeof(rSql),stdin);
            //判断是否退出 quit
            if(strncmp(rSql,"quit",4) == 0 || strncmp(rSql,"QUIT",4) == 0)
            {
                printf("bye bye
    ");
                break;
            }
            //查询
            if(mysql_query(mysql,rSql) != 0)
            {
                printf("query err
    ");
                //mysql_close(mysql);
                //exit(1);
                continue;
            }
            //打印结果
            //先取回结果 
            MYSQL_RES *result = NULL ;
            result = mysql_store_result(mysql); 
            
            if(result){
                //打印结果集
                show_result(result,mysql);
                //释放结果集
                mysql_free_result(result); 
            }
            else
            {
                printf("Query OK, %ld  rows affected 
    ",(long) mysql_affected_rows(mysql));
            }
                    
        }
        //3.关闭
        mysql_close(mysql);
        return 0;
    }
    06_client_format.c

    >make

    >./06_client_format

    yekaisql>select * from dept;

    yekaisql>select * from emp;

    yekaisql>quit

    》分析代码(08_tran.c):

    //mysql中的事务
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "mysql.h"
    
    #define SET_TRAN    "SET AUTOCOMMIT=0"          //手动commit    ————手动commit
    #define UNSET_TRAN    "SET AUTOCOMMIT=1"            //自动commit
    
    #define _HOST_ "127.0.0.1"
    #define _USER_ "root"
    #define _PASSWD_ "123"
    #define _DBNAME_ "scott"
    
    //设置事务为手动提交
    int mysql_OperationTran(MYSQL *mysql)              
    {
        //--开启事务
        int ret = mysql_query(mysql, "start transaction");  
        if (ret != 0) {
            printf("mysql_OperationTran query start err: %s
    ", mysql_error(mysql));
            return ret;
        }
    
        //--设置事务为手动提交
        ret = mysql_query(mysql, SET_TRAN);            //set autocommmit = 0
        if (ret != 0) {
            printf("mysql_OperationTran query set err: %s
    ", mysql_error(mysql));
            return ret;
        }
    
        return ret;
    }
    
    //设置事务为自动提交
    int mysql_AutoTran(MYSQL *mysql)
    {
        //--开启事务
        int ret = mysql_query(mysql, "start transaction");  
        if (ret != 0) {
            printf("mysql_AutoTran query start err: %s
    ", mysql_error(mysql));
            return ret;
        }
    
        //--设置事务为自动提交
        ret = mysql_query(mysql, UNSET_TRAN);  //"set autocommit = 1"
        if (ret != 0) {
            printf("mysql_AutoTran query set err: %s
    ", mysql_error(mysql));
            return ret;
        }
    
        return ret;        
    }
    
    //执行commit,手动提交事务
    int mysql_Commit(MYSQL *mysql)
    {
        int ret = mysql_query(mysql, "COMMIT"); //提交
        if (ret != 0) {
            printf("commit err: %s
    ", mysql_error(mysql));
            return ret;
        }
        return ret;
    }
    
    //执行rollback,回滚事务        
    int mysql_Rollback(MYSQL *mysql)
    {
        int ret = mysql_query(mysql, "ROLLBACK");
        if (ret != 0) {
            printf("rollback err: %s
    ", mysql_error(mysql));
            return ret;
        }
        return ret;
        
    }
    
    #define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
    #define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,
                                                     col2 VARCHAR(10),
                                                     col3 VARCHAR(10))"
                                                                                           
    #define sql01 "INSERT INTO test_table(col1,col2,col3) VALUES(10, 'AAA', 'A1')"
    #define sql02 "INSERT INTO test_table(col1,col2,col3) VALUES(20, 'BBB', 'B2')"
    #define sql03 "INSERT INTO test_table(col1,col2,col3) VALUES(30, 'CCC', 'C3')"
    #define sql04 "INSERT INTO test_table(col1,col2,col3) VALUES(40, 'DDD', 'D4')"
    
    int main(void)
    {
        int ret = 0;
    
        MYSQL *mysql = mysql_init(NULL);
        
        mysql = mysql_real_connect(mysql, _HOST_, _USER_, _PASSWD_, _DBNAME_, 0, NULL, 0);
        if (mysql == NULL) {
            ret = mysql_errno(mysql);
            printf("func mysql_real_connect() err:%d
    ", ret);
            return ret;
        }     
        printf(" --- connect ok......
    ");    
        //执行删除表
        if (mysql_query(mysql, DROP_SAMPLE_TABLE)) {
          fprintf(stderr, " DROP TABLE failed
    ");
          fprintf(stderr, " %s
    ", mysql_error(mysql));
          exit(0);
        }
        //执行创建表
        if (mysql_query(mysql, CREATE_SAMPLE_TABLE)) {
          fprintf(stderr, " CREATE TABLE failed
    ");
          fprintf(stderr, " %s
    ", mysql_error(mysql));
          exit(0);
        }    
        
        ret = mysql_OperationTran(mysql);     //开启事务,并修改事务属性为手动commit 
        if (ret != 0) {
            printf("mysql_OperationTran() err:%d
    ", ret);
            return ret;
        }
        
        ret = mysql_query(mysql, sql01);    //向表中插入第一行数据 ‘AAA’
        if (ret != 0) {
            printf("mysql_query() err:%d
    ", ret);
            return ret;
        }
        
        ret = mysql_query(mysql, sql02);    //向表中插入第二行数据 ‘BBB’
        if (ret != 0) {
            printf("mysql_query() err:%d
    ", ret);
            return ret;
        }
        
        ret = mysql_Commit(mysql);             //手动提交事务
        if (ret != 0) {
            printf("mysql_Commit() err:%d
    ", ret);
            return ret;
        }
        //////////AAA BBB  进去了。
        
    #if 1
        ret = mysql_AutoTran(mysql);         // =再次= 修改事务属性为【自动】commit
        if (ret != 0) {
            printf("mysql_OperationTran() err:%d
    ", ret);
            return ret;
        }
    #else 
        ret = mysql_OperationTran(mysql);     // =再次= 修改事务属性为【手动】commit
        if (ret != 0) {
            printf("mysql_OperationTran() err:%d
    ", ret);
            return ret;
        }
    #endif
    
        ret = mysql_query(mysql, sql03);    //向表中插入第三行数据 ‘CCC’
        if (ret != 0) {
            printf("mysql_query() err:%d
    ", ret);
            return ret;
        }
        
        ret = mysql_query(mysql, sql04);    //向表中插入第四行数据 ‘DDD’
        if (ret != 0) {
            printf("mysql_query() err:%d
    ", ret);
            return ret;
        }
        
        ret = mysql_Rollback(mysql);        //直接rollback操作
        if (ret != 0) {
            printf("mysql_Rollback() err:%d
    ", ret);
            return ret;
        }
        
        //rollback操作是否能回退掉CCC、DDD的值,取决于事务属性。
        
        mysql_close(mysql);
        
        return 0;    
    }
    08_tran.c

    >make

    >./08_tran

    (一定要确保set autocommit=1;)

    打开另一个客户端,输入(mysql>select * from test_table;)

    》设置为手动提交,相当于开启事务

    set autocommit=0;(需要手动执行commit; 再另一个客户端才能看到结果。)

    12、课后作业

    》上传文件
    upload srcfile desfile
    //字符串拆分函数
    void splitString(const char *Src, char delim, vector<string> &vsplit);
    find_first_not_of 找第一个不是的
    find_first_of  找第一个是的

    》(MysqlTran.h和MysqlTran.cpp)代码如下:

    #pragma once
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stdlib.h>
    #include <stdio.h>
    
    using namespace std;
    class CMysqlTran
    {
    public:
        //构造函数,初始化mysql连接
        CMysqlTran(const char *Host,const char *User, const char *Pass, const char *db);
        //析构函数,释放mysql连接
        ~CMysqlTran();
        //执行sql语句,用于insert,update,delete类sql使用
        int ExeSql(const char *rSql);
        //查询sql返回结果数,用于统计查询sql的结果集数量
        int SelectDataCount(const char *rSql);
        //查询sql并且显示相应的结果集
        int SelectData(const char *rSql);
        
    private:
        
    };
    //字符串拆分函数
    void splitString(const char *Src, char delim, vector<string> &vsplit);
    MysqlTran.h
    #include "MysqlTran.h"
    #include <mysql.h>
    
    
    
    
    MYSQL *mysql = NULL;
    void show_result(MYSQL_RES * result);//打印结果集函数
    CMysqlTran::CMysqlTran(const char *Host, const char *User, const char *Pass, const char *db)
    {
        //mysql连接的初始化
        mysql = mysql_init(NULL);
        if (mysql == NULL){
            cout << "mysql init err" << endl;
            exit(1);
        }
        //连接到mysql数据库
        mysql = mysql_real_connect(mysql, Host, User, Pass, db, 0, NULL, 0);
        if (mysql == NULL){
            cout << "mysql conn err" << endl;
            exit(1);
        }
    }
    
    CMysqlTran::~CMysqlTran()
    {
        if (mysql){
            //释放连接
            mysql_close(mysql);
        }
    }
    int CMysqlTran::ExeSql(const char *rSql)
    {
        return mysql_query(mysql, rSql);
    }
    int CMysqlTran::SelectDataCount(const char *rSql)
    {
        int RowCount = 0;
        //执行查询sql
        if (mysql_query(mysql, rSql)){
            cout << "run Sql err:" << rSql << endl;
            return -1;
        }
        //取回结果集
        MYSQL_RES *result = mysql_store_result(mysql);
        if (result){
            //获取结果集的行数
            RowCount = result->row_count;
            return RowCount;
        }
        return 0;
    }
    int CMysqlTran::SelectData(const char *rSql)
    {
        if (mysql_query(mysql, rSql)){
            cout << "run Sql err:" << rSql << endl;
            return -1;
        }
        //取回结果集,打印结果集 
        MYSQL_RES * result = mysql_store_result(mysql);  //取回结果集
        if (result != NULL)//代表有需要处理的结果集
        {
    
            show_result(result);//打印结果集
            mysql_free_result(result);//释放结果集
        }
    }
    void show_result(MYSQL_RES * result)//打印结果集函数
    {
        unsigned int num_fields;
        unsigned int i;
        MYSQL_FIELD *fields;
    
        num_fields = mysql_num_fields(result); // 取结果集的字段个数
        fields = mysql_fetch_fields(result); // 取结果集中的字段结构信息 数组
        for (i = 0; i < num_fields; i++)
        {
            printf("%s	", fields[i].name);//打印结果集的字段名
        }
        printf("
    -----------------------------------------------------------------------
    ");//华丽的分割线
    
    
        //获取行
        //MYSQL_ROW row =  mysql_fetch_row(MYSQL_RES *result) 返回结果为NULL代表 取完
        MYSQL_ROW row;
        while ((row = mysql_fetch_row(result)) != NULL)//循环取每一行
        {
            for (i = 0; i < num_fields; i++)//因为知道有8列,所以可以这样写.
            {
                printf("%s	", row[i]);
            }
            printf("
    ");
        }
        printf("-----------------------------------------------------------------------
    ");//华丽的分割线
        printf("%llu rows in set 
    ", result->row_count);//打印获得的行数
    }
    //quit
    //upload 11 22
    //download 22 11
    //list
    void splitString(const char *Src, char delim, vector<string> &vsplit)
    {
        string tmp = Src;
        vsplit.clear();
        int index = 0;
        size_t last = 0;
        last = tmp.find_first_not_of(delim, last);//找到第一个不为分隔符的字符
        index = tmp.find_first_of(delim, last);//找到第一个分隔符
        while (index != string::npos)//npos代表字符串的结尾
        {
            string target = tmp.substr(last, index - last);
            vsplit.push_back(target);
    
            //last = index +1;
            last = tmp.find_first_not_of(delim, index);
            index = tmp.find_first_of(delim, last);
    
        }
        if (index == string::npos && tmp.length() > last)//到末尾了,如果整个长度大于last坐标,说明还有最后一个字符要放到vector
        {
            vsplit.push_back(tmp.substr(last));
        }
    #if 0
        cout << vsplit.size() << endl;
        for (size_t i = 0; i < vsplit.size(); i++)
        {
            cout << "i=" << i << "," << vsplit[i].c_str() << endl;
        }
    #endif
    }
    MysqlTran.cpp

    五、monogodb数据库

    1、monogodb数据库的安装

    RedHat/CentOS下的安装步骤

    http://docs.mongodb.org/manual/tutorial/install-mongodb-on-red-hat/

    》下载mongodb压缩包

    http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.10.tgz

    如果虚拟机登录输入:(可以直接下载到本地)

    shell>wget  http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.10.tgz

    也可以使用下载好的安装包: mongodb-linux-x86_64-2.6.10.gz

    root用户登录
    >tar -zxvf mongodb-linux-x86_64-2.6.10.gz
    >mv mongodb-linux-x86_64-2.6.10 /usr/local/mongodb
    >cd /usr/local/mongodb
    >mkdir db
    >mkdir logs
    >cd bin

    》增加配置文件
    >vi mongodb.conf
    dbpath=/usr/local/mongodb/db
    logpath=/usr/local/mongodb/logs/mongodb.log
    port=27017
    fork=true
    nohttpinterface=true
     
    》开机自动启动mongodb
    >vi /etc/rc.d/rc.local
    /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/bin/mongodb.conf

    》建议mongo快捷启动
    ln -s /usr/local/mongodb/bin/mongo /usr/local/bin/mongo


    》ubuntu安装
    sudo apt-get install mongodb

    2、monogodbc+驱动安装

    》MongoDB的 C++驱动下载源 目前有三个版本:
    1)26compat
        下载网址 https://github.com/mongodb/mongo-cxx-driver/tree/26compat
    2)legacy
        下载网址 https://github.com/mongodb/mongo-cxx-driver/tree/legacy
    3)master
        下载网址 https://github.com/mongodb/mongo-cxx-driver/tree/master

    》Redhat/centOS下安装MongoDB的C++驱动

    1)安装boost库准标准库

      下载boost_1_55_0.zip:http://jaist.dl.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.zip

    2)安装PCRE c++的正则表达式的第三方库

      下载pcre-8.00.tar.gz:http://jaist.dl.sourceforge.net/project/pcre/pcre/8.00/pcre-8.00.tar.gz

    3)scons 编译驱动(因为mongoDB驱动编译不是用CMake,需要下载scons)

      下载scons-2.5.0-1.noarch.rpm:http://jaist.dl.sourceforge.net/project/scons/scons/2.5.0/scons-2.5.0-1.noarch.rpm

    4)编译驱动程序

      下载mongodb的驱动程序:http://downloads.mongodb.org/cxx-driver/mongodb-linux-x86_64-v2.2-latest.tgz

    》编译testmongo.cpp

    //g++ -o testmongo testmongo.cpp -lmongoclient -lboost_thread -lboost_filesystem -lboost_program_options -L/home/itcast/driver/boost/lib -L/home/itcast/driver/mongo/lib -I/home/itcast/driver/mongo/include -I/home/itcast/driver/boost/include
    #include <iostream>   
    
    #include "mongo/client/dbclient.h"   
    
    char dbhost[20]="localhost"; 
    using namespace mongo;
    using namespace std;
    void printIfAge(DBClientConnection& c, int age) {  
    auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", QUERY( "age" << age ).sort("name") );  
        while( cursor->more() ) {  
            BSONObj p = cursor->next();  
            cout << p.getStringField("name") << endl;  
        }  
    }  
    
    void run() {  
        DBClientConnection c;  
        c.connect(dbhost);   
        cout << "connected ok" << endl;  
        BSONObj p = BSON( "name" << "Joe" << "age" << 33 );  
        c.insert("tutorial.persons", p); /**< 向person表中插入数据 */  
        p = BSON( "name" << "Jane" << "age" << 40 );  
        c.insert("tutorial.persons", p);  
        p = BSON( "name" << "Abe" << "age" << 33 );  
        c.insert("tutorial.persons", p);  
        p = BSON( "name" << "Samantha" << "age" << 21 << "city" << "Los Angeles" << "state" << "CA" );  
        c.insert("tutorial.persons", p);  
        c.ensureIndex("tutorial.persons", fromjson("{age:1}"));  
        cout << "count:" << c.count("tutorial.persons") << endl; /**< 显示person表中的数据数目 */  
        auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", BSONObj());  
        while( cursor->more() ) {  
            cout << cursor->next().toString() << endl;  
        }  
        cout << "
    printifage:
    ";  
        printIfAge(c, 33);  
    }  
    int main(int argc,char *argv[]) {  
        if(argc == 2)
        {
            memset(dbhost,0x00,sizeof(dbhost));
            strcpy(dbhost,argv[1]);
            printf("connect to dbhost:[%s]
    ",dbhost);
        }
        else
        {
            printf("connect to dbhost:[%s]
    ",dbhost);
            printf("if you need to connet to remote service,please input ip!
    ");
        }
    
        try {  
            run();  
        }  
    
        catch( DBException &e ) {  
            cout << "caught " << e.what() << endl;  
        }  
        return 0;  
    }
    testmongo.cpp

    >g++ -o testmongo testmongo.cpp -lmongoclient -lboost_thread -lboost_filesystem -lboost_program_options -L/home/itcast/driver/boost/lib -L/home/itcast/driver/mongo/lib -I/home/itcast/driver/mongo/include -I/home/itcast/driver/boost/include

    >mongo(没有密码,直接登录)

    >show dbs

    打开另一个终端,切换到相应目录下,执行>./testmongo

    再切换到原终端

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

  • 相关阅读:
    HTML5和CSS3的学习视频
    webpack中bundler源码编写2
    webpack中bundler源码编写
    webpack中如何编写一个plugin
    webpack多页面打包配置
    webpack中配置eslint
    webpack解决单页面路由问题
    webpack中使用WebpackDevServer实现请求转发
    webpack中typeScript的打包配置
    rsync 同步
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_Database_04.html
Copyright © 2020-2023  润新知