Linux下C與Mysql的混合編程

1 概述

  MySQL 是一個關係型數據庫管理系統。由瑞典MySQL AB公司開發,眼下屬於Oracle公司。MySQL是最流行的關係型數據庫管理系統。node

   支持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等。mysql

 

2 安裝mysql

2.1 經過網絡安裝mysql

2.1.1 檢查是否已經安裝mysql

      # rpm -qa | grep mysql sql

         // 上述命令就會查看該操做系統上是否已經安裝了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-devesocket

      經過輸入 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!\n");  
    else  
        printf("Connected Mysql successful!\n");  
      
    /*關閉鏈接*/  
    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!\n");  
        return 0;  
    }else {  
        printf("Connected to Mysql successfully!\n");  
    }  
    query = "select * from log";  
    /*查詢,成功則返回0*/  
    flag = mysql_real_query(&mysql, query, (unsigned int)strlen(query));  
    if(flag) {  
        printf("Query failed!\n");  
        return 0;  
    }else {  
        printf("[%s] made...\n", 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\t", row[t]);  
        }  
        printf("\n");  
    }  
    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!\n");  
        return 0;  
    }else {  
        printf("Connected to Mysql successfully!\n");  
    }  
    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!\n");  
        return 0;  
    }else {  
        printf("Insert data success!\n");  
    }  
  
  
    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!\n");  
        return 0;  
    }else {  
        printf("Connected to Mysql successfully!\n");  
    }  
    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!\n");  
        return 0;  
    }else {  
        printf("Delete data success!\n");  
    }  
  
    mysql_close(&mysql);  
    return 0;  
}  
相關文章
相關標籤/搜索