最近開始寫博客了,把我學習到的東西進行彙總和總結,今天就說說怎麼使用sqlite3來操縱數據庫吧 算法
數據庫的相關知識我就不去說明了,畢竟只要會sql語言的人就你們都同樣。sql
本案例是在Xcode環境下建立的single view application進行演示操做,若有不清楚的朋友能夠找我下載代碼。qq:1750587828.數據庫
首先第一點,爲何要使用sqlite3? 編程
在iOS的編程中,毫無疑問接觸最多的就是界面的代碼編排和設計,數據的解析與放置,算法的各類撓頭問題。。。 在數據的解析與放置這一塊,就會涉及到數據庫緩存的操做,咱們都知道,iOS手機編程是在手機端運行的,你不能總是去服務器端讀取數據啊,好,就算你不煩,手機也跑的起來,流量不要過啊,對於手機控或者應用使用者來講,流量就是生命,並且,若是老是去服務器端讀取數據,對手機的運行速度也會有影響,畢竟有一個網絡傳輸的過程,因此,爲了讓用戶有一個更好的體驗,通常建議的作法是,將服務器的數據進行下載,而後經過數據庫緩存起來,這樣就不用每次每次的去請求服務器數據了,若是在數據庫中有的數據,直接能夠經過數據庫查詢獲得,而省去了一次甚至屢次的服務器請求操做。而sqlite3就是提供了一種C語言的訪問數據庫的形式。以後咱們的代碼會看到,其實sqlite3的語法可能比較難以理解,不過,我也會給你們來進行介紹的。 緩存
那麼第二點,使用sqlite3的好處是什麼?服務器
使用sqlite3的好處麼,除開語法的各類蛋疼以外,訪問的速度仍是會比FMDB快一些的。並且,隨着一步步的彙總和總結,你能夠清晰的知道每一句sqlite3的語句的做用,而不是使用封裝好了的語句,只要用就能夠了,可是不知道是爲何。我我的以爲,學習學習吧,仍是要知其然,亦知其因此然這樣才能學的踏實。 網絡
第三點,讓咱們來開始學習sqlite3的使用方式吧: app
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的基本使用已經有了大體的瞭解,若是對代碼中有不理解的地方,或者有其餘相關的問題,能夠找我一塊兒來研究討論。
第一次發博客,但願你們提出寶貴的意見和建議,編程路上,與你同行。