zoukankan      html  css  js  c++  java
  • 【C/C++学院】(23)Mysql数据库编程--C语言编程实现mysqlclient


    【送给在路上的程序猿】

    对于一个开发人员而言,能够胜任系统中随意一个模块的开发是其核心价值的体现。



    对于一个架构师而言,掌握各种语言的优势并能够利运用到系统中,由此简化系统的开发,是其架构生涯的第一步。



    对于一个开发团队而言。能够在短期内开发出用户惬意的软件系统是其核心竞争力的体现。

    每个程序猿都不能固步自封,要多接触新的行业,新的技术领域,突破自我。


    makefile

    .SUFFIXES: .c .o
    
    CC=gcc
    SRCS=mysql1.c
                mydb.c
    
    OBJS=$(SRCS:.c=.o)
    EXEC=mysql1
    
    all: $(OBJS)
        $(CC) -o $(EXEC) $(OBJS) -lmysqlclient
        @echo '-------------ok--------------'
    
    .c.o:
        $(CC) -Wall -g -o $@ -c $< 
    
    clean:
        rm -f $(OBJS)
        rm -f core*
    

    mydb.h

    #ifndef MYDB_H_
    #define MYDB_H_
    
    
    void init_db();
    int conn_db(const char *hostname, const char *username, const char *password,
            const char *dbname);
    void disconn_db();
    int open_db(const char *SQL);
    int exec_db(const char *SQL);
    
    #endif /* MYDB_H_ */

    mydb.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <mysql/mysql.h>
    #include "mydb.h"
    
    MYSQL *connection = NULL;
    MYSQL mysql;
    
    void init_db()
    {
        mysql_init(&mysql);//初始化mysql
    }
    
    int conn_db(const char *hostname, const char *username, const char *password,
            const char *dbname)
    {
        if (connection)
            mysql_close(connection);
        connection = mysql_real_connect(&mysql, hostname, username, password,
                dbname, 0, 0, 0);//连接到mysql
    
        if (connection == NULL)
        {
            printf("%s
    ", mysql_error(&mysql));
            return -1;//连接失败,返回-1
        }
    
        printf("success connect to mysql
    ");
        return 0;
    }
    
    void disconn_db()//断开数据库连接
    {
        if (connection)
        {
            mysql_close(connection);
            connection = NULL;
        }
    }
    
    int open_db(const char *SQL)//运行有返回数据集的SQL语句
    {
        int state = mysql_query(connection, SQL);//运行SQL语句
        if (state != 0)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;//运行失败,返回-1
        }
    
        MYSQL_RES *result = mysql_store_result(connection);//得到查询结果
        if (result == (MYSQL_RES *) NULL)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;//运行失败。返回-1
        } else
        {
            MYSQL_FIELD *sqlField;
            int iFieldCount = 0;
            while (1)//循环遍历全部字段
            {
                sqlField = mysql_fetch_field(result);
                if (sqlField == NULL)
                    break;
                printf("%s	", sqlField->name);//向屏幕打印字段名
                iFieldCount++;
            }
            printf("
    ");//每一行结尾打印一个
    字符
    
            MYSQL_ROW sqlRow;
            while (1)//循环到每一行
            {
                sqlRow = mysql_fetch_row(result);
                if (sqlRow == NULL)
                    break;
                int i;
                for (i = 0; i < iFieldCount; i++)//循环得到每一行中的每个字段
                {
                    if (sqlRow[i] == NULL)
                        printf("NULL	");//假设值为NULL。屏幕打印为"NULL"
                    else
                        printf("%s	", (const char *)sqlRow[i]);//屏幕打印为字段内容
                }
                printf("
    ");//每一行结尾打印一个
    字符
            }
            printf("query is ok, %u rows affected
    ", (unsigned int)mysql_affected_rows(connection));
            mysql_free_result(result);
        }
        return 0;
    }
    
    int exec_db(const char *SQL)//运行没有返回数据集的SQL语句
    {
        int state = mysql_query(connection, SQL);//运行SQL语句
        if (state != 0)
        {
            printf("%s
    ", mysql_error(connection));
            return -1;
        }
        printf("query is ok, %u rows affected
    ", (unsigned int)mysql_affected_rows(connection));
        return 0;
    }

    mysql1.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <termios.h>
    #include "mydb.h"
    
    
    void sqldb(const char *src)//參数src为要运行的SQL语句
    {
        if ((strncmp(src, "select", 6) == 0) || (strncmp(src, "SELECT", 6) == 0)
                || (strncmp(src, "show", 4) == 0) || (strncmp(src, "SHOW", 4) == 0)
                || (strncmp(src, "desc", 4) == 0) || (strncmp(src, "DESC", 4) == 0))
        {
            open_db(src);//假设src为有返回数据集SQL语句,那么调用open_db函数
        } else
        {
            exec_db(src);//假设src为没有有返回数据集SQL语句。那么调用exec_db函数
        }
    }
    
    
    
    void work(const char *userid, const char *password)
    {
        init_db();
        if (conn_db("localhost", userid, password, "test") != 0)//连接到数据库
        {
            return;//连接数据库失败。函数退出
        }
        char buf[2048];
        while (1)//循环从键盘读取
        {
            write(STDOUT_FILENO, "mysql1>", strlen("mysql1>"));//屏幕输出命令提示符mysql1>
            memset(buf, 0, sizeof(buf));
            read(STDIN_FILENO, buf, sizeof(buf));//等待用户从键盘输入
            if (strncmp(buf, "quit", 4) == 0)
                break;//用户输入quit,循环break;
            sqldb(buf);
        }
        disconn_db();//断开数据库连接
    }
    
    
    struct termios oldterm;
    void setstty()//设置输入退格键,不回显
    {
        //system("stty erase ^H");//运行shell命令,也能够 用来设置读取用户键盘输入的时候。退格键不回显
        struct termios term;
        if(tcgetattr(STDIN_FILENO, &term) == -1)//得到系统termion的设置
        {
            printf("tcgetattr error is %s
    ", strerror(errno));
            return;
        }
    
        oldterm = term;//保留当前termios设置,以便程序退出的时候能够恢复termios
    
        /*
        term.c_lflag &= ~ICANON;//取消ICANON选项(不规范输入)
        term.c_lflag |= ICANON;//设置ICANON选项(规范输入)
        term.c_cc字段为要设置的详细特殊输入字符,如c_cc[VERASE]代表退格键,
        term.c_cc[VERASE] = '';意思为把退格键改动为''
        VERASE代表向前擦出一个字符,VINTR代表发送ctrl + C中断信号,ctrl + c的ASCII码为3
        比如:term.c_cc[VINTR] = '	';意思为将tab键设置为终端信号
        tcsetattr中,第二个參数说明,TCSAFLUSH:发送了全部输出后更改才生效。在更改发生时,未读取的全部输入数据都被删除
        TCSANOW:更改马上生效
        TCSADRAIN:发送了全部输出后更改才发生。假设更改输出參数则应该使用该选项
        */
        term.c_cc[VERASE] = '';//''为退格键的ASCII码
        if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)//设置系统termion
        {
            printf("tcsetattr error is %s
    ", strerror(errno));
        }
        return;
    }
    
    void returnstty()//恢复系统的termios设置
    {
        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldterm) == -1)//设置系统termion
        {
            printf("tcsetattr error is %s
    ", strerror(errno));
        }
        return;
    }
    
    
    int main(int arg, char *args[])
    {
        if (arg < 4)//假设没有參数,main函数退出
        {
            return EXIT_FAILURE;
        }
    
        if (strncmp(args[1], "-u", 2) != 0)//假设第二个參数不是-u。main函数退出
        {
            return EXIT_FAILURE;
        }
    
        if (strncmp(args[3], "-p", 2) != 0)//假设第四个參数不是-p,main函数退出
        {
            return EXIT_FAILURE;
        }
    
        const char *passwd = getpass("please input password:");//输入密码,屏幕不回显
    
        setstty();//设置输入退格键,不回显
        work(args[2], passwd);
        returnstty();//恢复系统的termios设置
        return EXIT_SUCCESS;
    }


    |========== 吴英强CSDN博客专栏==========|

    |== C/C++学院 专栏文章的内容(不定期更新)===|

    |== linux驱动开发 探索linux底层的奥秘 ========|

    |== Java基础学习篇 掌握java语言的基础知识=====|

    |====== 每天进步一点点,健康快乐每一天 ======|

  • 相关阅读:
    SpringMVC-乱码问题
    SpringMVC-数据提交
    SpringMVC-结果跳转方式
    SpringMVC-Controller&RestFul
    SpringMVC-基础
    Spring-声明式事务
    Spring-整合MyBatis
    Spring-AOP
    android 入门-工序
    android 入门-android Studio 解决方案
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5078268.html
Copyright © 2011-2022 走看看