• Linux下C与Mysql的混合编程


    1 概述

      MySQL 是一个关系型数据库管理系统。由瑞典MySQL AB公司开发,眼下属于Oracle公司。MySQL是最流行的关系型数据库管理系统。

       支持AIX、FreeBSD、HP-UX、Linux、Mac OS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris、Windows等多种操作系统。 为多种编程语言提供了API。这些编程语言包含C、C++、Python、Java、Perl、PHP、Eiffel、Ruby,.NET和Tcl等。

    2 安装mysql

    2.1 通过网络安装mysql

    2.1.1 检查是否已经安装mysql

          # rpm -qa | grep mysql 

             // 上述命令就会查看该操作系统上是否已经安装了mysql数据库

          有的话。我们就通过 rpm -e 命令 或者 rpm -e --nodeps 命令来卸载掉

          #rpm -e --nodeps mysql

          在删除完以后我们能够通过 rpm -qa | grep mysql 命令来查看mysql是否已经卸载成功!

    2.1.2 通过yum来进行mysql的安装

        #yum install -y mysql-server mysql mysql-deve

          通过输入 yum install -y mysql-server mysql mysql-devel 命令将mysql mysql-server mysql-devel都安装好(注意:安装mysql时我们并非安装了mysqlclient就相当于安装好了mysql数据库了,我们还须要安装mysql-server服务端才行) 

        通过yum方式安装mysql数据库省去了非常多不是必需的麻烦。当出现以下的结果时,就代表mysql数据库成功安装了

        

    此时我们能够通过例如以下命令,查看刚安装好的mysql-server的版本号

            #rpm -qi mysql-server

    2.2 离线安装mysql

    2.2.1 检查是否安装mysql

    方法同2.1.1

    2.2.2 通过rpm安装mysql

     1. 须要准备离线安装包

        MySQL-server-5.5.30-1.el6.x86_64.rpm

        MySQL-client-5.5.30-1.el6.x86_64.rpm

        MySQL-devel-5.5.30-1.el6.x86_64.rpm 

     2.安装新的MySQL

       #rpm -ivh MySQL-server-5.5.30-1.el6.x86_64.rpm

       #rpm -ivh MySQL-client-5.5.30-1.el6.x86_64.rpm

       #rpm -ivh MySQL-devel-5.5.30-1.el6.x86_64.rpm 

     3.启动MySQL服务

       #service mysql start

     4.查看mysql执行状态

       #/etc/rc.d/init.d/mysqld status

     5.MySQL服务一些其它命令

        a、察看mysql是否在自己主动启动列表:  #/sbin/chkconfig list

        b、加入mysql到系统自启动服务组:  #/sbin/chkconfig – addmysql

        c、把mysql从启动服务组中删除:    #/sbin/chkconfig – delmysql  

        d、停止mysql服务:                # service mysqld stop

        e、脚本启动mysql服务:            # /etc/rc.d/init.d/mysqld start  

    f、脚本停止mysql服务:            # /etc/rc.d/init.d/mysqld stop

    2.3 mysql设置password

    命令例如以下:

       # /usr/bin/mysqladmin -u root password '123456'

    2.4 mysql设置开机启动

    2.4.0.1  查看Mysql服务是否是开机启动

      命令例如以下:

        #chkconfig --list | grep mysqld 

    2.4.0.2  设置开机启动

    命令例如以下:

     # chkconfig mysqld on

     

    2.5 Mysql数据库的主要配置

    /etc/my.cnf 这是mysql的主配置文件

    我们能够查看一下这个文件的一些信息

    # cat my.cnf 

    [mysqld]

    datadir=/var/lib/mysql

    socket=/var/lib/mysql/mysql.sock

    user=mysql

    # Disabling symbolic-links is recommended to prevent assorted security risks

    symbolic-links=0

    [mysqld_safe]

    log-error=/var/log/mysqld.log

    pid-file=/var/run/mysqld/mysqld.pid

    简要介绍

    ./var/lib/mysql   mysql数据库的数据库文件存放位置

    ./var/log mysql数据库的日志输出存放位置

    3 CMysql

    3.1 Mysql C API 函数概述

    这里归纳了C API可使用的函数

    函数

    描写叙述

    mysql_affected_rows()

    返回上次UPDATE、DELETE或INSERT查询更改/删除/插入的行数。

    mysql_autocommit()

    切换 autocommit模式,ON/OFF

    mysql_change_user()

    更改打开连接上的用户和数据库。

    mysql_charset_name()

    返回用于连接的默认字符集的名称。

    mysql_close()

    关闭server连接。

    mysql_commit()

    提交事务。

    mysql_connect()

    连接到MySQLserver。

    该函数已不再被重视。使用mysql_real_connect()代替。

    mysql_create_db()

    创建数据库。该函数已不再被重视,使用SQL语句CREATE DATABASE取而代之。

    mysql_data_seek()

    在查询结果集中查找属性行编号。

    mysql_debug()

    用给定的字符串运行DBUG_PUSH。

    mysql_drop_db()

    撤销数据库。该函数已不再被重视,使用SQL语句DROP DATABASE取而代之。

    mysql_dump_debug_info()

    让server将调试信息写入日志。

    mysql_eof()

    确定是否读取了结果集的最后一行。该函数已不再被重视。能够使用mysql_errno()或mysql_error()取而代之。

    mysql_errno()

    返回上次调用的MySQL函数的错误编号。

    mysql_error()

    返回上次调用的MySQL函数的错误消息。

    mysql_escape_string()

    为了用在SQL语句中,对特殊字符进行转义处理。

    mysql_fetch_field()

    返回下一个表字段的类型。

    mysql_fetch_field_direct()

    给定字段编号,返回表字段的类型。

    mysql_fetch_fields()

    返回全部字段结构的数组。

    mysql_fetch_lengths()

    返回当前行中全部列的长度。

    mysql_fetch_row()

    从结果集中获取下一行

    mysql_field_seek()

    将列光标置于指定的列。

    mysql_field_count()

    返回上次运行语句的结果列的数目。

    mysql_field_tell()

    返回上次mysql_fetch_field()所使用字段光标的位置。

    mysql_free_result()

    释放结果集使用的内存。

    mysql_get_client_info()

    以字符串形式返回client版本号信息。

    mysql_get_client_version()

    以整数形式返回client版本号信息。

    mysql_get_host_info()

    返回描写叙述连接的字符串。

    mysql_get_server_version()

    以整数形式返回server的版本。

    mysql_get_proto_info()

    返回连接所使用的协议版本号。

    mysql_get_server_info()

    返回server的版本。

    mysql_info()

    返回关于近期所运行查询的信息。

    mysql_init()

    获取或初始化MYSQL结构。

    mysql_insert_id()

    返回上一个查询为AUTO_INCREMENT列生成的ID。

    mysql_kill()

    杀死给定的线程。

    mysql_library_end()

    终于确定MySQL C API库。

    mysql_library_init()

    初始化MySQL C API库。

    mysql_list_dbs()

    返回与简单正則表達式匹配的数据库名称。

    mysql_list_fields()

    返回与简单正則表達式匹配的字段名称。

    mysql_list_processes()

    返回当前server线程的列表。

    mysql_list_tables()

    返回与简单正則表達式匹配的表名。

    mysql_more_results()

    检查是否还存在其它结果。

    mysql_next_result()

    在多语句运行过程中返回/初始化下一个结果。

    mysql_num_fields()

    返回结果集中的列数。

    mysql_num_rows()

    返回结果集中的行数。

    mysql_options()

    为mysql_connect()设置连接选项。

    mysql_ping()

    检查与server的连接是否工作,如有必要又一次连接。

    mysql_query()

    运行指定为“以Null终结的字符串”的SQL查询。

    mysql_real_connect()

    连接到MySQLserver。

    mysql_real_escape_string()

    考虑到连接的当前字符集,为了在SQL语句中使用。对字符串中的特殊字符进行转义处理。

    mysql_real_query()

    运行指定为计数字符串的SQL查询。

    mysql_refresh()

    刷新或复位表和快速缓冲。

    mysql_reload()

    通知server再次载入授权表。

    mysql_rollback()

    回滚事务。

    mysql_row_seek()

    使用从mysql_row_tell()返回的值,查找结果集中的行偏移。

    mysql_row_tell()

    返回行光标位置。

    mysql_select_db()

    选择数据库。

    mysql_server_end()

    终于确定嵌入式server库。

    mysql_server_init()

    初始化嵌入式server库。

    mysql_set_server_option()

    为连接设置选项(如多语句)。

    mysql_sqlstate()

    返回关于上一个错误的SQLSTATE错误代码。

    mysql_shutdown()

    关闭数据库server。

    mysql_stat()

    以字符串形式返回server状态。

    mysql_store_result()

    检索完整的结果集至client。

    mysql_thread_id()

    返回当前线程ID。

    mysql_thread_safe()

    假设client已编译为线程安全的,返回1。

    mysql_use_result()

    初始化逐行的结果集检索。

    mysql_warning_count()

    返回上一个SQL语句的告警数。

    3.2 API使用的一般原则

    MySQL交互时,应用程序应使用该一般性原则:

    1.    通过调用mysql_library_init(),初始化MySQL库。

    库能够是mysqlclient C客户端库,或mysqld嵌入式server库。详细情况取决于应用程序是否与“-libmysqlclient”或“-libmysqld”标志链接。

    2.    通过调用mysql_init()初始化连接处理程序。并通过调用mysql_real_connect()连接到server。

    3.    发出SQL语句并处理其结果。

    (在以下的讨论中,具体介绍了使用它的方法)。

    4.    通过调用mysql_close()。关闭与MySQLserver的连接。

    5.    通过调用mysql_library_end()。结束MySQL库的使用。

    调用mysql_library_init()mysql_library_end()的目的在于。为MySQL库提供恰当的初始化和结束处理。

    对于与client库链接的应用程序,它们提供了改进的内存管理功能。假设不调用mysql_library_end(),内存块仍将保持分配状态(这不会添加应用程序使用的内存量,但某些内存泄漏检測器将抗议它)。对于与嵌入式server链接的应用程序,这些调用会启动并停止server。

    mysql_library_init()mysql_library_end()实际上是#define符号,这类符号使得它们等效于mysql_server_init()mysql_server_end()。但其名称更清楚地指明,不管应用程序使用的是mysqlclientmysqld库,启动或结束MySQL库时,应调用它们。

    对于早期的MySQL版本号。可调用mysql_server_init()mysql_server_end()取而代之。

    假设愿意,可省略对mysql_library_init()的调用。这是由于,必要时,mysql_init()会自己主动调用它。

    要想连接到server。可调用mysql_init()来初始化连接处理程序,然后用该处理程序(以及其它信息,如主机名、username和password)调用mysql_real_connect()。建立连接后,在低于5.0.3版的API中。mysql_real_connect()会将再连接标志(MYSQL结构的一部分)设置为1,或在较新的版本号中,将其设置为0。对于该标志。值“1”指明,假设因连接丢失而无法运行语句,放弃之前,会尝试再次连接到server。

    MySQL 5.0.13開始,能够在mysql_options()上使用MYSQL_OPT_RECONNECT选项。以控制再连接行为。完毕连接后。调用mysql_close()中止它。

    当连接处于活动状态时。client也许会使用mysql_query()mysql_real_query()向server发出SQL查询。两者的区别在于。mysql_query()预期的查询为指定的、由Null终结的字符串。而mysql_real_query()预期的是计数字符串。假设字符串包括二进制数据(当中可能包括Null字节)。就必须使用mysql_real_query()

    对于每一个非SELECT查询(比如INSERTUPDATEDELETE)。通过调用mysql_affected_rows()。可发现有多少行已被改变(影响)。

    对于SELECT查询,可以检索作为结果集的行。

    注意,某些语句因其返回行,类似与SELECT

    包含SHOWDESCRIBEEXPLAIN

    应依照对待SELECT语句的方式处理它们。

    client处理结果集的方式有两种。一种方式是,通过调用mysql_store_result()。一次性地检索整个结果集。该函数能从server获得查询返回的全部行。并将它们保存在client。另外一种方式是针对client的。通过调用mysql_use_result(),对“按行”结果集检索进行初始化处理。该函数能初始化检索结果。但不能从server获得不论什么实际行。

    在这两种情况下,均能通过调用mysql_fetch_row()訪问行。

    通过mysql_store_result()mysql_fetch_row()可以訪问曾经从server获得的行。

    通过mysql_use_result()mysql_fetch_row()可以实际地检索来自server的行。通过调用mysql_fetch_lengths(),能获得关于各行中数据大小的信息。

    完毕结果集操作后。请调用mysql_free_result()释放结果集使用的内存。

    这两种检索机制是互补的。

    client程序应选择最能满足其要求的方法。实际上,client最常使用的是mysql_store_result()

    mysql_store_result()1个长处在于,因为将行所有提取到了client上,你不仅能连续訪问行。还能使用mysql_data_seek()mysql_row_seek()在结果集中向前或向后移动,以更改结果集内当前行的位置。通过调用mysql_num_rows(),还能发现有多少行。还有一方面。对于大的结果集。mysql_store_result()所需的内存可能会非常大。你非常可能遇到内存溢出状况。

    mysql_use_result()1个长处在于,client所需的用于结果集的内存较少,原因在于。一次它仅维护一行(因为分配开销较低,mysql_use_result()能更快)。它的缺点在于,你必须高速处理每一行以避免妨碍server,你不能随机訪问结果集中的行(仅仅能连续訪问行),你不知道结果集中有多少行,直至所有检索了它们为止。不仅如此,即使在检索过程中你判定已找到所寻找的信息,也必须检索所有的行。

    通过API,client可以恰当地对查询作出响应(仅在必要时检索行),而无需知道查询是否是SELECT查询。可以在每次mysql_query()mysql_real_query()后,通过调用mysql_store_result()完毕该操作。假设结果集调用成功,查询为SELECT,并且可以读取行。假设结果集调用失败,可调用mysql_field_count()来推断结果是否的确是所预期的。

    假设mysql_field_count()返回0,查询不返回数据(表明它是INSERTUPDATEDELETE等),并且不返回行。假设mysql_field_count()是非0值,查询应返回行。但没有返回行。这表明查询是失败了的SELECT。关于怎样实现该操作的演示样例,请參见关于mysql_field_count()的介绍。

    不管是mysql_store_result()还是mysql_use_result(),均同意你获取关于构成结果集的字段的信息(字段数目。它们的名称和类型等)。通过反复调用mysql_fetch_field()。能够按顺序訪问行内的字段信息,或者,通过调用mysql_fetch_field_direct()。能够在行内按字段编号訪问字段信息。

    通过调用mysql_field_seek(),能够改变当前字段的光标位置。对字段光标的设置将影响兴许的mysql_fetch_field()调用。

    此外,你也能通过调用mysql_fetch_fields(),一次性地获得关于字段的全部信息。

    为了检測和通报错误,MySQL提供了使用mysql_errno()mysql_error()函数訪问错误信息的机制。它们能返回关于近期调用的函数的错误代码或错误消息。近期调用的函数可能成功也可能失败,这样,你就能推断错误是在何时出现的,以及错误是什么。

    4 C API使用演示样例

    4.1 连接数据库  

    /*练习mysql数据库的连接*/  
    #include <stdio.h> 
    #include <mysql.h>  
      
    int main()  
    {  
        MYSQL mysql;  
        int t, r;  
        /*连接之前。先用mysql_init初始化MYSQL连接句柄*/  
        mysql_init(&mysql);  
        /*使用mysql_real_connect连接server,其參数依次为MYSQL句柄。serverIP地址。 
        登录mysql的username,password,要连接的数据库等*/  
        if(!mysql_real_connect(&mysql, "localhost", "root", "6748355", "spytest", 0, NULL, 0))   
            printf("Error connecting to Mysql!
    ");  
        else  
            printf("Connected Mysql successful!
    ");  
          
        /*关闭连接*/  
        mysql_close(&mysql);  
        return 0;  
    }

     

    4.2 数据库查询

    /*练习mysql数据库的查询*/  
    #include <stdio.h>  
    #include <string.h>  
    #include "mysql.h"  
      
      
    int main()  
    {  
        MYSQL mysql;  
        MYSQL_RES *res;  
        MYSQL_ROW row;  
        char *query;  
        int flag, t;  
        mysql_init(&mysql);  
        if(!mysql_real_connect(&mysql, "localhost", "root", "6748355", "spytest", 0, NULL, 0)) {  
            printf("Failed to connect to Mysql!
    ");  
            return 0;  
        }else {  
            printf("Connected to Mysql successfully!
    ");  
        }  
        query = "select * from log";  
        /*查询,成功则返回0*/  
        flag = mysql_real_query(&mysql, query, (unsigned int)strlen(query));  
        if(flag) {  
            printf("Query failed!
    ");  
            return 0;  
        }else {  
            printf("[%s] made...
    ", query);  
        }  
      
      
        /*mysql_store_result讲所有的查询结果读取到client*/  
        res = mysql_store_result(&mysql);  
        /*mysql_fetch_row检索结果集的下一行*/  
        while(row = mysql_fetch_row(res)) {  
            /*mysql_num_fields返回结果集中的字段数目*/  
            for(t=0; t<mysql_num_fields(res); t++)  
            {  
                printf("%s	", row[t]);  
            }  
            printf("
    ");  
        }  
        mysql_close(&mysql);  
        return 0;  
    }  


    4.3 数据库插入数据

    /*练习mysql数据库的数据加入*/  
    #include <stdio.h>  
    #include <string.h>  
    #include "mysql.h"  
      
      
    int main()  
    {  
        MYSQL mysql;  
        MYSQL_RES *res;  
        MYSQL_ROW row;  
        char *query;  
        int flag, t;  
        mysql_init(&mysql);  
        if(!mysql_real_connect(&mysql, "localhost", "root", "6748355", "spytest", 0, NULL, 0)) {  
            printf("Failed to connect to Mysql!
    ");  
            return 0;  
        }else {  
            printf("Connected to Mysql successfully!
    ");  
        }  
        query = "insert into log(title, keyword, content) values('sleep', 'rest', 'I have a dream')";  
        /*插入,成功则返回0*/  
        flag = mysql_real_query(&mysql, query, (unsigned int)strlen(query));  
        if(flag) {  
            printf("Insert data failure!
    ");  
            return 0;  
        }else {  
            printf("Insert data success!
    ");  
        }  
      
      
        mysql_close(&mysql);  
        return 0;  
    }  

    4.4 数据库删除

    /*练习mysql数据库的删除*/  
    #include <stdio.h>  
    #include <string.h>  
    #include "mysql.h"  
      
    int main()  
    {  
        MYSQL mysql;  
        MYSQL_RES *res;  
        MYSQL_ROW row;  
        char *query;  
        int flag, t;  
        mysql_init(&mysql);  
        if(!mysql_real_connect(&mysql, "localhost", "root", "6748355", "spytest", 0, NULL, 0)) {  
            printf("Failed to connect to Mysql!
    ");  
            return 0;  
        }else {  
            printf("Connected to Mysql successfully!
    ");  
        }  
        query = "delete from log where log_id=3";  
        /*删除,成功则返回0*/  
        flag = mysql_real_query(&mysql, query, (unsigned int)strlen(query));  
        if(flag) {  
            printf("Delete data failure!
    ");  
            return 0;  
        }else {  
            printf("Delete data success!
    ");  
        }  
      
        mysql_close(&mysql);  
        return 0;  
    }  


  • 相关阅读:
    2021.1.20 学习总结
    2021.1.19 学习总结
    2021.1.18 学习总结
    学习总结13
    学习总结12
    学习总结11
    学习总结10
    ASP.NET网站开发步骤
    学习总结9
    阅读笔记4
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6731515.html
Copyright © 2020-2023  润新知