SQLite3

iOS數(shù)據(jù)庫簡單入門

什么是數(shù)據(jù)庫

言簡意賅:字面上的理解,保存數(shù)據(jù)的倉庫.
維基百科:可視為電子化的文件柜——存儲電子文件的處所立砸,用戶可以對文件中的數(shù)據(jù)運(yùn)行新增索赏、截取、更新、刪除等操作.
類似于EXCEL表格

常見數(shù)據(jù)庫

  1. Oracle
  2. DB2
  3. SQL Server
  4. Postgre SQL
  5. MySQL

相關(guān)術(shù)語

DBS(Database System):數(shù)據(jù)庫系統(tǒng)

  • 數(shù)據(jù)庫 DB(Database)
  • 數(shù)據(jù)庫管理系統(tǒng)DBMS(Database Management System)
  • 應(yīng)用開發(fā)工具
  • 管理員及用戶

SQL語言(Structured Query Language)結(jié)構(gòu)化查詢語言

  • DDL (Data Definition Language) 數(shù)據(jù)庫定義語言
    數(shù)據(jù)定義語言DDL用來創(chuàng)建數(shù)據(jù)庫中的各種對象-----表介蛉、視圖、
    索引溶褪、同義詞币旧、聚簇等如:
    CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
    | | | | |
    表 視圖 索引 同義詞 簇
    主要語句:
    Create語句:可以創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)庫的一些對象。
    Drop語句:可以刪除數(shù)據(jù)表猿妈、索引吹菱、觸發(fā)程序、條件約束以及數(shù)據(jù)表的權(quán)限等彭则。
    Alter語句:修改數(shù)據(jù)表定義及屬性鳍刷。

  • DML(Data Manipulation Language) 數(shù)據(jù)庫操作語言
    數(shù)據(jù)操縱語言DML主要有三種形式:

  1. 插入:INSERT
  2. 更新:UPDATE
  3. 刪除:DELETE
  • DQL (Data Query Language)數(shù)據(jù)庫查詢語言
    數(shù)據(jù)查詢語言DQL基本結(jié)構(gòu)是由SELECT子句,F(xiàn)ROM子句俯抖,WHERE
    子句組成的查詢塊:
    SELECT <字段名表>
    FROM <表或視圖名>
    WHERE <查詢條件>

  • DCL (Data Control Language)數(shù)據(jù)庫控制語言
    數(shù)據(jù)控制語言DCL用來授予或回收訪問數(shù)據(jù)庫的某種特權(quán),并控制
    數(shù)據(jù)庫操縱事務(wù)發(fā)生的時間及效果,對數(shù)據(jù)庫實(shí)行監(jiān)視等艾猜。如:

  1. GRANT:授權(quán)宙橱。
  2. ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點(diǎn)。
    回滾---ROLLBACK
    回滾命令使數(shù)據(jù)庫狀態(tài)回到上次最后提交的狀態(tài)柬祠。其格式為:
    SQL>ROLLBACK;
  3. COMMIT [WORK]:提交北戏。

SQL語句

創(chuàng)建表

CREATE TABLE IF NOT EXISTS table_Name(ID PRIMARY KEY,);

sqlite3

SQLite是一個嵌入式的數(shù)據(jù)庫引擎,專門適用于資源有限的設(shè)備(手機(jī),pda等)適量數(shù)據(jù)存儲.即輕量級的數(shù)據(jù)庫,沒有服務(wù)器進(jìn)程.其使用的是原生的C函數(shù)庫.

特點(diǎn)

1.所有數(shù)據(jù)在表單中進(jìn)行管理,數(shù)據(jù)沒有順序
2.SQL語句不區(qū)分大小寫,字段,表單區(qū)分大小寫
3.表單必須有主鍵,主鍵唯一,主鍵不會歸零,只增不減
4.SQLite內(nèi)部只支持NULL,INTEGER,REAL(浮點(diǎn)數(shù)),TEXT(文本),BLOB(大二進(jìn)制對象),這5種類型,但實(shí)際上也完全可以接受VARCHAR(N),CHAR(N),DECIMAL(P,S)等數(shù)據(jù)類型,只不過SQLite會在運(yùn)算或保存時將他們轉(zhuǎn)換為上面5種數(shù)據(jù)類型中相應(yīng)的類型.
5.SQLite允許把各種類型的數(shù)據(jù)保存到任何類型字段只能中,開發(fā)者可以不用關(guān)心聲明該字段所使用的數(shù)據(jù)類型.例如:可以把字符串類型的值存入INTEGER類型的字段中,也可以把數(shù)值型的值存入布爾類型的字段中.但是定義為”INTEGER PRIMARY KEY”即主鍵,只能存儲64位整數(shù),存儲除整數(shù)以外的其它數(shù)據(jù)類型時,SQLite會產(chǎn)生錯誤.

sqlite3工具

Mac OS X ++自帶sqlite3工具,可以通過終端來執(zhí)行命令來檢查,管理數(shù)據(jù)庫.
得到數(shù)據(jù)庫路徑,在終端執(zhí)行 sqlite3 路徑來啟動SQLite數(shù)據(jù)庫
常用命令:

  • .database:查看當(dāng)前數(shù)據(jù)庫
  • .tables:查看當(dāng)前數(shù)據(jù)庫里的數(shù)據(jù)庫表
  • .help查看sqlite3支持的命令
    我們編寫代碼時可以用來測試SQL語句.

sqlite3API

1
2
3
4
5

sqlite3使用

添加library---libsqlite3.tbd,導(dǎo)入頭文件#import "sqlite3.h"

sqlite3的創(chuàng)建

步驟如下:

  1. 根據(jù)路徑,調(diào)用函數(shù)sqlite3_open()打開數(shù)據(jù)庫
  2. 使用sqlite3_exec函數(shù)執(zhí)行Create Table語句
  3. 使用sqlite3_close函數(shù)釋放資源

聲明一個sqlite3 *db變量,獲取沙盒創(chuàng)建資源路徑,一般放在沙盒路徑下的Documents文件夾下.橋接成C語言的字符串,調(diào)用sqlite3_open()打開數(shù)據(jù)庫

@interface SQLManage : NSObject{
    sqlite3 *db;
}
//獲取路徑
static const char *sqliteResoursePath(){
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = [[paths firstObject]stringByAppendingPathComponent:@"xxxx.sqlite"];
    return documentDirectory.UTF8String;
}
    //打開數(shù)據(jù)庫
    //參數(shù)一:數(shù)據(jù)庫文件所在的完整路徑, const char *
    //參數(shù)二:數(shù)據(jù)庫句柄 地址 &&sqlite3
    int status = sqlite3_open(sqliteResoursePath()?:”:memory:", &db);
    if (status != SQLITE_OK) {
        //SQLITE_OK 代表打開成功
        sqlite3_close(db);
        NSAssert(NO, @"數(shù)據(jù)庫打開失敗~");
    }

建表
CREATE TABLE [IF NOT EXISTS] 表名(字段名稱 字段類型 [完整性約束條件],完整性約束條件], .....)ENGINE=存儲引擎 CHARSET=編碼方式;

 char *sql = "create table if not exists Student(id integer primary key autoincrement,name varchar(10),age integer,score float default 0.0,sex text,desc text)”;

關(guān)于完整性約束條件

約束條件 含義
UNSIGNED 無符號,沒有負(fù)數(shù),從0開始
ZEROFILL 零填充,當(dāng)數(shù)據(jù)的顯示長度不夠的時候,可以使用前補(bǔ)0的效果填充至指定長度,字段會自動添加UNSIGNED
NOT NULL 非空約束,也就是插入值的時候,這個字段必須要給值,值不能為空
DEFAULT 默認(rèn)值.如果插入記錄的時候沒有給字段賦值,則使用默認(rèn)值
PRIMARY KEY 主鍵,標(biāo)識記錄的唯一性,值不能重復(fù),一個表只能有一個主鍵,自動禁止為空
AUTO_INCREMENT 自動增長,只能用于數(shù)值列,而且配合索引使用,默認(rèn)起始值從1開始,每次增長1
UNIQUE KEY 唯一性,一個表中可以有多個字段是唯一索引,同樣的值不能重復(fù),但是NULL值除外
FOREIGN KEY 外鍵約束
        char *error;
//數(shù)據(jù)庫語句
        char *sql = "create table if not exists user(id integer primary key autoincrement,name text,desc text)";
        //執(zhí)行SQL語句
        //參數(shù)一: 數(shù)據(jù)庫對象
        //參數(shù)二: 數(shù)據(jù)庫語句
        //參數(shù)三: 回調(diào)函數(shù)
        //參數(shù)四: 回調(diào)函數(shù)的引用(傳遞參數(shù))
        //參數(shù)五: 錯誤信息
       int execStatus = sqlite3_exec(db, sql, NULL, NULL, &error);
        if (execStatus != SQLITE_OK) {
            NSLog(@"execSql failed:%s",error);
            NSAssert(NO, @"create table falied”);
        }else{
            NSLog(@"exec sql success!");
        }
        //關(guān)閉數(shù)據(jù)庫
         sqlite3_close(db);

添加數(shù)據(jù)

  1. sqlite3_open()打開數(shù)據(jù)庫
  2. 使用sqlite3_prepare_v2函數(shù)預(yù)處理SQL語句
  3. 使用sqlite3_bind_text|int..(類型)函數(shù)綁定參數(shù)
  4. 使用sqlite3_step函數(shù)執(zhí)行SQL語句,遍歷結(jié)果集合.
- (void)insert:(NSString *)name desc:(NSString *)desc{
    
    char *insertSQL = "insert into user values(null,?,?)";
    
    sqlite3_stmt *stmt;
    
    int result = sqlite3_prepare_v2(db, insertSQL, -1, &stmt, NULL);
    
    //預(yù)編譯成功
    if (result == SQLITE_OK) {
        //為第一個?綁定參數(shù)
        sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);
        //為第二個?綁定參數(shù)
        sqlite3_bind_text(stmt, 2, desc.UTF8String, -1, NULL);
        
        //執(zhí)行SQL語句
        result = sqlite3_step(stmt);
        if (result == SQLITE_DONE) {
            NSLog(@"插入成功~");
        }
        sqlite3_finalize(stmt);
    }
    //關(guān)閉數(shù)據(jù)庫
    sqlite3_close(db);
}

刪除表

drop table 表名

- (void)dropTable{
    
    char *drop = "drop table user";
    char *error;
    int result = sqlite3_exec(db, drop, NULL, NULL, &error);
    if (result != SQLITE_OK) {
        if (error) {
            NSLog(@"drop table failed,error:%s",error);
        }
    }else{
        NSLog(@"drop table success!");
    }
}

刪除記錄

delete from 表名 where ID = 2;
delete from 表名; ——表單內(nèi)容全部刪除(表單還在)

模糊刪除
delete from 表名 where name like '%楓%';
delete from 表名 where name = ‘小明’;
delete from 表名 where name = ‘小明’ and age = ’20’;
delete from 表名 where name = ‘小明’ and ID > 5;

更新記錄

update 表名 set name = ‘小明’ where ID = 1;
update 表名 set name = ‘小明’, age = ’20’ where ID = 1;

使用sqlite進(jìn)行數(shù)據(jù)查找操作

select:
select * from 表名; 查詢所有數(shù)據(jù)
select name from 表名;
select name, age from 表名;

where:
select * from 表名 where name like '%舒%';
select * from 表名 where name like '%舒%' and ID == 1;
select * from 表名 where name like '%舒%' and ID < 2;

select:
select count(*) from 表名
select sum(ID) from 表名
select avg(ID) from 表名

運(yùn)算符

= 或 == 或 like 等于

大于
< 小于
= 大于等于
<= 小于等于
<> 不等于
!> 不大于
!< 不小于
%小明% 包含子字符串”小明” 只用于like

  1. sqlite3_open()打開數(shù)據(jù)庫
  2. 使用sqlite3_prepare_v2函數(shù)預(yù)處理SQL語句
  3. 使用sqlite3_bind_text|int..(類型)函數(shù)綁定參數(shù)
  4. 使用sqlite3_step函數(shù)執(zhí)行SQL語句,遍歷結(jié)果集合.
  5. 使用sqlite3_column_text|int..(類型)等函數(shù)提取字段數(shù)據(jù)
//查詢
- (void)queryKey:(NSString *)key{
    
    //sqlite3_exec()一般執(zhí)行無須返回值的語句 DDL DML
    //如果需要執(zhí)行查詢語句,則先調(diào)用sqlite3_prepare_v2預(yù)處理查詢語句,然后循環(huán)調(diào)用sqlite3_step()取出查詢結(jié)果集.
    char *querySQL = "SELECT * FROM user where name like ?";
    
    sqlite3_stmt *statement;
    
    //v2代表新版本
    //預(yù)編譯SQL語句,sqlite3_stmt保存了預(yù)編譯結(jié)果的引用
   int result =  sqlite3_prepare_v2(db, querySQL, -1, &statement, nil);
    //預(yù)編譯成功
    if (result == SQLITE_OK) {
        
        //%代表通配符
        NSString *keys = [NSString stringWithFormat:@"%%%@%%",key];
        sqlite3_bind_text(statement, 1, keys.UTF8String, -1, NULL);
        
        while (sqlite3_step(statement) == SQLITE_ROW) {
            int idKey = sqlite3_column_int(statement, 0);
            const unsigned char *name = sqlite3_column_text(statement, 1);
            const unsigned char *desc = sqlite3_column_text(statement, 2);
            NSLog(@"%d,%s,%s",idKey,name,desc);
        }
    }
    
}

FMDB的使用

單例類

#import "DBManage.h"
#import "FMDatabase.h"
#import "FMResultSet.h"
@implementation DBManage{
    FMDatabase *_dataBase;
}

+ (id)defaultDBManager{
    static DBManage *manager = nil;
    if (manager == nil) {
        manager = [[DBManage alloc]init];
    }
    return manager;
}
/*
 對于Model而言,重寫init方法目的在于瓶盛,創(chuàng)建容器最欠,創(chuàng)建對應(yīng)的對象,調(diào)用成員方法之前的準(zhǔn)備的工作
 對于View而言惩猫,重寫init方法目的在于 添加控件芝硬,達(dá)到自定制頁面的目的
 */
- (id)init{
    if (self = [super init]) {
        [self createDB];
    }
    return self;
}

建表

- (void)createDB{
    
    NSString *dbPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/DB"];
    NSLog(@"%@",dbPath);
    if (_dataBase == nil) {
        _dataBase = [FMDatabase databaseWithPath:dbPath];
    }
    //操作數(shù)據(jù)庫之前,一定要打開數(shù)據(jù)庫轧房,要不然所有的操作都無法執(zhí)行
    [_dataBase open];
    
    [self createTable];
}
- (void)createTable{

    NSString *sql = @"create table if not exists Contact(ID integer primary key autoincrement,name varchar(128),remark text,tel text,email varchar(200),head text);";
   
    [_dataBase executeUpdate:sql];
}

添加數(shù)據(jù)

- (void)addUser:(ContactModel *)user{
  
    NSString *sql = @"insert into Contact(name,head,email,tel,remark) values(?,?,?,?,?);";
    [_dataBase executeUpdate:sql,user.name,user.head,user.email,user.tel,user.remark];
}

刪除數(shù)據(jù)

- (void)deleteUser:(ContactModel *)user{
    //根據(jù)電話號碼刪除記錄
    NSString *sql =@"delete from Contact where tel=?;";
    [_dataBase executeUpdate:sql,user.tel];
}

更新數(shù)據(jù)

- (void)updateUser:(ContactModel *)user toUser:(ContactModel *)newUser{
    
    //1.找到對應(yīng)的用戶拌阴;
    NSString *sql = @"select ID from Contact where tel = ?;";
    FMResultSet *resultSet = [_dataBase executeQuery:sql,user.tel];
    NSString *ID = nil;
    if (resultSet.next) {
        ID =[resultSet stringForColumn:@"ID"];
    }
    //2.修改
    if (ID) {
        NSString *sql =@"update Contact set tel=?,name=?,email=?,head=?,remark=? where ID = ?;";
        [_dataBase executeUpdate:sql,newUser.tel,newUser.name,newUser.email,newUser.head,newUser.remark,ID];
    }
}

獲取所有數(shù)據(jù)

- (NSArray *)searchAllUsers{
    NSMutableArray *array = [NSMutableArray array];
    NSString *sql = @"select * from Contact;";
    FMResultSet *set = [_dataBase executeQuery:sql];
    while (set.next) {
        ContactModel *user = [[ContactModel alloc]init];
       user.name = [set stringForColumn:@"name"];
        user.tel = [set stringForColumn:@"tel"];
        user.email  = [set stringForColumn:@"email"];
       user.head = [set stringForColumn:@"head"];
        user.remark = [set stringForColumn:@"remark"];
       
        [array addObject:user];
    }
    return array;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奶镶,隨后出現(xiàn)的幾起案子迟赃,更是在濱河造成了極大的恐慌,老刑警劉巖厂镇,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纤壁,死亡現(xiàn)場離奇詭異,居然都是意外死亡捺信,警方通過查閱死者的電腦和手機(jī)酌媒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秒咨,你說我怎么就攤上這事喇辽。” “怎么了雨席?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵菩咨,是天一觀的道長。 經(jīng)常有香客問我陡厘,道長抽米,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任雏亚,我火速辦了婚禮缨硝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罢低。我一直安慰自己查辩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布网持。 她就那樣靜靜地躺著宜岛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪功舀。 梳的紋絲不亂的頭發(fā)上萍倡,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機(jī)與錄音辟汰,去河邊找鬼列敲。 笑死,一個胖子當(dāng)著我的面吹牛帖汞,可吹牛的內(nèi)容都是我干的戴而。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼翩蘸,長吁一口氣:“原來是場噩夢啊……” “哼所意!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起催首,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扶踊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后郎任,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秧耗,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年舶治,在試婚紗的時候發(fā)現(xiàn)自己被綠了分井。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胶台。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杂抽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情韩脏,我是刑警寧澤缩麸,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站赡矢,受9級特大地震影響杭朱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吹散,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一弧械、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧空民,春花似錦刃唐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浊猾,卻和暖如春抖甘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葫慎。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工衔彻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人偷办。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓艰额,卻偏偏與公主長得像,于是被迫代替她去往敵國和親爽篷。 傳聞我的和親對象是個殘疾皇子悴晰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容