日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

IOS操作数据库总结

發布時間:2025/4/14 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IOS操作数据库总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

iOS學習筆記-數據庫操作(使用FMDB)

? ? ? ? ?iOS中原生的SQLite API在使用時,非常不便。于是,就出現了一系列將SQLite API進行封裝的庫,例如FMDB、


PlausibleDatabase、sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款簡潔、易用的封裝庫,這一篇文章


簡單介紹下FMDB的使用。
在FMDB下載文件后,工程中必須導入如下文件,并使用 libsqlite3.dylib 依賴包。


FMDB同時兼容ARC和非ARC工程,會自動根據工程配置來調整相關的內存管理代碼。
FMDB常用類:
FMDatabase : 一個單一的SQLite數據庫,用于執行SQL語句。
FMResultSet :執行查詢一個FMDatabase結果集,這個和android的Cursor類似。
FMDatabaseQueue :在多個線程來執行查詢和更新時會使用這個類。


創建數據庫:


db = [FMDatabase databaseWithPath:database_path]; ?


? ? ? ? ?1、當數據庫文件不存在時,fmdb會自己創建一個。
? ? ? ? ?2、 如果你傳入的參數是空串:@"" ,則fmdb會在臨時文件目錄下創建這個數據庫,數據庫斷開連接時,數據庫文件被刪除。
? ? ? ? ?3、如果你傳入的參數是 NULL,則它會建立一個在內存中的數據庫,數據庫斷開連接時,數據庫文件被刪除。


打開數據庫:
[db open] ?


返回BOOL型。
關閉數據庫:
[db close] ?


數據庫增刪改等操作:
除了查詢操作,FMDB數據庫操作都執行executeUpdate方法,這個方法返回BOOL型。


看一下例子:
創建表:
if ([db open]) { ?
? ? ? ? NSString *sqlCreateTable = ?[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('%@' INTEGER PRIMARY?


KEY AUTOINCREMENT, '%@' TEXT, '%@' INTEGER, '%@' TEXT)",TABLENAME,ID,NAME,AGE,ADDRESS]; ?
? ? ? ? BOOL res = [db executeUpdate:sqlCreateTable]; ?
? ? ? ? if (!res) { ?
? ? ? ? ? ? NSLog(@"error when creating db table"); ?
? ? ? ? } else { ?
? ? ? ? ? ? NSLog(@"success to creating db table"); ?
? ? ? ? } ?
? ? ? ? [db close]; ?
??
? ? } ?




添加數據:
if ([db open]) { ?
? ? ? ?NSString *insertSql1= [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TABLENAME, NAME, AGE, ADDRESS, @"張三", @"13", @"濟南"]; ?
? ? ? ?BOOL res = [db executeUpdate:insertSql1]; ?
? ? ? ?NSString *insertSql2 = [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TABLENAME, NAME, AGE, ADDRESS, @"李四", @"12", @"濟南"]; ?
? ? ? ?BOOL res2 = [db executeUpdate:insertSql2]; ?
? ? ? ? ?
? ? ? ?if (!res) { ?
? ? ? ? ? ?NSLog(@"error when insert db table"); ?
? ? ? ?} else { ?
? ? ? ? ? ?NSLog(@"success to insert db table"); ?
? ? ? ?} ?
? ? ? ?[db close]; ?
??
? ?} ?




修改數據:
if ([db open]) { ?
? ? ? ? NSString *updateSql = [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@"UPDATE '%@' SET '%@' = '%@' WHERE '%@' = '%@'", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TABLENAME, ? AGE, ?@"15" ,AGE, ?@"13"]; ?
? ? ? ? BOOL res = [db executeUpdate:updateSql]; ?
? ? ? ? if (!res) { ?
? ? ? ? ? ? NSLog(@"error when update db table"); ?
? ? ? ? } else { ?
? ? ? ? ? ? NSLog(@"success to update db table"); ?
? ? ? ? } ?
? ? ? ? [db close]; ?
??
? ? } ?




刪除數據:
if ([db open]) { ?
? ? ? ? ??
? ? ? ? NSString *deleteSql = [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@"delete from %@ where %@ = '%@'", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TABLENAME, NAME, @"張三"]; ?
? ? ? ? BOOL res = [db executeUpdate:deleteSql]; ?
? ? ? ? ??
? ? ? ? if (!res) { ?
? ? ? ? ? ? NSLog(@"error when delete db table"); ?
? ? ? ? } else { ?
? ? ? ? ? ? NSLog(@"success to delete db table"); ?
? ? ? ? } ?
? ? ? ? [db close]; ?
??
? ? } ?




數據庫查詢操作:
查詢操作使用了executeQuery,并涉及到FMResultSet。
if ([db open]) { ?
? ? ? ? NSString * sql = [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? @"SELECT * FROM %@",TABLENAME]; ?
? ? ? ? FMResultSet * rs = [db executeQuery:sql]; ?
? ? ? ? while ([rs next]) { ?
? ? ? ? ? ? int Id = [rs intForColumn:ID]; ?
? ? ? ? ? ? NSString * name = [rs stringForColumn:NAME]; ?
? ? ? ? ? ? NSString * age = [rs stringForColumn:AGE]; ?
? ? ? ? ? ? NSString * address = [rs stringForColumn:ADDRESS]; ?
? ? ? ? ? ? NSLog(@"id = %d, name = %@, age = %@ ?address = %@", Id, name, age, address); ?
? ? ? ? } ?
? ? ? ? [db close]; ?
? ? } ?


FMDB的FMResultSet提供了多個方法來獲取不同類型的數據:




數據庫多線程操作:
? ? ? ? 如果應用中使用了多線程操作數據庫,那么就需要使用FMDatabaseQueue來保證線程安全了。 應用中不可在多個線程中共同使


用一個FMDatabase對象操作數據庫,這樣會引起數據庫數據混亂。 為了多線程操作數據庫安全,FMDB使用了FMDatabaseQueue,使用


FMDatabaseQueue很簡單,首先用一個數據庫文件地址來初使化FMDatabaseQueue,然后就可以將一個閉包(block)傳入inDatabase方法中


。 在閉包中操作數據庫,而不直接參與FMDatabase的管理。


FMDatabaseQueue * queue = [FMDatabaseQueue databaseQueueWithPath:database_path]; ?
? ?dispatch_queue_t q1 = dispatch_queue_create("queue1", NULL); ?
? ?dispatch_queue_t q2 = dispatch_queue_create("queue2", NULL); ?
? ? ?
? ?dispatch_async(q1, ^{ ?
? ? ? ?for (int i = 0; i < 50; ++i) { ?
? ? ? ? ? ?[queue inDatabase:^(FMDatabase *db2) { ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?NSString *insertSql1= [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES (?, ?, ?)", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TABLENAME, NAME, AGE, ADDRESS]; ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?NSString * name = [NSString stringWithFormat:@"jack %d", i]; ?
? ? ? ? ? ? ? ?NSString * age = [NSString stringWithFormat:@"%d", 10+i]; ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?BOOL res = [db2 executeUpdate:insertSql1, name, age,@"濟南"]; ?
? ? ? ? ? ? ? ?if (!res) { ?
? ? ? ? ? ? ? ? ? ?NSLog(@"error to inster data: %@", name); ?
? ? ? ? ? ? ? ?} else { ?
? ? ? ? ? ? ? ? ? ?NSLog(@"succ to inster data: %@", name); ?
? ? ? ? ? ? ? ?} ?
? ? ? ? ? ?}]; ?
? ? ? ?} ?
? ?}); ?
? ? ?
? ?dispatch_async(q2, ^{ ?
? ? ? ?for (int i = 0; i < 50; ++i) { ?
? ? ? ? ? ?[queue inDatabase:^(FMDatabase *db2) { ?
? ? ? ? ? ? ? ?NSString *insertSql2= [NSString stringWithFormat: ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES (?, ?, ?)", ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TABLENAME, NAME, AGE, ADDRESS]; ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?NSString * name = [NSString stringWithFormat:@"lilei %d", i]; ?
? ? ? ? ? ? ? ?NSString * age = [NSString stringWithFormat:@"%d", 10+i]; ?
? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?BOOL res = [db2 executeUpdate:insertSql2, name, age,@"北京"]; ?
? ? ? ? ? ? ? ?if (!res) { ?
? ? ? ? ? ? ? ? ? ?NSLog(@"error to inster data: %@", name); ?
? ? ? ? ? ? ? ?} else { ?
? ? ? ? ? ? ? ? ? ?NSLog(@"succ to inster data: %@", name); ?
? ? ? ? ? ? ? ?} ?
? ? ? ? ? ?}]; ?
? ? ? ?} ?
? ?}); ?
demo下載
http://blog.csdn.net/xyz_lmn


ios 上 sqlite的第三方封裝庫介紹
https://github.com/ccgus/fmdb
========

Delphi for iOS開發指南-在iOS客戶端應用程序中連接企業級數據庫



這篇教程描述了在iOS客戶端應用程序中連接企業級數據庫。(Delphi)


要連接到企業級數據庫,你需要一個客戶端的庫。在多數情況下,客戶端庫由數據庫供應商以DLL文件格式提供。這個方式不能在iOS?


Device上運行,因為沒有可用的客戶端庫。要解決這個問題,你可以開發一個中間層來連接到一個企業級數據庫,你的iOS應用程序可以


與這個中間層會話。


RAD Studio提供DataSnap框架來讓你不需要寫代碼就能夠開發這個中間層(并且訪問這個中間層)。這篇教程描述了開發這個中間層,


以及開發iOS客戶端的步驟。
?
創建中間層,一個DataSnap Server


首先,創建一個DataSnap Server,從數據庫數據器導出一個表。這篇教程使用一個DataSnap Server VCL Forms Application作為


DataSnap Server。


注:在這篇教程中,DataSnap Server(VCL應用程序)在多層數據庫應用程序中作為中間層。你可以輕松創建并刪除一個DataSnap?


Server。在你理解這些基本步驟之后中,你可以將這個中間層轉換成Windows服務程序。


創建一個DataSnap Server VCL Application
?
1. 創建一個新的工程。選擇File>New>Other,然后從New Items對話框中選擇Delphi Projects>Data Snap Server>DataSnap Server來


創建一個新的Delphi工程。


2.彈出New DataSnap Server向導,你需要按照這些步驟,不需要修改太多參數。


在New DataSnap Server向導中:
? ? ? ? 1. 第一步,選擇VCL Forms Application作為應用程序類型。
? ? ? ? 2. 第二步,選擇TCP/IP協議,Server Methods Class,和Sample Methods。
? ? ? ? 3.第三步,保持默認的TCP/IP通訊端口為211。這會保證客戶端和服務端的通訊通過默認的DataSnap端口。
? ? ? ? 4. 最后一步(第四)選擇TDSServerModule作為Server Methods的父類。
3. 保存窗體單元為DataSnapServerUnit.pas。
4. 切換到DataSnapServerUnit,更改窗體的Name屬性為DSServerForm。
5. 保存Server Mothods單元(向導默認創建為:ServerMethodsUnit1)為ServerModuleUnit.pas。
6. 保存Server Containter單元(向導默認創建為:ServerContainerUnit1)為ServerContainerUnit.pas。
7. 保存新的工程為DataSnapServerProject.droj。
8. 在Project Manager中選擇ProjectGroup1,然后保存這個工程為DataSnapTutorialProjectGroup.groupproj。


在DataSnap Server上定義一個數據集
?
1. 切換到ServerContainerUnit.pas文件,然后替換在Implementation中的Uses子句為:uses Winapi.Windows, ServerModuleUnit;
2.切換到ServerModuleUnit.pas文件。
3.在Form Designer中,更改Server Module的Name屬性為DSServerModule_EMPLOYEE。
4.在Server Module上配置如下組件:
.拖放一個TSQLConnection組件在Server Module,然后設置如下屬性:


TSQLConnection封裝了一個數據庫服務器的dbExpress連接。
.設置Name屬性為SQLConnection_EMPLOYEE。
.設置LoginPrompt屬性為False。
.設置Driver為InterBase。
.展開Drive節點,設置DataBase屬性為C:\Users\Public\Documents\RAD Studio\11.0\Samples\Data\EMPLOYEE.GDB。
.更改Connected屬性為True。如果你遇到一個錯誤,再次檢查一下Driver屬性。
.拖放一個TSQLDataSet組件到Server Module上,設置如下屬性:


TSQLDataSet用來連接使用dbExpress接收到的數據。
.設置Name屬性為SQLDataSet_EMPLOYEE。
.設置SQLConnection屬性為SQLConnection_EMPLOYEE。
.設置CommandType屬性為ctTable。
.設置CommandText屬性為EMPLOYEE。
.更改Active屬性為Ture。如果你遇到一個錯誤,再次查檢你剛才配置過的屬性。
.拖放一個TDataSetProvider組件到Server Module上,然后設置如下屬性:
TDataSetProvider將一個數據集里面的數據打包,然后將這些可以傳輸的數據包到DataSnap客戶端。
.設置Name屬性為DataSetProvider_EMPLOYEE 。
.設置DataSet屬性為SQLDataSet_EMPLOYEE :


注:這篇教程使用InterBase作為例子。然而,你可以連接到任意數據庫服務器,使用相同的步驟。選擇合適的Driver,以及其他屬性指


向你的數據庫。


從DataSnap Server導出DataSet


你剛剛創建一個新的Server Module,包含一個DataSet和DataSetProvider(將數據打包傳遞給下一層)。下一步是導出這個Server?


Module到DataSnap Client。
1. 在Form Designer中,打開ServerContainerUnit。
2. 選擇DSServerClass1,然后更新已經存在的OnGetClass事件的事件處理過程。添加如下代碼到DSServerClass1的事件處理過程中:
?
[delphi]
procedure TServerContainer1.DSServerClass1GetClass(DSServerClass: TDSServerClass; ?
??
? var PersistentClass: TPersistentClass); ?
??
begin ?
??
? PersistentClass := TDSServerModule_EMPLOYEE; ?
??
end; ?
[delphi]
procedure TServerContainer1.DSServerClass1GetClass(DSServerClass: TDSServerClass; ?
??
? var PersistentClass: TPersistentClass); ?
??
begin ?
??
? PersistentClass := TDSServerModule_EMPLOYEE; ?
??
end; ?
?
使用這個事件處理過程,DataSnap Server會導出DataSetProvider,就像這個類中的公共方法一樣給一個DataSnap Client。基于上一節


你所做的,現在你要導出這個DataSetProvider_EMPLOYEE到你的DataSnap Client。


運行DataSnap Server


DataSnap Server的實現已經完成。右擊DataSnapServerProject.exe,然后選擇Run Without Debugging。
?
現在你可以看到DataSnap Server運行在你的Windows電腦上。因為這個DataSnap Server沒有任何界面元素,因此它是一個空窗體:


創建一個iOS應用程序連接到DataSnap Server


下一步,創建iOS客戶端應用程序
?
1.在Project Manager中,右擊DataSnapTutorialProjectGroup,然后選擇Add New Project。


2.在Delphi Projects頁選擇FireMonkey Mobile Application:
3.保存新的單元為DataSnapClientUnit.pas。
4.保存新的工程為DataSnapClientProject.droj。
5.打開DataSnapClientUnit,然后更改窗體的Name屬性為DSClientForm。
6.拖放以下組件到FireMonkey Mobile Form Designer上:
.TSQLConnection組件(SQLConenction1)
TSQLConnction封裝了一個與數據庫服務器的dbExpress連接。當然,它也支持DataSnap Server。
.設置Driver屬性為DataSnap。
.展開Driver屬性,然后設置HostName屬性為DataSnap Server的主機名。
.設置LoginPrompt屬性為False。
.設置Connected屬性為True。
如果你遇到一個錯誤,請再次檢查你剛設置的屬性。
.TDSProviderConnection組件(DSProviderConnection1)
TDSProviderConnection組件使用dbExpress提供與DataSnap Server的連接。
.設置SQLConnection屬性為SQLConnection1。
.設置ServerClassName為TDSServerModule_EMPLOYEE。這個名稱需要與DataSnap Server里的Server Module的類名匹配。
.設置Connected屬性為True。
.TClientDataSet組件(ClientDataSet1)
TClientDataSet實現了一個與數據庫無關的數據集,它可以用作一個其他數據集的本地內存緩沖。
.設置RemoteServer屬性為DSProviderConnection1。
.設置ProviderName屬性為DataSetProvider_EMPLOYEE。這個名稱需要與DataSnap Server里的DataSetProvider的名稱匹配。
.設置Active屬性為True。
.TListBox組件
.設置Align屬性為alClient。
7.打開LiveBindings Designer,按照下圖連接數據和用戶界面:
1. 點擊BindSourceDB1中的FULL_NAME,然后拖動鼠標指針到ListBox1的Item.Text上去:
2. 現在你已經創建并配置了一個在iOS上的DataSnap Client了。你應該能夠在IDE中看到從DataSnap Server中的數據了:


布署MIDAS庫到iOS Simulator


要在iOS Simulator中執行你的應用程序,你需要布置下列文件:
1.MIDAS庫
2.通過選擇Project>Deployment來打開Deployment Manager。
3.選擇Add Featured Files():
4.選擇如下模板,然后點擊OK,關閉Deployment Manager:
.MIDAS庫


在iOS模擬器,或iOS Device上運行你的應用程序


現在你的應用程序可以準備運行了。
在Project Manager中,選擇iOS Simulator或iOS Device作為目標平臺,然后運行你的應用程序。你應該可以瀏覽到數據。
http://blog.csdn.net/wei_wu49036233/article/category/1611027
========

iOS開發數據庫篇—SQL代碼應用示例



一、使用代碼的方式批量添加(導入)數據到數據庫中


1.執行SQL語句在數據庫中添加一條信息


插入一條數據的sql語句:


點擊run執行語句之后,刷新數據


2.在ios項目中使用代碼批量添加多行數據示例


  代碼示例:


復制代碼
//
// ?main.m
// ?01-為數據庫添加多行數據
//
// ?Created by apple on 14-7-26.
// ?Copyright (c) 2014年 wendingding. All rights reserved.
//


#import <Foundation/Foundation.h>


int main(int argc, const char * argv[])
{


? ? @autoreleasepool {
? ? ? ? NSArray *names=@[@"張一",@"張二",@"張三",@"張四"];
? ? ? ? NSMutableString *sql=[NSMutableString string];
? ? ? ??
? ? ? ? for (int i=0; i<200; i++) {
? ? ? ? ? ? int ID=i+1;
? ? ? ? ? ? //這里的警告為無符號類型轉換
? ? ? ? ? ? NSString *name=names[arc4random_uniform(names.count)];
? ? ? ? ? ? name=[name stringByAppendingFormat:@"-%d",arc4random_uniform(200)];
? ? ? ? ? ? //生成隨機數,范圍以20為中心上下波動10
? ? ? ? ? ? int age=arc4random_uniform(20)+10;
? ? ? ? ? ? [sql appendFormat:@"INSERT INTO t_student (id,name,age) VALUES (%d,'%@',%d);\n",ID,name,age];
? ? ? ? }
? ? ? ? //把sql寫入到文件中
? ? ? ? [sql writeToFile:@"/Users/apple/Desk/students.sql" atomically:YES encoding:NSUTF8StringEncoding error:nil];
? ? ? ? NSLog(@"\n%@",sql);
? ? ? ? }
? ? return 0;
}


作用:生成200條相應的sql插入語句


打印結果為:


使用文本編輯器,打開生成的sql文件。


可以把這些SQL語句拷貝到Navicat中進行執行,也可以直接執行整個文件。


在數據庫中創建一張表:


選擇執行SQL文件:


執行完畢后,點擊cancel。


刷新數據庫,查看插入的200條數據


二、分頁簡單演示


說明:


使用limit可以精確地控制查詢結果的數量,比如每次只查詢10條數據


格式 select * from 表名 limit 數值1, 數值2 ;


示例


select * from t_student limit 4, 8 ;


可以理解為:跳過最前面4條語句,然后取8條記錄


limit常用來做分頁查詢,比如每頁固定顯示5條數據,那么應該這樣取數據


第1頁:limit 0, 5


第2頁:limit 5, 5


第3頁:limit 10, 5





第n頁:limit 5*(n-1), 5


下面語句的作用


select * from t_student limit 7 ;


相當于select * from t_student limit 0, 7 ;表示取最前面的7條記錄


三、補充


1.關于外鍵約束(建立起兩張表之間的聯系)


第一種做法:可以新建一張關系表,讓之前兩張表(班級表和學生表建立起對應的聯系),但是這種做法很冗余,沒有必要


第二種做法:使用外鍵約束


一對一,一對多,多對多關系。當兩張表有聯系時,如何設置外鍵(在哪張表中設置?)


2.關于表連接


子查詢:要求查詢所有類型為粵菜的菜名。


查詢結果為:


連接查詢:


查詢結果為:
========

經典SQL語句大全

http://www.cnblogs.com/yubinfeng/archive/2010/11/02/1867386.html
?
1.常用語句


***SQL語句的預編譯:將語句轉為數據流,執行語句前檢查語句的語法,但不能知道語句是否能查出結果。此方法有返回值 ?預編譯成功


則返回SQLITE_OK----0否則返回SQLITE_ERROR----1
int sqlite3_prepare_v2(
? sqlite3 *db, ? ? ? ? ? ? ? ? //指向數據庫的指針
? const char *zSql, ? ? ? ? //SQL語句
? int nByte, ? ? ? ? ? ? ? ? ? //SQL語句的長度 (一般用-1,系統可以自動算出字符串得長度)
? sqlite3_stmt **ppStmt, //指向語句的指針
? const char **pzTail ? ? ? //SQL中沒有用到的一部分,一般為空
);
***SQL語句的值綁定。
*此類方法均有返回值 ?預編譯成功則返回SQLITE_OK----0否則返回SQLITE_ERROR----1
//對整數值的綁定
int sqlite3_bind_int(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int, ? ? ? ? ? ? ? ? ? ? ?//占位符的序號(從1開始以此類推)
int ? ? ? ? ? ? ? ? ? ? ? //綁定的值
);
//對字符串值的綁定
int sqlite3_bind_text(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int, ? ? ? ? ? ? ? ? ? ? ?//占位符的序號(從1開始以此類推)
const char*, ? ? ? ? ? ? ?//要綁定的值(這里要c類型的字符串(CString),一般我們使用的是oc的字符串(NSString*)要通過-?


(__strong const char *)UTF8String轉一下就可以了)
int n, ? ? ? ? ? ? ? ? ? ?//該字符串的長度(一般用-1,系統可以自動算出字符串得長度)
void(*)(void*) ? ? ? ? ? ?//回調函數(這里博主還沒用過所以不是很了解以后會慢慢更新)
);
//對二進制數據值的綁定
int sqlite3_bind_blob(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int, ? ? ? ? ? ? ? ? ? ? ?//占位符的序號(從1開始以此類推)
const void*, ? ? ? ? ? ? ?//要綁定的值(這里要的是c類型的比特(Byte),一般我們使用的是oc的NSDATA(NsData*)要通過-?


(const void *)bytes轉一下就可以了)
int n, ? ? ? ? ? ? ? ? ? ?//數據的長度(用- (NSUInteger)length得到 ?這里為什么不用-1呢?因為-1對于算字符串長度在行,其


他的不一定準所以這里我們手動算出數據的長度)
void(*)(void*) ? ? ? ? ? ?//回調函數(這里博主還沒用過所以不是很了解以后會慢慢更新)
);
***SQL語句的取值(從數據庫中對每一列取值)
//對整數字段的取值
int sqlite3_column_int(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int iCol ? ? ? ? ? ? ? ? ?//數據庫中表中列的序號(從0開始以此類推)
);
//對字符串字段的取值
*注意這里我們取得是無符號的c字符串我們要先轉為有符號C字符串再轉為OC字符串
例sname為oc字符串
NSString *sname=[NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];


const unsigned char *sqlite3_column_text(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int iCol ? ? ? ? ? ? ? ? ?//數據庫中表中列的序號(從0開始以此類推)
);
//對二進制字段的取值
*注意這里我們取得是c二進制我們要轉為oc二進制(我們要將byte(c)轉為nsdata(oc)通過+ (id)dataWithBytes:(const void *)


bytes length:(NSUInteger)length;因為這里需要數據的長度所以需要調用int sqlite3_column_bytes(sqlite3_stmt*, int iCol);獲


取數據的長度)

int length=sqlite3_column_bytes(stmt,3);//獲取二進制數據的長度
NSData *img=[NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:length]; //將二進制數據轉換位NSData對象
?
const void *sqlite3_column_blob(
sqlite3_stmt*, ? ? ? ? ? ?//指向語句的指針
int iCol ? ? ? ? ? ? ? ? ?//數據庫中表中列的序號(從0開始以此類推)
);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
******************************************新建一個類(Student*)
包含以下屬性
@property(retain,nonatomic)NSString*sname;
@property(assign,nonatomic)int sage;
@property(retain,nonatomic)NSData*simage;
@property(assign,nonatomic)int sid;
1.數據庫的全表查詢
+(NSMutableArray*) findall//返回表中所有記錄
{
? ? NSMutableArray* stuArray;//存儲查詢結果 ?在這里只聲明不開辟空間 等用的時候再開辟(節省空間)
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫 ?并且定義了一個指針sqlite指向dbpoint所指向的區域(數據庫)
? ? sqlite3_stmt *stmt=nil;//定義一個指向sql語句的指針對象
? ? int flag=sqlite3_prepare_v2(sqlite, "select * from tblstudent", -1, &stmt, nil);//調用預處理函數將sql語句賦值給stmt


對象 ?sqlite:數據庫 -1:系統自動算出要存的sql語句的長度(也可以自己給出) &stmt:一個指向sql語句的內存的地址 ?nil:sql


語句中沒有用到的一部分(一般為空) 返回值為一個int(宏)SQLITE_OK 0 ?SQLITE_ERROR 1
? ? if (flag==SQLITE_OK) //預編譯成功
? ? {
? ? ? ? stuArray=[[NSMutableArray alloc]init];//為數組開辟空間
? ? ? ? while (sqlite3_step(stmt)==SQLITE_ROW) //開始指向第一行的上面 判斷下一行是否存在(存在:做準備指針移到下一行)


(不存在:跳出循環)
? ? ? ? {
? ? ? ? ? ? int sid1=sqlite3_column_int(stmt, 0);//獲取表中當前行第一列的值
? ? ? ? ? ? int sage=sqlite3_column_int(stmt, 2);
? ? ? ? ? ? NSString *sname1=[NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];//獲取當前表中


當前行第二列的值
? ? ? ? ? ? //sqlite3_column_text(stmt, 1):返回的是一個無符號c字符串 ?(const char *)進行強轉為有符號c字符串 ?


stringWithUTF8String:將一個c字符串轉為nsstring類型
? ? ? ? ? ? int length=sqlite3_column_bytes(stmt,3);//獲取二進制數據的長度 sqlite3_column_bytes():獲取當前行某一列的


所占內存的字節數
? ? ? ? ? ? NSData *img1=[NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:length]; //將二進制數據轉換位NSData


對象
? ? ? ? ? ? //sqlite3_column_blob(stmt, 2):返回的是byte型(c) dataWithBytes:length:將(c)二進制轉為nsdata(oc)


? ? ? ? ? ? //定義一個(Student*)對象并將從數據庫取來的數據賦值給對象的相應屬性
? ? ? ? ? ? Student *stu=[[Student alloc]init];//實例化
? ? ? ? ? ? stu.sid=sid1;
? ? ? ? ? ? stu.sname=sname1;
? ? ? ? ? ? stu.simage=img1;
? ? ? ? ? ? stu.sage=sage;
? ? ? ? ? ? [stuArray addObject:stu];//將一個對象存入數組
? ? ? ? ? ? [stu release];//釋放對象
? ? ? ? }
? ? }
? ? sqlite3_finalize(stmt);//回收stmt對象
? ? return [stuArray autorelease];//返回包含學生信息的數組 ?并設為自動釋放
}
2.通過姓名或者學號查詢
*注意這里學號是主鍵所以肯定查回來是有唯一確定的(Student*)對象
+(Student*) findbysid:(int) sid
{
? ? Student *stu;//用于返回的學生對象
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫
? ? sqlite3_stmt *stmt=nil;//定義sql語句對象
? ? int flag=sqlite3_prepare_v2(sqlite, "select * from tblstudent where stuid=?", -1, &stmt, nil);//調用預處理函數將sql


語句賦值給stmt對象
? ? if (flag==SQLITE_OK)
? ? {
? ? ? ? sqlite3_bind_int(stmt, 1, sid);//給問號占位符賦值
? ? ? ? while (sqlite3_step(stmt)==SQLITE_ROW)//因為一個學號肯定對應一個學生所以這里其實只執行一次
? ? ? ? {
? ? ? ? ? ? //根據列順序(從零開始)
? ? ? ? ? ? int sid=sqlite3_column_int(stmt, 0);//取整型數據
? ? ? ? ? ? int sage=sqlite3_column_int(stmt, 2);
? ? ? ? ? ? NSString *sname=[NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];//取nsstring數據
? ? ? ? ? ? int length=sqlite3_column_bytes(stmt,3);//獲取二進制數據的長度
? ? ? ? ? ? NSData *img=[NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:length]; //將二進制數據轉換位NSData對



? ? ? ? ? ? //將從數據庫中查詢來的數據存到(Student*)對象中,用于返回?
? ? ? ? ? ? stu=[[Student alloc]init];//此時開辟空間節省內存
? ? ? ? ? ? stu.sid=sid;
? ? ? ? ? ? stu.sname=sname;
? ? ? ? ? ? stu.simage=img;
? ? ? ? ? ? stu.sage=sage;
? ? ? ? }
? ? }
? ? sqlite3_finalize(stmt);//回收stmt對象
? ? return [stu autorelease];//返回包含學生信息的對象
}
*注意這里一般學生姓名并不是唯一標示所以可能會查到多條記錄符合條件所以要返回一個數組來存儲符合條件的(Student*)對象 ?但


現在我們的數據庫不涉及重名的事例所以這里只返回學生對象
+(Student*) findbysname:(NSString*)sname
{
? ? Student *stu;//用于返回的學生對象
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫
? ? sqlite3_stmt *stmt=nil;//定義sql語句對象
? ? int flag=sqlite3_prepare_v2(sqlite, "select * from tblstudent where stuname=?", -1, &stmt, nil);//調用預處理函數將


sql語句賦值給stmt對象
? ? if (flag==SQLITE_OK)
? ? {
? ? ? ? sqlite3_bind_text(stmt, 1, [sname UTF8String], -1, nil);//給問號占位符賦值
? ? ? ? while (sqlite3_step(stmt)==SQLITE_ROW)
? ? ? ? {
? ? ? ? ? ? //根據列順序(從零開始)
? ? ? ? ? ? int sid=sqlite3_column_int(stmt, 0);//取整型數據
? ? ? ? ? ? int sage=sqlite3_column_int(stmt, 2);
? ? ? ? ? ? NSString *sname=[NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];//取nsstring數據
? ? ? ? ? ? int length=sqlite3_column_bytes(stmt,3);//獲取二進制數據的長度
? ? ? ? ? ? NSData *img=[NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:length]; //將二進制數據轉換位NSData對


象?
? ? ? ? ? ? stu=[[Student alloc]init];//此時開辟空間節省內存
? ? ? ? ? ? stu.sid=sid;
? ? ? ? ? ? stu.sname=sname;
? ? ? ? ? ? stu.simage=img;
? ? ? ? ? ? stu.sage=sage;
? ? ? ? }
? ? }
? ? sqlite3_finalize(stmt);//回收stmt對象
? ? return [stu autorelease];//返回包含學生信息的(Student*)對象
}
3.向數據庫增加一條記錄
+(void) insertstudent:(NSString*) name age:(int)age image:(NSData*)image
{
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫
? ? sqlite3_stmt *stmt=nil;//定義sql語句對象
? ? int flag=sqlite3_prepare_v2(sqlite, "insert into tblstudent(stuname,stuage,stuimage) values(?,?,?)", -1, &stmt,?


nil);//調用預處理函數將sql語句賦值給stmt對象 ?多值綁定逗號隔開
? ? if (flag==SQLITE_OK)
? ? {
? ? ? ? sqlite3_bind_text(stmt, 1, [name UTF8String],-1,nil);//給問號占位符賦值
? ? ? ? sqlite3_bind_int(stmt, 2, age);//對整型數據的綁定
? ? ? ? sqlite3_bind_blob(stmt, 3, [image bytes], [image length], nil);//對二進制類型數據的綁定 數據的字節數(-1 針對字


符串的長度比較準)
? ? ? ? if(sqlite3_step(stmt)==SQLITE_ERROR)//執行insert動作
? ? ? ? {
? ? ? ? ? ? NSLog(@"insert error");
? ? ? ? }
? ? }
? ? sqlite3_finalize(stmt);//回收stmt對象
}
4.修改更新數據庫的數據
*注意更新數據庫時要通過一定的限制條件來確定要更新的記錄,可能是一條也可能是多條,當要更新的記錄是多條時要注意所有符合條


件的記錄都會改為你定義的值。
+(void) updatestudent:(Student*) stu
{
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫
? ? sqlite3_stmt *stmt=nil;//定義sql語句對象
? ? int flag=sqlite3_prepare_v2(sqlite, "update tblstudent set stuname=?,stuage=?,stuimage=? where stuid=?", -1, &stmt,?


nil);//調用預處理函數將sql語句賦值給stmt對象
? ? if (flag==SQLITE_OK)
? ? {
? ? ? ? sqlite3_bind_text(stmt, 1, [stu.sname UTF8String],-1,nil);//給問號占位符賦值
? ? ? ? //stu.sname為nsstring ? ?UTF8String ? ?nsstring---->ctring
? ? ? ? sqlite3_bind_int(stmt, 4, stu.sid);//給問號占位符賦值
? ? ? ? sqlite3_bind_int(stmt, 2, stu.sage);//給年齡賦值
? ? ? ? sqlite3_bind_blob(stmt, 3, [stu.simage bytes], [stu.simage length], nil);
? ? ? ? if(sqlite3_step(stmt)==SQLITE_ERROR)//執行update動作
? ? ? ? {
? ? ? ? ? ? NSLog(@"update error");
? ? ? ? }
? ? ? ? sqlite3_finalize(stmt);//回收stmt對象
? ? }
}
5.刪除數據庫的記錄
*注意刪除數據庫的記錄時要通過一定的限制條件來確定要刪除的記錄,可能是一條也可能是多條,當要刪除的記錄是多條時要注意所有


符合條件的記錄都會被刪除。
+(void) deletebysid:(int) sid
{
? ? sqlite3 *sqlite=[DataBase OpenDB];//打開數據庫
? ? sqlite3_stmt *stmt=nil;//定義sql語句對象
? ? int flag=sqlite3_prepare_v2(sqlite, "delete from tblstudent where stuid=?", -1, &stmt, nil);//調用預處理函數將sql語


句賦值給stmt對象
? ? if (flag==SQLITE_OK)
? ? {
? ? ? ? sqlite3_bind_int(stmt, 1, sid);//給問號占位符賦值 ?1.語句2.占位符的序號3.給占位符賦得值
? ? ? ? //執行delete動作
? ? ? ? if(sqlite3_step(stmt)==SQLITE_ERROR)//未執行成功
? ? ? ? {
? ? ? ? ? ? NSLog(@"delete error");
? ? ? ? }
? ? }
? ? sqlite3_finalize(stmt);//回收stmt對象
? ?
? ? NSLog(@"刪除了第%d",sid);
}
========

IOS 四種保存數據的方式

在iOS開發過程中,不管是做什么應用,都會碰到數據保存的問題。將數據保存到本地,能夠讓程序的運行更加 流暢,不會出現讓人厭惡的


菊花形狀,使得用戶體驗更好。下面介紹?一下數據保存的方式:
1.NSKeyedArchiver:采用歸檔的形式來保存數據,該數據對象需要遵守NSCoding協議,并且該對象對應的類必須提 供encodeWithCoder:和


initWithCoder:方法。前?一個方法告訴系統怎么對對象進行編碼,而后?一個方法則是告訴系統怎 么對對象進行解碼。例如對


Possession對象歸檔保存。
定義Possession:
@interface Possession:NSObject{//遵守NSCoding協議
NSString *name;//待歸檔類型 }
@implementation Possession -(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:name forKey:@"name"]; }
-(void)initWithCoder:(NSCoder *)aDecoder{
name=[[aDeCoder decodeObjectforKey:@"name"] retain];
}
歸檔操作: 如果對Possession對象allPossession歸檔保存,只需要NSCoder子類NSKeyedArchiver的方法 archiveRootObject:toFile: 即


可。
NSString *path = [self possessionArchivePath];
[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]
解壓操作: 同樣調用NSCoder子類NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可 allPossessions = [[NSKeyedUnarchiver?


unarchiveObjectWithFile:path] retain];
缺點:歸檔的形式來保存數據,只能?一次性歸檔保存以及?一次性解壓。所以只能針對小量數據,而且對數據操作比較 笨拙,即如果想改


動數據的某?一小部分,還是需要解壓整個數據或者歸檔整個數據。 2.NSUserDefaults:用來保存應用程序設置和屬性、用戶保存的數據


。用戶再次打開程序或開機后這些數據仍然存 在。NSUserDefaults可以存儲的數據類型包括:NSData、NSString、NSNumber、NSDate、


NSArray、 NSDictionary。如果要存儲其他類型,則需要轉換為前面的類型,才能用NSUserDefaults存儲。具體實現為:
保存數據:
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults]; NSString *name =@”default string“;
[defaults setObject:firstName forKey:@"name"];
//獲得UIImage實例
UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];
NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage對象轉換成NSData [defaults synchronize];//用


synchronize方法把數據持久化到standardUserDefaults數據庫
讀取數據:
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:@"name"];//根據鍵值取出name
NSData *imageData = [defaults dataForKey:@"image"];
UIImage *Image = [UIImage imageWithData:imageData];//NSData轉換為UIImage
3. Write寫入方式:永久保存在磁盤中。具體方法為:
第?一步:獲得文件即將保存的路徑:
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);//使用C函數


NSSearchPathForDirectoriesInDomains來獲得沙盒中目錄的全路
徑。該函數有三個參數,目錄類型、he domain mask、布爾值。其中布爾值表示是否需要通過?~擴展路徑。 而且第?一個參數是不變的


,即為NSSearchPathDirectory 。在IOS中后兩個參數也是不變的,即為:
NSUserDomainMask 和 YES。
NSString *ourDocumentPath =[documentPaths objectAtIndex:0];
還有?一種方法是使用NSHomeDirectory函數獲得sandbox的路徑。具體的用法為:
NSString *sandboxPath = NSHomeDirectory();
// Once you have the full sandbox path, you can create a path from it,但是不能在sandbox的本文件層上寫 文件也不能創建目


錄,而應該是此基礎上創建?一個新的可寫的目錄,例如Documents,Library或者temp。 NSString *documentPath = [sandboxPath
stringByAppendingPathComponent:@"Documents"];//將Documents添加到sandbox路徑上,具體原 因前面分析了!
這兩者的區別就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因為該文件目 錄可


能在未來發送的系統上發生改變。
第二步:生成在該路徑下的文件:
NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件 名
第三步:往文件中寫入數據:
[data writeToFile:FileName atomically:YES];//將NSData類型對象data寫入文件,文件名為FileName
最后:從文件中讀出數據:
NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//從FileName中讀取出數據
4. SQLite:采用SQLite數據庫來存儲數據。SQLite作為?一中小型數據庫,應用ios中,跟前三種保存方式相比,相對 比較復雜?一些。還


是?一步步來吧!
第?一步:需要添加SQLite相關的庫以及頭文件:在項目文件的Build Phases下,找到Link Binary Library(ies),添加?


libsqlite3.0.dylib(libsqlite3.dylib與前者的區別暫時不知,兩者應該差不多);在項目文件中頭文件或者源文件中添加頭文件?


#import "/usr/include/sqlite3.h"
第二步:開始使用SQLite:
使用前注意:如果不往數據庫里面添加任何的表,這個數據庫等于沒有建立,不會在硬盤上產生任何文件,如果數據庫已經 存在,則會打開


這個數據庫。
NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES);
NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];
//上面兩句已經比較熟悉了吧!
//打開數據庫
if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) {
NSLog(@"sqlite dadabase is opened."); }
else{ return;}//打開不成功就返回
在打開了數據庫的前提下,如果數據庫沒有表,那就開始建表了哦!
char *error;
const char *createSql="create table(id integer primary key autoincrement, name text)"; if (sqlite3_exec(database,?


createSql, NULL, NULL, &error)==SQLITE_OK) {
NSLog(@"create table is ok."); }
else {
sqlite3_free(error);//每次使用完畢清空error字符串,提供給下?一次使用 }
建表完成之后,就開始插入記錄:
const char *insertSql="insert into a person (name) values(‘gg’)";
if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) {
NSLog(@"insert operation is ok."); }
else {
NSLog(@"error: %s",error);
NSLog(@"error: %s",error);
sqlite3_free(error);//每次使用完畢清空error字符串,提供給下?一次使用 }
下?一步,查詢記錄:
const char *selectSql="select id,name from a person";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) {
NSLog(@"select operation is ok."); }
else {
sqlite3_free(error); }
while(sqlite3_step(statement)==SQLITE_ROW) {
int _id=sqlite3_column_int(statement, 0);
NSString *name=(char*)sqlite3_column_text(statement, 1); NSLog(@"row>>id %i, name %s",_id,name);
}
sqlite3_finalize(statement);
最后,關閉數據庫:
sqlite3_close(database);
注意:寫入數據庫,字符串可以采用char方式,而從數據庫中取出char類型,當char類型有表示中文字符 時,會出現亂碼。這是因為數據庫


默認使用ascII編碼方式。所以要想正確從數據庫中取出中文,需要用 NSString來接收從數據庫取出的字符串。?
========

總結

以上是生活随笔為你收集整理的IOS操作数据库总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。