- 一隘弊、數(shù)據(jù)庫管理系統(tǒng)
- 二、SQL語句
- 三送悔、 iOS的數(shù)據(jù)庫技術(shù)實(shí)現(xiàn)
數(shù)據(jù)庫常用概念:
- SQL:SQL是Structured Query Language(結(jié)構(gòu)化查詢語言)的縮寫慢显。SQL是專為數(shù)據(jù)庫而建立的操作命令集,是一種功能齊全的數(shù)據(jù)庫語言欠啤。
- 數(shù)據(jù)庫:是按照數(shù)據(jù)結(jié)構(gòu)來組織荚藻、存儲和管理數(shù)據(jù)的倉庫。
- 數(shù)據(jù)庫的分類:關(guān)系型數(shù)據(jù)庫(主流)洁段、對象型數(shù)據(jù)庫鞋喇、層次型數(shù)據(jù)庫。
- 數(shù)據(jù)庫的特征:1.以一定的方式存儲在一起眉撵。2.能為多個用戶共享侦香。3.具有盡可能少的冗余代碼。4.與程序彼此獨(dú)立的數(shù)據(jù)集合纽疟。
- 常用的關(guān)系型數(shù)據(jù)庫:PC端:Oracle罐韩、MySQL、SQL Server污朽、Access散吵、DB2、Sybase蟆肆。嵌入式\移動客戶端:SQLite
- 表:是數(shù)據(jù)庫中一個非常重要的對象矾睦,是其他對象的基礎(chǔ)。根據(jù)信息的分類情況炎功,一個數(shù)據(jù)庫中可能包含若干個數(shù)據(jù)表枚冗。
- 字段:表中的"列"成為"字段",每個字段包含某一專題的信息蛇损。(標(biāo)識本列數(shù)據(jù)類型)
- 記錄:是指對應(yīng)于數(shù)據(jù)表中一行信息的一組完整的相關(guān)信息赁温。
SQLite數(shù)據(jù)庫數(shù)據(jù)類型:SQLite是無類型數(shù)據(jù)庫坛怪,可以保存任何類型數(shù)據(jù),對于SQLite來說 對字段不指定類型是完全有效的(注:良好的編程習(xí)慣應(yīng)該要為字段標(biāo)注類型)股囊。為了使SQLite和其他數(shù)據(jù)庫間的兼容性最大化袜匿,SQLite支持"類型近似"的觀點(diǎn),列的類型近似指的是存儲在列上的數(shù)據(jù)的推薦類型稚疹。
SQLite近似類型規(guī)則:1.如果類型字符串中包含"INT",那么該字段的親緣類型是INTEGER居灯。2.如果類型字符串中包含"CHAR"、"CLOB"内狗、"TEXT",那么該字段的親緣類型是TEXT穆壕。3.如果類型字符串中包含"BLOB",那么該字段的親緣類型是NONE。4.如果類型字符串中包含"REAL"其屏、"FLOA"喇勋、"DOUB",那么該字段的親緣類型是REAL。5.其他情況下,字段的親緣類型是NUMERIC偎行。
SQLite字段約束條件:
SQL語句:1.建表命令(create table)2.數(shù)據(jù)插入命令(insert)3.數(shù)據(jù)庫更新命令(update)4.數(shù)據(jù)庫刪除命令(delete)5.數(shù)據(jù)庫檢索命令(select)
建表:create table if not exists 表名 (字段1 約束1 約束2······川背,字段2 約束1 約束2······,·····)蛤袒;
注:1.create table 建表關(guān)鍵字 2. if not exists 如果創(chuàng)建的表存在就不在創(chuàng)建 3.一個字段可以有多個約束熄云。插入:insert into 表名(字段1,字段2妙真,字段3缴允,······)values(字段1值,字段2值珍德,字段3值·····)练般;
注:字段值要和前面的字段順序一致更新:update 表名 set 字段名1 = 修改值1,字段名2 = 修改值2 ······ where 條件;
注:條件可以有一個或多個锈候。多個條件使用and(與),or(或)連接薄料。刪除:delete from 表名 where 條件;
示例: delete from stu where age = 10;查詢:select 要查找的字段 from 表名 where 條件;
注:要查找的字段(如果查找所有字段可以使用通配符*)
示例: select from stu where sex = '男'; select name , age , from stu where sex = '男';
iOS數(shù)據(jù)庫技術(shù)的實(shí)現(xiàn)
Linux系統(tǒng)級的SQLite技術(shù)實(shí)現(xiàn)框架
Xcode6中 libsqlite3.0.dylib
Xcode7中 libsqlite3.0tdb
1.引入<sqlite3.h>頭文件
2.打開數(shù)據(jù)庫
3.執(zhí)行SQL命令(建表泵琳,增刪改查)
4.關(guān)閉數(shù)據(jù)庫
建表 插入 更新等操作
//創(chuàng)建數(shù)據(jù)庫文件的路徑
- (NSString*)dbPath{
NSString* docPath = [[SandBoxPaths documentsPath] stringByAppendingPathComponent:@"testDB.sqlite"];
return docPath;
}
//創(chuàng)建數(shù)據(jù)庫文件
- (void)createDB{
//創(chuàng)建數(shù)據(jù)庫文件的函數(shù),如果數(shù)據(jù)庫文件存在摄职,那么這個方法就是打開數(shù)據(jù)庫文件,如果數(shù)據(jù)庫文件不存在获列,這個方法就是先創(chuàng)建數(shù)據(jù)庫文件谷市,在打開數(shù)據(jù)庫
//第一個參數(shù)是數(shù)據(jù)庫文件的路徑
//第二個參數(shù):數(shù)據(jù)庫文件的句柄取地址
//將數(shù)據(jù)庫句柄指向數(shù)據(jù)庫內(nèi)存,我們對數(shù)據(jù)庫的操作都是通過句柄來完成的
// dbPath.UTF8String是把NSString類型轉(zhuǎn)換為C語言的 char* 類型
NSString* dbPath = [self dbPath];
int result = sqlite3_open(dbPath.UTF8String, &sqliteHandle);
if (result == SQLITE_OK) {
NSLog(@"數(shù)據(jù)庫打開成功");
}else{
NSLog(@"數(shù)據(jù)庫打開失敗----%d",result);
}
}
//數(shù)據(jù)庫的非查詢操作(無返回結(jié)果集的操作)击孩,插入迫悠,更新,刪除等操作
//參數(shù)為要執(zhí)行的sql語句
- (void)noQueryOpertion:(NSString*)sql{
//用來執(zhí)行無返回結(jié)果集的操作
//第一個參數(shù):數(shù)據(jù)庫句柄溯壶;所有對數(shù)據(jù)庫的操作都是通過句柄來完成的
//第二個參數(shù):要執(zhí)行的sql語句
//第三個參數(shù):回調(diào)函數(shù)及皂,該exec執(zhí)行完畢之后會執(zhí)行的C語言函數(shù),如果你需要在該操作執(zhí)行完畢的時候且改,做一些其他操作验烧,就需要實(shí)現(xiàn)該回調(diào)函數(shù),一般我們直接給NULL
//第四個參數(shù):是第三個參數(shù)中回調(diào)函數(shù)的第一個參數(shù)
//第五個參數(shù):錯誤日志
int result = sqlite3_exec(sqliteHandle, sql.UTF8String, NULL, NULL , NULL);
if (result == SQLITE_OK) {
NSLog(@"無返回結(jié)果集的操作成功");
}else{
NSLog(@"無返回結(jié)果集的操作失敗-----%d",result);
}
}
/打開或者創(chuàng)建數(shù)據(jù)庫
[self createDB];
//建表操作
NSString* sql = @"create table if not exists stu(name text unique,age integer,gender char)";
[self noQueryOpertion:sql];
//插入數(shù)據(jù)操作
NSString* sqlInsert = @"insert into stu values('李四',20,'男')";
[self noQueryOpertion:sqlInsert];
//更新操作
NSString* sqlUpdate = @"update stu set age = 100 where age = 20";
NSString* sqlUpdate1 = @"update stu set name = '張三' where name = '李四'";
[self noQueryOpertion:sqlUpdate];
[self noQueryOpertion:sqlUpdate1];
//關(guān)閉數(shù)據(jù)庫
sqlite3_close(sqliteHandle);
查詢操作
//數(shù)據(jù)庫的查詢操作
//參數(shù)為要執(zhí)行的sql語句
- (void)queryOpertion:(NSString*)sql{
//伴隨指針(相當(dāng)于我們進(jìn)行查詢操作的時候又跛,該指針可以理解為存儲了一條一條的記錄碍拆。我們獲取一條記錄的所有信息都是通過伴隨指針)
sqlite3_stmt* stmt = NULL;
//預(yù)執(zhí)行sql語句,如果預(yù)執(zhí)行成功慨蓝,那么我們就可以獲取一條一條的記錄感混,如果預(yù)執(zhí)行失敗,一般說明我們的sql語句有問題礼烈,不能獲取表中的記錄信息
//第一個參數(shù):數(shù)據(jù)庫句柄
//第二個參數(shù):要執(zhí)行的sql語句
//第三個參數(shù):要執(zhí)行的sql語句的長度弧满,要想全部執(zhí)行完,就賦值為 -1
//第四個參數(shù):伴隨指針的地址
//第五個參數(shù):如果sql語句不全部執(zhí)行此熬,該參數(shù)保存未執(zhí)行的sql語句
int result = sqlite3_prepare(sqliteHandle, sql.UTF8String, -1, &stmt, NULL);
// 初始化一個可變數(shù)組用來存放所有的記錄庭呜;每一條記錄就相當(dāng)于一個字典
NSMutableArray* recordMArray = [[NSMutableArray alloc] init];
if (result == SQLITE_OK) {
//說明預(yù)執(zhí)行成功,可以取表中的記錄了
//通過while循環(huán)將表中的每一條記錄取出
//step方法每執(zhí)行一次犀忱,伴隨指針就會指向下一條記錄募谎,當(dāng)所有的記錄都取完之后,step函數(shù)的返回值就不等于SQLITE_ROW阴汇,循環(huán)也就停止了
while (sqlite3_step(stmt) == SQLITE_ROW) {
//進(jìn)入循環(huán)體內(nèi)数冬,伴隨指針就相當(dāng)于一條記錄
//從記錄中取值,是一個字段一個字段取
//每次執(zhí)行while循環(huán)搀庶,都是一條新的記錄拐纱,要對應(yīng)一個新字典
NSMutableDictionary* recordMDic = [[NSMutableDictionary alloc] init];
//取出第0列的值
const unsigned char* name = sqlite3_column_text(stmt, 0);
//將char* 轉(zhuǎn)換為OC中可用的NSString*類型
NSString* nameString = [[NSString alloc] initWithCString:(const char *)name encoding:NSUTF8StringEncoding];
//
[recordMDic setObject:nameString forKey:@"name"];
//取出第一列的值
int age = sqlite3_column_int(stmt, 1);
//放入字典中
[recordMDic setObject:@(age) forKey:@"age"];
//取出第二列的值
const unsigned char* gender = sqlite3_column_text(stmt, 2);
NSString* genderString = [[NSString alloc] initWithCString:(const char *)gender encoding:NSUTF8StringEncoding];
[recordMDic setObject:genderString forKey:@"gender"];
[recordMArray addObject:recordMDic];
}
NSLog(@"%@",recordMArray);
}else{
NSLog(@"預(yù)執(zhí)行失敗---%d",result);
}
//釋放掉伴隨指針?biāo)钟械闹羔? sqlite3_finalize(stmt);
}
//調(diào)用該方法
[self queryOpertion:@"select * from stu"];