未命名標(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

分頁:

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

多表查詢:

OC中代碼:

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

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

創(chuàng)建表
    char *error = nil;
    //sqlite3_exec對數(shù)據(jù)庫的操作:創(chuàng)建表,增刪改,都建議用這個(gè)方法,查建議用其他的
    //參數(shù) 1.數(shù)據(jù)庫對象 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ù)對字符串做一份拷貝。
                一般使用這兩個(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ù)是對"準(zhǔn)備語句"的封裝 (預(yù)處理語句->綁定參數(shù)->執(zhí)行語句->重置語句->釋放語句)
如果需要綁定二進(jìn)制數(shù)據(jù), 就必須要使用"準(zhǔn)備語句了"
sqlite_exec 用法相對簡單

整體耗時(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ù)庫
        // 參數(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)勢:1.封裝 2.提供了多線程訪問數(shù)據(jù)方式

三個(gè)主要的類:

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

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

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

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

推薦文章:

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,025評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評(píng)論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,970評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,157評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,410評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評(píng)論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,896評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,157評(píng)論 2 375

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