
一.SQLite簡介
先莫急,認(rèn)真看完簡介,一定對你有幫助的(已經(jīng)熟知的跳過簡介,當(dāng)你在公司有同事不會sqlite的時(shí)候,你就可以先簡單的說幾句SQLite的簡介以達(dá)到裝逼的目的,裝b效果如果100分的話,大多基本上會給你90分了)。
SQLite,是一款輕型的數(shù)據(jù)庫,是遵守ACID的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它包含在一個(gè)相對小的C庫中。它是D.RichardHipp建立的公有領(lǐng)域項(xiàng)目。它的設(shè)計(jì)目標(biāo)是嵌入式的,而且目前已經(jīng)在很多嵌入式產(chǎn)品中使用了它,它占用資源非常的低,在嵌入式設(shè)備中,可能只需要幾百K的內(nèi)存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統(tǒng),同時(shí)能夠跟很多程序語言相結(jié)合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源的世界著名數(shù)據(jù)庫管理系統(tǒng)來講,它的處理速度比他們都快。SQLite第一個(gè)Alpha版本誕生于2000年5月。
二.sqlite使用之創(chuàng)建數(shù)據(jù)庫,創(chuàng)建表,對表內(nèi)數(shù)據(jù)操作等
1.創(chuàng)建數(shù)據(jù)庫(前面的準(zhǔn)備工作(導(dǎo)入libsqlite3庫)就不介紹了)
- (void)createDataBase{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsStr = [paths objectAtIndex:0];
//應(yīng)用的文檔目錄
NSLog(@"%@",documentsStr);
NSString *database_path = [documentsStr stringByAppendingPathComponent:KDBName];
//打開數(shù)據(jù)庫,如果沒有的話,就會在該目錄創(chuàng)建該數(shù)據(jù)庫。
if(sqlite3_open([database_path UTF8String], &db) != SQLITE_OK) {
sqlite3_close(db);
}
}
2.創(chuàng)建表
- (void)createTable{
//IF NOT EXISTS 如果不存在 (如果該數(shù)據(jù)庫已經(jīng)存在了該表,則sqlite3_exec在執(zhí)行數(shù)據(jù)庫操作的時(shí)候不會報(bào)錯(cuò)給我們,如果表已經(jīng)存在了,又沒有加這個(gè)判斷的話,會執(zhí)行不成功并關(guān)閉數(shù)據(jù)庫)
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (ID INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, sex INTEGER, phoneNum VARCHAR);",KTBUserInfo];
[self execSql:sql];
/*
* sqlite數(shù)據(jù)庫里面的數(shù)據(jù)類型參考SQLite數(shù)據(jù)庫的文檔,這里的sql語句CREATE、INTEGER等關(guān)鍵詞,大寫是為了區(qū)分這是系統(tǒng)的,并不是規(guī)定的,小寫也是能正常通過的,不過,為了規(guī)范,建議大寫。
*/
}
3.插入數(shù)據(jù)
- (void)insertData{
NSString *sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"張三", @"23", @"1",@"18875022022"];
[self execSql:sql];
sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"李四", @"24", @"0",@"18875022023"];
[self execSql:sql];
sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"王五", @"25", @"1",@"18875022024"];
[self execSql:sql];
}
execSql方法
- (void)execSql:(NSString *)sql{
char *err;
sqlite3_open([[documents stringByAppendingPathComponent:KDBName] UTF8String], &db);
sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err);
sqlite3_close(db);
}
就不貼修改、刪除數(shù)據(jù)的代碼了,附件demo里有詳細(xì)代碼。只要sql不是SELECT命令的都視為更新操作(使用exec開頭的方法)。就包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等等。SELECT命令的話,使用sqlite3_prepare開頭的方法。
4.查詢數(shù)據(jù)
- (void)queryDataWithTableName:(NSString *)tbName{
sqlite3_open([[documents stringByAppendingPathComponent:KDBName] UTF8String], &db);
NSString *sqlQuery = [NSString stringWithFormat:@"SELECT * FROM %@;",tbName];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, [sqlQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char *name = (char*)sqlite3_column_text(statement, 1);
NSString *nsNameStr = [[NSString alloc] initWithUTF8String:name];
int age = sqlite3_column_int(statement, 2);
int sex = sqlite3_column_int(statement, 3);
int columnCount = sqlite3_column_count(statement);
if (columnCount == 5) {//為了兼容我這里兩個(gè)表,其中一個(gè)表少一個(gè)字段,揀個(gè)懶
char *phoneNum = (char*)sqlite3_column_text(statement, 4);
NSString *phoneNumStr = [[NSString alloc] initWithUTF8String:phoneNum];
NSLog(@"%@: name:%@ age:%d sex:%d phoneNum:%@",tbName,nsNameStr,age,sex,phoneNumStr);
}else{
NSLog(@"%@: name:%@ age:%d sex:%d",tbName,nsNameStr,age,sex);
}
}
}else{
NSLog(@"%@查詢數(shù)據(jù)失敗",tbName);
}
sqlite3_close(db);
}
三.FMDB的用法
由于原生的SQLite在進(jìn)行數(shù)據(jù)操作的時(shí)候,使用的是C語言中的函數(shù),對于我這種C語言又是小白的人,就會感覺比較麻煩。程序員都是懶人,于是,出了一系列的對SQLite的API進(jìn)行封裝的庫,如FMDB。還有一些其他的,就不列舉了,自行百度。
1.FMDB簡介
<a >FMDB</a>是針對iOS的libsqlite3框架的封裝的一個(gè)簡易庫(簡單易學(xué),輕量級,使用靈活),它用起來和SQLite類似,而且,對多線程并發(fā)操作進(jìn)行了處理,所以線程安全。
2.比較重要的幾個(gè)類
FMDB.h 引入了你在使用FMDB過程中可能會用到的幾個(gè)類。
FMDatabase 代表一個(gè)單獨(dú)的SQLite數(shù)據(jù)庫,用它調(diào)用方法執(zhí)行sql語句,類似原生sqlite3。
FMResultSet 在使用FMDatabase執(zhí)行了查詢的sql語句后,得到的結(jié)果集,就是FMResultSet。
FMDatabaseQueue 多線程中,執(zhí)行數(shù)據(jù)操作,查詢等。
3.使用FMDB創(chuàng)建數(shù)據(jù)庫和表(首先實(shí)現(xiàn)文件里聲明全局變量fmdb)
@interface ViewController (){
sqlite3 *db;
FMDatabase *fmdb;//!< FMDatabase,執(zhí)行數(shù)據(jù)操作,查詢。
}
@end
@implementation ViewController
#pragma amrk - fmdb創(chuàng)建數(shù)據(jù)庫
- (void)fmdbCreate{
NSString *database_path = [documents stringByAppendingPathComponent:KFMDBName];
//數(shù)據(jù)庫打開、創(chuàng)建
fmdb = [FMDatabase databaseWithPath:database_path];
}
#pragma amrk - fmdb創(chuàng)建表
- (void)fmdbTableCreate{
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (ID INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, sex INTEGER, phoneNum VARCHAR);",KTBUserInfo];
[self fmdbExecSql:sql];
}
#pragma mark - fmdbUpdate
- (void)fmdbExecSql:(NSString *)sql{
if ([fmdb open]) {
/*
* 只要sql不是SELECT命令的都視為更新操作(使用executeUpdate方法)。就包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等等。SELECT命令的話,使用executeQuery方法。
* 執(zhí)行更新返回一個(gè)BOOL值。YES表示 執(zhí)行成功,否則表示有錯(cuò)誤。你可以調(diào)用 -lastErrorMessage 和 -lastErrorCode方法來得到更多信息。
*/
if ([fmdb executeUpdate:sql]) {
NSLog(@"%@%@%@",@"fmdb操作表",KTBUserInfo,@"成功!");
}else{
NSLog(@"%@%@%@ lastErrorMessage:%@,lastErrorCode:%d",@"fmdb創(chuàng)建",KTBUserInfo,@"失??!",fmdb.lastErrorMessage,fmdb.lastErrorCode);
}
}else{
NSLog(@"%@",@"fmdb數(shù)據(jù)庫打開失??!");
}
}
@end
同樣的道理,只有是操作數(shù)據(jù)的命令,都是調(diào)用executeUpdate方法,查詢命令SELECT則調(diào)用executeQuery開頭的方法。這里就不列舉增刪改的方法了。
4.fmdb查詢數(shù)據(jù)
- (void)fmdbSelectData{
NSString *sqlQuery = [NSString stringWithFormat:@"SELECT * FROM %@;",KTBUserInfo];
//根據(jù)條件查詢,如果成功返回FMResultSet對象,錯(cuò)誤返回nil。與執(zhí)行更新相當(dāng),支持使用NSError參數(shù)。
FMResultSet *resultSet = [fmdb executeQuery:sqlQuery];
//遍歷結(jié)果集合
while ([resultSet next]){
NSString *name = [resultSet
objectForColumnName:@"name"];
int age = [resultSet intForColumn:@"age"];
int sex = [resultSet intForColumn:@"sex"];
NSString *phone = [resultSet objectForColumnName:@"phoneNum"];
NSLog(@"%@: name:%@ age:%d sex:%d phoneNum:%@",KTBUserInfo,name,age,sex,phone);
}
/*
* fmdb封裝過后的讀取數(shù)據(jù)是要比原生的sqlite3方便了很多哈
*/
}
5.fmdb多線程
- (void)fmdbQueue{
//創(chuàng)建隊(duì)列
FMDatabaseQueue *queue = [FMDatabaseQueue
databaseQueueWithPath:[documents stringByAppendingPathComponent:KFMDBName]];
__block BOOL tag = true;
//把任務(wù)放到到隊(duì)列里
[queue inTransaction:^(FMDatabase *dbe, BOOL *rollback)
{
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:11]];
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:22]];
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:33]];
//如果有錯(cuò)誤 回滾
if (!tag){
*rollback = YES;
return;
}
}];
}
6.查詢結(jié)果獲取數(shù)據(jù)格式的方法,在FMResultSet.h文件里面,搜索包含F(xiàn)orColumn的方法定義。然后,你就會發(fā)現(xiàn)類似這種doubleForColumn、doubleForColumnIndex的方法,注釋也是寫的非常的詳細(xì),不懂英語其實(shí)翻譯一下就搞定,機(jī)智如我。
四.工具推薦
喜歡用客戶端的自行百度搜索SQLiteManager for mac 破解版,畢竟找工具還是自力更生。我不喜歡客戶端,有沒有簡單粗暴的直接可以打開的?有!如果你有裝火狐瀏覽器、就應(yīng)該會用插件。不會的也可以下一個(gè)火狐瀏覽器,開發(fā)用還是很ok的。

<a >點(diǎn)擊跳轉(zhuǎn)源碼下載地址</a>