[原創] Xcode中使用sqlite3訪問數據庫


  最近開始寫博客了,把我學習到的東西進行匯總和總結,今天就說說怎么使用sqlite3來操縱數據庫吧   

  數據庫的相關知識我就不去說明了,畢竟只要會sql語言的人就大家都一樣。

  本案例是在Xcode環境下創建的single view application進行演示操作,如有不清楚的朋友可以找我下載代碼。qq:1750587828.

  首先第一點,為什么要使用sqlite3?   

  在iOS的編程中,毫無疑問接觸最多的就是界面的代碼編排和設計,數據的解析與放置,算法的各種撓頭問題。。。   在數據的解析與放置這一塊,就會涉及到數據庫緩存的操作,我們都知道,iOS手機編程是在手機端運行的,你不能老是去服務器端讀取數據啊,好,就算你不煩,手機也跑的起來,流量不要過啊,對於手機控或者應用使用者來說,流量就是生命,而且,如果總是去服務器端讀取數據,對手機的運行速度也會有影響,畢竟有一個網絡傳輸的過程,所以,為了讓用戶有一個更好的體驗,一般建議的做法是,將服務器的數據進行下載,然后通過數據庫緩存起來,這樣就不用每次每次的去請求服務器數據了,如果在數據庫中有的數據,直接可以通過數據庫查詢得到,而省去了一次甚至多次的服務器請求操作。而sqlite3就是提供了一種C語言的訪問數據庫的形式。之后我們的代碼會看到,其實sqlite3的語法可能比較難以理解,不過,我也會給大家來進行介紹的。      

  那么第二點,使用sqlite3的好處是什么?

  使用sqlite3的好處么,除開語法的各種蛋疼之外,訪問的速度還是會比FMDB快一些的。而且,隨着一步步的匯總和總結,你可以清晰的知道每一句sqlite3的語句的作用,而不是使用封裝好了的語句,只要用就可以了,但是不知道是為什么。我個人覺得,學習學習吧,還是要知其然,亦知其所以然這樣才能學的踏實。   

  第三點,讓我們來開始學習sqlite3的使用方式吧:  

  3.1 第一步,引入sqlite3庫,並在使用sqlite3的地方導入sqlite3.

   

  3.2 第二步,創建sqlite數據庫文件   

  sqlite3提供的是一種訪問操縱數據庫的形式,那么,如果想要使用sqlite3來訪問操縱數據庫,首先我們得先有個數據庫,下面就是一句代碼生成一個數據庫文件。

/*得到數據庫文件地址,這是一個拼接的地址字符串,是沙盒路徑下面的shop.sqlite文件,

這個文件名可以隨便取名字,后綴最好是db啊或者sqlite這種,用來表示這是一個數據庫文件*/

    NSString* filename=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"shop.sqlite"];

/*sqlite3_open是我們接觸到的第一條sqlite3語句,它的作用時打開數據庫連接,如果有數據庫文件就打開它,沒有就重新創建數據庫,這個方法有一個枚舉的返回值表示是否正常打開了數據庫,我用int的變量status去接收了這個值,后面會進行判斷。

sqlite3_open有兩個參數,第一個參數是數據庫文件的路徑,第二個參數是一個數據庫的引用,即一個sqlite3*類型的引用;

filename.UTF8String:filename本身是oc的字符串類型,但是sqlite3_open要求傳遞的是C類型的字符串,所以,使用UTF8String將oc的字符串類型轉換為C類型的字符串

*/

    int status=sqlite3_open(filename.UTF8String, &_shop);

    if(status == SQLITE_OK)//枚舉值SQLITE_OK,代表成功的狀態

    {

    NSLog(@"打開數據庫成功");

  }

    else

           NSLog(@"打開數據庫失敗");

 

  3.3 創建數據庫表

  當我們打開了數據庫連接的時候,表示在程序的沙盒路徑下已經創建了一個shop.sqlite的數據庫文件,而這個數據庫里現在什么東西都沒有,我們需要創建一張數據庫表來存放數據。在這里我就封裝一個setupTable來進行創建表的操作。

-(void) setupTable
{

     //創表語句,IF NOT EXISTS防止創建重復的表,AUTOINCREMENT是自動增長關鍵字,real是數字類型

        const char * sql="CREATE TABLE IF NOT EXISTS t_shop(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,price real);";

        //保存錯誤信息的變量

        char * errMsg=NULL;

    /*sqlite3_exec是我們接觸到的第二個sqlite3語句,這個語句用於執行除了查詢語句以外的其他語句.

    它有一個枚舉類型的返回值,和sqlite3_open返回的枚舉值一致,這里我並沒有使用變量保存,因為我有其他形式來獲得創建表是否成功。

    sqlite3_exec需要傳遞5個參數,第一個參數是數據庫引用即sqlite3* _shop,第二個參數是要執行的sql語句,

    第三個參數是執行完sql語句后要執行的函數,第四個參數是執行完sql語句后要執行的函數的參數,第五個參數是執行完sql語句后的報錯信息。

  */

        sqlite3_exec(_shop, sql, NULL, NULL, &errMsg);

        if(errMsg)//如果存在報錯信息,代表語句執行失敗,比判斷枚舉值要更簡單一些

        {

            NSLog(@"創建表shop失敗-%s",errMsg);//打印錯誤信息

        }

}

 

  3.4 封裝數據庫連接和創建數據庫表

-(void)setupDB

{

    //得到數據庫文件地址

    NSString* filename=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"shop.sqlite"];

    //NSLog(@"%@",filename);

    //打開數據庫連接,如果有就打開,沒有就重新創建連接

    int status=sqlite3_open(filename.UTF8String, &_shop);

    

    if(status == SQLITE_OK)

    {

        NSLog(@"打開數據庫成功");

        //創表語句

        [self setupTable];

    }

    else

    {

        NSLog(@"打開數據庫失敗");

    }

}

  3.5 數據表操縱

  所謂的數據表操縱即是對數據表中數據的增刪改,也是最經常會使用到的功能。即執行insert,update,delete語句。

- (IBAction)add:(id)sender {//這里是一個按鈕的點擊提供的新增功能

    /*拼接插入數據的sql語句*/

    NSString * sql=[NSString stringWithFormat:@"INSERT INTO t_shop(name,price) VALUES('%@',%f)",self.name.text,self.price.text.doubleValue];

    char* errMsg=NULL;

    sqlite3_exec(self.shop, sql.UTF8String, NULL, NULL, &errMsg);

    

    if(errMsg)

    {

        NSLog(@"插入數據失敗--%s",errMsg);

    }

}

 

-(void)updateData//這里是一個方法提供了更新功能

{

 //拼接sql更新語句

    NSString * sql=[NSString stringWithFormat:@"update t_shop set name='%@',price='%@' where id=%@",self.name.text,self.price.text,self.lbl.text];

    //NSLog(@"%@",sql);

    char* errMsg=NULL;

    sqlite3_exec(self.myShop, sql.UTF8String, NULL, NULL, &errMsg);

    if(errMsg)

    {

        NSLog(@"更新數據失敗--%s",errMsg);

    }

}

 

-(void)deleteDataById:(int)pid

{//提供一個方法執行刪除操作,該方法要求得到要刪除的數據的id

  //拼接sql刪除語句

    NSString * sql=[NSString stringWithFormat:@"DELETE FROM t_shop where id=%d",pid];

    char* errMsg=NULL;

    sqlite3_exec(self.shop, sql.UTF8String, NULL, NULL, &errMsg);

    if(errMsg)

    {

        NSLog(@"刪除數據失敗--%s",errMsg);

    }

}

  大家可以觀察上面的三個方法,會發現除了sql語句的拼接不一樣以外,其他的地方幾乎一模一樣,所以,增刪改的操作相對來說還是比較簡單的。

 

  3.6 查詢數據 

/**

 *  查詢數據

 */

-(void)setupData

{

    const char * sql="select * from t_shop";//查詢sql語句

    //stmt用來取出查詢結果

    sqlite3_stmt *stmt=NULL;

    /*sqlite3_prepare_v2函數是准備要執行sql查詢的一個函數,可以當做這個函數就是用來做sql查詢之前的准備工作的,

  它也是返回一個枚舉作為准備工作的結果,SQLITE_OK則代表准備工作ok

  sqlite3_prepare_v2需要傳入5個參數,第一個參數是數據庫引用即(sqlite3* _shop),第二個參數是要執行的sql語句,第三個參數是sql語句的長度

  第四個參數是查詢結果stmt的引用,查詢完成后,查詢結果將會存入該引用,第五個參數是指向無法使用的部分的指針,一般不會用到,給NULL就可以了

  */

    int status = sqlite3_prepare_v2(_shop, sql, -1, &stmt, NULL);

    if(status == SQLITE_OK)//准備成功,SQL語句正確

    {

  /*sqlite3_step(stmt)函數將會執行查詢並且將查詢到的當前記錄存入到stmt(sqlite3_stmt * 類型)中

    第一次執行sqlite3_step(stmt)將會將表中的第一條數據存入到stmt中,第二次執行sqlite3_step(stmt)將會把表中的第二條記錄存入到stmt中

  也就是說,while(sqlite3_step(stmt)==SQLITE_ROW)將會一條一條的去讀取表中的記錄,而SQLITE_ROW枚舉判斷的是有讀取到數據行的情況*/

        while(sqlite3_step(stmt) == SQLITE_ROW)//成功指向一條記錄

        {

            Shop* shop=[[Shop alloc]init];//封裝的實體

    /*sqlite3_column_xxxx函數:它用來讀取數據行中不同類型的數據,該函數的返回值就是讀取到得數據內容,

      該函數需要2個參數,第一個參數是存放數據的stmt,第二個參數是數據列下標*/

            shop.pid= sqlite3_column_int(stmt, 0);//讀取stmt中存儲的第0列數據

            const char* pname= (const char*)sqlite3_column_text(stmt, 1);//讀取stmt中存儲的第1列數據

            const char* pprice = (const char*)sqlite3_column_text(stmt, 2);//讀取stmt中存儲的第2列數據

            shop.name = [NSString stringWithUTF8String:pname];//將C類型的字符串轉換為oc類型的字符串並存儲

            shop.price = [NSString stringWithUTF8String:pprice];//將C類型的字符串轉換為oc類型的字符串並存儲

            //NSLog(@"編號:%d,商品名:%s,價格:%s",shop.pid,pname,pprice);

        }

    }

}

 

  那么,寫到這里,相信大家對sqlite3的基本使用已經有了大致的了解,如果對代碼中有不理解的地方,或者有其他相關的問題,可以找我一起來研究討論。

  第一次發博客,希望大家提出寶貴的意見和建議,編程路上,與你同行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM