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