未命名標(biāo)題shu

數(shù)據(jù)表定義語句(DDL)

創(chuàng)建表:

create table if not exists <biaoming> (id integer primary key autoincrement,name text not NULL, age integer default 60)

刪除表:

drop table if exists <biaoming>

更改表名:

alter table <biaoming> rename to <xinbiaoming>

給表增加列:

alter table <biaoming> add column <lieming> name text <zhibiaofu>

數(shù)據(jù)表操作語句(DML)

增加:

insert into <biaoming> (name, age,score) values {'xiaowang',90,80}

修改:

update <> set name = 'xiaohong',age = 20

update <> set score = 30 where id > 30

刪除:

delete from <> where age is 18

DQL:查詢語句

select name, age from <>

select * from <>

統(tǒng)計(jì):

記錄所有age不為空的個(gè)數(shù)(記錄)select count(age) from <>

記錄某個(gè)字段平均值 select avg(age) from <>

求和:sum zuida:max zuixiao:min

排序:

select *from <> order by score ASC(升序) 或者用 DESC(降序)

select *from <> order by score ASC死陆,age DESC

分頁(yè):

select * from <> limit 1,3 1表示跳過1條,3表示跳過3條

多表查詢:

OC中代碼:

創(chuàng)建數(shù)據(jù)庫(kù)

    //參數(shù)1.數(shù)據(jù)庫(kù)文件的路徑 2.數(shù)據(jù)庫(kù)對(duì)象,要打開的數(shù)據(jù)庫(kù)
    //返回值表示操作的狀態(tài)碼
    int result = sqlite3_open(filename, &_db);
    if (result == SQLITE_OK)
    {
        NSLog(@"數(shù)據(jù)庫(kù)打開成功");
        return YES;
    }
    else
    {
        NSLog(@"數(shù)據(jù)庫(kù)打開失敗");
        //sqlite3_close 關(guān)閉數(shù)據(jù)庫(kù)的方法
        sqlite3_close(_db);
        return NO;
    }

創(chuàng)建表
    char *error = nil;
    //sqlite3_exec對(duì)數(shù)據(jù)庫(kù)的操作:創(chuàng)建表,增刪改,都建議用這個(gè)方法,查建議用其他的
    //參數(shù) 1.數(shù)據(jù)庫(kù)對(duì)象 2.sql語句 3.回調(diào)函數(shù)nil 4.回調(diào)函數(shù)的參數(shù)nil
    if (sqlite3_exec(_db, [str UTF8String], nil, nil, &error)==SQLITE_OK)
    {
        NSLog(@"創(chuàng)建表成功");
    }
    else
    {
        NSLog(@"創(chuàng)建表失敗:%s",error);
    }

增刪改查

//第一種方式sqlite3_exec

//sql為相關(guān)的增刪改語句
sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK

//另一種方式,預(yù)處理語句sqlite3_prepare_v2

let prepareSql = "INSERT INTO \(tableName)(\(columnNames)) values (\(valuesStr))"

        var stmt: COpaquePointer = nil

        // 預(yù)處理SQL語句, 并生成 "語句句柄" , 后續(xù)會(huì)使用這樣的語句句柄綁定數(shù)值, 并執(zhí)行

        if sqlite3_prepare_v2(db, prepareSql, -1, &stmt, nil) != SQLITE_OK
        {
            print("預(yù)處理失敗")
            // 釋放語句資源
            sqlite3_finalize(stmt)
            return false
        }

        var index: Int32 = 1

        for obj in values
        {

            if obj is Int
            {
                let temp: sqlite_int64 = obj as! sqlite_int64
                sqlite3_bind_int64(stmt, index, temp)
            } else if obj is Double
            {
                sqlite3_bind_double(stmt, index, obj as! Double)
            }else if obj is String
            {
                /**
                 第5個(gè)參數(shù)
                 此參數(shù)有兩個(gè)常數(shù)凉袱,SQLITE_STATIC告訴sqlite3_bind_text函數(shù)字符串為常量版述,可以放心使用;
                 而SQLITE_TRANSIENT會(huì)使得sqlite3_bind_text函數(shù)對(duì)字符串做一份拷貝婿失。
                一般使用這兩個(gè)常量參數(shù)來調(diào)用sqlite3_bind_text嫩痰。
                 */
                sqlite3_bind_text(stmt, index, obj as! String, -1, SQLITE_TRANSIENT)

            }else {
                continue
            }

            index++

        }

        var result: Bool = false
        if sqlite3_step(stmt) == SQLITE_DONE
        {
            print("插入成功")
            result = true
        }else
        {
            print("插入失敗")
            result = false

        }

        // 將語句復(fù)位
        if sqlite3_reset(stmt) != SQLITE_OK
        {
            print("復(fù)位失敗")
            result = false
        }

        // 釋放語句
        sqlite3_finalize(stmt)

        return result

處理大數(shù)據(jù)耗時(shí)問題

插入10000條數(shù)據(jù)

sqlite_exec 10000 5.8080689907074
sqlite_prepare 10000 5.93309998512268
sqlite_prepare 分解后, 準(zhǔn)備1次, 多次綁定/重置, 一次釋放 5.11254101991653
分析結(jié)果
所以: 如果執(zhí)行單條語句的話, 兩者效率幾乎一致
如果執(zhí)行多條語句, 建議使用"準(zhǔn)備語句"
兩者區(qū)別:
sqlite_exec 函數(shù)是對(duì)"準(zhǔn)備語句"的封裝 (預(yù)處理語句->綁定參數(shù)->執(zhí)行語句->重置語句->釋放語句)
如果需要綁定二進(jìn)制數(shù)據(jù), 就必須要使用"準(zhǔn)備語句了"
sqlite_exec 用法相對(duì)簡(jiǎn)單

整體耗時(shí), 依然達(dá)到5秒左右, 非常龐大
原因: 因?yàn)閟qlite3_exec, 或者 sqlite3_step 執(zhí)行語句時(shí), 都會(huì)自動(dòng)開啟事務(wù)-> 執(zhí)行語句 -> 提交事務(wù) 這樣的流程, 所以造成了, 多次開啟和提交事務(wù), 這個(gè)是非常耗時(shí)的操作
解決方案: 手動(dòng)開啟和提交事務(wù)即可, 這樣 系統(tǒng)就不會(huì)自動(dòng)開啟事務(wù)和提交事務(wù)了

代碼:


XMGSQLTool.shareInstance.beginTransaction()
for _ in 0...9999 {
stu.insertStudent()
}
XMGSQLTool.shareInstance.commitTransaction()

/** 開啟事務(wù) */
    func beginTransaction() -> Bool
    {
        let sql = "BEGIN TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

    /** 提交事務(wù) */
    func commitTransaction() -> Bool
    {
        let sql = "COMMIT TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

/** 回滾事務(wù)*/
    func rollBackTransaction() -> Bool
    {
        let sql = "ROLLBACK TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

開啟事務(wù)BEGIN TRANSACTION
提交事務(wù)COMMIT TRANSACTION
回滾事務(wù)ROLLBACK TRANSACTION

查詢的兩種方式

        let selectSql = "select * from t_student"

        // 方式1:
        // 參數(shù)1: 一個(gè)打開的數(shù)據(jù)庫(kù)
        // 參數(shù)2: 需要執(zhí)行的SQL語句
        // 參數(shù)3: 查詢結(jié)果回調(diào)(執(zhí)行0次或多次)
            // 參數(shù)1: 參數(shù)4的值
            // 參數(shù)2: 列的個(gè)數(shù)
            // 參數(shù)3: 結(jié)果值的數(shù)組
            // 參數(shù)4: 所有列的名稱數(shù)組
            // 返回值: 0代表繼續(xù)執(zhí)行一致到結(jié)束, 1代表執(zhí)行一次
        // 參數(shù)4: 回調(diào)函數(shù)的第一個(gè)值
        // 參數(shù)5: 錯(cuò)誤信息
        sqlite3_exec(db, selectSql, { (parameter: UnsafeMutablePointer<Void>, columnCount: Int32, values: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>, columnNames: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>) -> Int32 in

                let count = Int(columnCount)
                for i: Int in 0..<count
                {
                    let column = columnNames[i]
                    let columnStr = String(CString: column, encoding: NSUTF8StringEncoding)

                    let value = values[i]
                    let valueStr = String(CString: value, encoding: NSUTF8StringEncoding)
                    print(columnStr! + "= " + valueStr!)
                }

                return 0
            }, nil, nil)

            // 方式2:
//        var stmt: COpaquePointer = nil
//        if sqlite3_prepare(db, selectSql, -1, &stmt, nil) != SQLITE_OK
//        {
//            print("預(yù)處理失敗")
//            return
//        }
//
//        // 因?yàn)椴樵冋Z句中沒有占位?, 所以, 可以省略"綁定步驟"
//        // 執(zhí)行語句
//        // sqlite3_step, 當(dāng)使用這個(gè)方法時(shí), 執(zhí)行完畢后, 會(huì)自動(dòng)跳到結(jié)果集的下一行, 如果依然有記錄就返回SQLITE_ROW,
//       while sqlite3_step(stmt) == SQLITE_ROW
//       {
//        let columnCount = sqlite3_column_count(stmt)
//
//        for i in 0..<columnCount
//        {
//
//            //  獲取列的類型
//            let type = sqlite3_column_type(stmt, i)
//
//            if type == SQLITE_TEXT
//            {
//                let text = UnsafePointer<Int8>(sqlite3_column_text(stmt, i))
//                let str = String(CString: text, encoding: NSUTF8StringEncoding)
//                print(str)
//            }
//
//        }
//
//        }
//
//        sqlite3_finalize(stmt)

FMDB使用:

優(yōu)勢(shì):1.封裝 2.提供了多線程訪問數(shù)據(jù)方式

三個(gè)主要的類:

FMDatabase:是一個(gè)提供 SQLite 數(shù)據(jù)庫(kù)的類剿吻,用于執(zhí)行 SQL 語句。
FMResultSet:用在 FMDatabase 中執(zhí)行查詢的結(jié)果的類串纺。
FMDatabaseQueue:在多線程下查詢和更新數(shù)據(jù)庫(kù)用到的類丽旅。

數(shù)據(jù)庫(kù)創(chuàng)建

FMDatabase 是通過一個(gè) SQLite 數(shù)據(jù)庫(kù)文件路徑創(chuàng)建的,此路徑可以是以下三者之一:

一個(gè)文件的系統(tǒng)路徑纺棺。磁盤中可以不存在此文件魔招,因?yàn)槿绻淮嬖跁?huì)自動(dòng)為你創(chuàng)建。
一個(gè)空的字符串 @""五辽。會(huì)在臨時(shí)位置創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù),當(dāng) FMDatabase 連接關(guān)閉時(shí)外恕,該數(shù)據(jù)庫(kù)會(huì)被刪除杆逗。
NULL。會(huì)在內(nèi)存中創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)鳞疲,當(dāng) FMDatabase 連接關(guān)閉時(shí)罪郊,該數(shù)據(jù)庫(kù)會(huì)被銷毀。

推薦文章:

[an example]http://www.reibang.com/p/d60ee3c85d63

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尚洽,一起剝皮案震驚了整個(gè)濱河市悔橄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腺毫,老刑警劉巖癣疟,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異潮酒,居然都是意外死亡睛挚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門急黎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扎狱,“玉大人侧到,你說我怎么就攤上這事∮倩鳎” “怎么了匠抗?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)污抬。 經(jīng)常有香客問我汞贸,道長(zhǎng),這世上最難降的妖魔是什么壕吹? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任著蛙,我火速辦了婚禮,結(jié)果婚禮上耳贬,老公的妹妹穿的比我還像新娘踏堡。我一直安慰自己,他們只是感情好咒劲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布顷蟆。 她就那樣靜靜地躺著,像睡著了一般腐魂。 火紅的嫁衣襯著肌膚如雪帐偎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天蛔屹,我揣著相機(jī)與錄音削樊,去河邊找鬼。 笑死兔毒,一個(gè)胖子當(dāng)著我的面吹牛漫贞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播育叁,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼迅脐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了豪嗽?” 一聲冷哼從身側(cè)響起谴蔑,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎龟梦,沒想到半個(gè)月后隐锭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡计贰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年成榜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹦玫。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赎婚,死狀恐怖刘绣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挣输,我是刑警寧澤纬凤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站撩嚼,受9級(jí)特大地震影響停士,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜完丽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一恋技、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逻族,春花似錦蜻底、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至抠璃,卻和暖如春站楚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搏嗡。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工窿春, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人采盒。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓旧乞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親纽甘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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