欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift學(xué)習(xí)教程之SQLite的基礎(chǔ)使用

 更新時(shí)間:2019年04月16日 11:26:27   作者:godiscoder  
這篇文章主要給大家介紹了關(guān)于Swift學(xué)習(xí)教程之SQLite的基礎(chǔ)使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Swift SQLite具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在我們的日常開發(fā)中,經(jīng)常會(huì)遇到用戶斷網(wǎng)或者網(wǎng)絡(luò)較慢的情況,這樣用戶在一進(jìn)入頁面的時(shí)候會(huì)顯示空白的頁面,那么如何避免沒網(wǎng)顯示空白頁面的尷尬呢?答案就是:先在網(wǎng)絡(luò)好的時(shí)候緩存一部分?jǐn)?shù)據(jù),這樣當(dāng)下次網(wǎng)絡(luò)情況不好的時(shí)候,至少用戶可以先看到之前緩存的內(nèi)容,已達(dá)到提高APP的用戶體驗(yàn)。

SQLite就是我們實(shí)現(xiàn)本地?cái)?shù)據(jù)緩存的一種方案,SQLite有以下優(yōu)點(diǎn):iOS內(nèi)嵌SQLite;經(jīng)過時(shí)間的驗(yàn)證;開源;跨平臺(tái)。
OK,廢話不多說,現(xiàn)在我們就開始進(jìn)入SQLite的體驗(yàn)之旅。當(dāng)然在開始之前我們要做一點(diǎn)準(zhǔn)備工作,畢竟我們不打沒有準(zhǔn)備的仗。

準(zhǔn)備工作

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

  • 導(dǎo)入SQLite3:import SQLite3
  • 創(chuàng)建一個(gè)Goods的類用來表示數(shù)據(jù)庫存儲(chǔ)的數(shù)據(jù)類型
  • 創(chuàng)建一個(gè)Goods類型的數(shù)組
  • 聲明一個(gè)dbPath和db的全局變量,聲明一個(gè)獲取libraryDirectory路徑的函數(shù)(數(shù)據(jù)庫存放路徑如何選擇

代碼如下:

class Goods {
 let name: String!
 let weight: Int!
 var price: Double!
 
 init(name: String, weight: Int, price: Double) {
  self.name = name
  self.weight = weight
  self.price = price
 }
}

let goods = Goods(name: "computer", weight: 10, price: 2000.0)
var goodArr = [Goods]()
var dbPath = ""
var db: OpaquePointer?

func createData() {
 for index in 0...4 {
  let goods = Goods(name: "computer" + "\(index)", weight: index * 10, price: 20.0)
  goodArr.append(goods)
 }
}

func fetchLibraryPath() {
 if let libraryPathString = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first {
  let pathURL = URL(fileURLWithPath: libraryPathString).appendingPathComponent("goods.sqlite")
  dbPath = pathURL.path
 }
}

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

func openDatabase() -> OpaquePointer? {
 var db: OpaquePointer?
 if sqlite3_open(dbPath, &db) == SQLITE_OK {
  resultLabel.text = "成功打開數(shù)據(jù)庫,路徑:\(dbPath)"
  return db
 } else {
  resultLabel.text = "打開數(shù)據(jù)庫失敗"
  return nil
 }
}

通過上面的代碼我們可以看到,首先聲明了一個(gè)OpaquePointer類型的可選值db,接下來調(diào)用了sqlite3_open()方法,該方法的作用是:如果之前創(chuàng)建了數(shù)據(jù)庫那么直接打開,若沒創(chuàng)建會(huì)直接創(chuàng)建一個(gè)。如果該方法調(diào)用成功,他會(huì)返回一個(gè)OpaquePointer的值賦值給你傳遞進(jìn)去的db。

SQLITE_OK是一個(gè)定義在SQLite庫中的一個(gè)常量,它代表一個(gè)Int32的0。SQLite的大多數(shù)函數(shù)都會(huì)返回一個(gè)Int32的值,例如SQLITE_ROW (100)、SQLITE_DONE (101)等,詳細(xì)列表你可以查看這里

現(xiàn)在你可以通過調(diào)用db = openDatabase()來打開或者創(chuàng)建一個(gè)數(shù)據(jù)庫了,正常情況下你會(huì)看見成功打開數(shù)據(jù)庫,路徑:xxx/xxx.sqlite的輸出。

現(xiàn)在,我們已經(jīng)成功的創(chuàng)建了一個(gè)名字為goods.sqlite的數(shù)據(jù)庫了,接下來我們要做的就是創(chuàng)建一個(gè)表了。

創(chuàng)建表

代碼

func createTable() {
 let createTableString = """
       CREATE TABLE Computer(
       Id INT PRIMARY KEY NOT NULL,
       Name CHAR(255),
       Weight Int,
       Price Float);
       """
 var createTableStatement: OpaquePointer?
 // 第一步
 if sqlite3_prepare_v2(db, createTableString, -1, &createTableStatement, nil) == SQLITE_OK {
  // 第二步
  if sqlite3_step(createTableStatement) == SQLITE_DONE {
   resultLabel.text = "成功創(chuàng)建表"
  } else {
   resultLabel.text = "未成功創(chuàng)建表"
  }
 } else {
   
 }
 //第三步
 sqlite3_finalize(createTableStatement)
}

代碼說明

首先解釋一下createTableString:創(chuàng)建一個(gè)名字為Computer的表,Id為主鍵且不為空,Name不超過255個(gè)字符,Weight為Int類型,Price為Float類型。
然后創(chuàng)建了一個(gè)OpaquePointer?類型的變量用于下面的函數(shù):sqlite3_prepare_v2()。

  • 第一步:該函數(shù)會(huì)將createTableString編譯為字節(jié)代碼(byte code)并返回一個(gè)status code,這個(gè)函數(shù)執(zhí)行成功則表明database已經(jīng)準(zhǔn)備好了執(zhí)行任意的SQL statement(就是創(chuàng)建的SQL的字符串),該函數(shù)執(zhí)行成功后即會(huì)執(zhí)行sqlite3_step()。
  • 第二步:sqlite3_step()用來執(zhí)行編譯完成的statement handle(createTableStatement)并返回一個(gè)status code。
  • 第三步:在你每一次的操作完成后你必須調(diào)用sqlite3_finalize()去刪除你的statement以避免resource leak。注意:一旦一個(gè)statement被finalized,你不應(yīng)該再一次使用它。

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

代碼

func insertOneData() {
 let insertRowString = "INSERT INTO Computer (Id, Name, Weight, Price) VALUES (?, ?, ?, ?);"
 var insertStatement: OpaquePointer?
 //第一步
 if sqlite3_prepare_v2(db, insertRowString, -1, &insertStatement, nil) == SQLITE_OK {
   let id: Int32 = 1
   //第二步
   sqlite3_bind_int(insertStatement, 1, id)
   
   sqlite3_bind_text(insertStatement, 2, goods.name, -1, nil)
   
   sqlite3_bind_int(insertStatement, 3, Int32(goods.weight))
   
   sqlite3_bind_double(insertStatement, 4, goods.price)
   //第三步
   if sqlite3_step(insertStatement) == SQLITE_DONE {
    resultLabel.text = "插入數(shù)據(jù)成功"
   } else {
    resultLabel.text = "插入數(shù)據(jù)失敗"
   }
 } else {
  
 }
 //第四步
 sqlite3_finalize(insertStatement)
}

代碼說明

  • insertRowString中的?和前面的字段是對(duì)應(yīng)的,它只是占位符的意思,告訴編譯器當(dāng)真正執(zhí)行該語句的時(shí)候會(huì)插入相應(yīng)的值。
  • 第二步:sqlite3_bind_int()標(biāo)識(shí)你綁定了一個(gè)Int類型的值,該函數(shù)的第一個(gè)參數(shù)是你的statement(即insertStatement),第二個(gè)參數(shù)是?的位置在你的statement(注意該值是非零的),在此處也就是1,第三個(gè)參數(shù)為你想綁定的值。sqlite3_bind_text()函數(shù)表示你綁定的是一個(gè)text(一般用于比較長(zhǎng)的字符串)類型值,該函數(shù)比sqlite3_bind_int()多了額外的兩個(gè)參數(shù),第四個(gè)參數(shù)的意思是text的字節(jié)數(shù),一般穿-1,第五個(gè)參數(shù)是一個(gè)closure回調(diào),處理完string后調(diào)用。
  • 第三步第四步同上

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

代碼

func insertMutipleData() {
  let insertRowString = "INSERT INTO Computer (Id, Name, Weight, Price) VALUES (?, ?, ?, ?);"
  var insertStatement: OpaquePointer?
  //第一步
  if sqlite3_prepare_v2(db, insertRowString, -1, &insertStatement, nil) == SQLITE_OK {
    for (index, good) in goodArr.enumerated() {
      let id: Int32 = Int32(index + 1)
      //第二步
      sqlite3_bind_int(insertStatement, 1, id)
      
      sqlite3_bind_text(insertStatement, 2, good.name, -1, nil)
      
      sqlite3_bind_int(insertStatement, 3, Int32(good.weight))
      
      sqlite3_bind_double(insertStatement, 4, good.price)
      //第三步
      if sqlite3_step(insertStatement) == SQLITE_DONE {
        resultLabel.text = "插入數(shù)據(jù)成功"
      } else {
        resultLabel.text = "插入數(shù)據(jù)失敗"
      }
      //第四步
      sqlite3_reset(insertStatement)
    }
  } else {
    
  }
  //第五步
  sqlite3_finalize(insertStatement)
}

代碼說明

  • insertRowString同上。
  • 第四步:調(diào)用sqlite3_reset()函數(shù),以便下次循環(huán)再次執(zhí)行insertStatement
  • 第一步、第二步、第三步、第五步同上。

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

代碼

func updateData() {
  let updateString = "UPDATE Computer SET Name = 'changeComputer' WHERE Id = 2;"
  var updateStatement: OpaquePointer?
  //第一步
  if sqlite3_prepare_v2(db, updateString, -1, &updateStatement, nil) == SQLITE_OK {
    //第二步
    if sqlite3_step(updateStatement) == SQLITE_DONE {
      resultLabel.text = "更新成功"
    } else {
      
    }
  }
  //第三步
  sqlite3_finalize(updateStatement)
}

代碼說明

  • updateString:將Id==2的數(shù)據(jù)的Name字段改為changeComputer。
  • sqlite3_prepare_v2():準(zhǔn)備,sqlite3_step():執(zhí)行更新statement,sqlite3_finalize():結(jié)束。

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

代碼

func deleteData() {
  let deleteString = "DELETE FROM Computer WHERE Id = 2;"
  var deleteStatement: OpaquePointer?
  //第一步
  if sqlite3_prepare_v2(db, deleteString, -1, &deleteStatement, nil) == SQLITE_OK {
    //第二步
    if sqlite3_step(deleteStatement) == SQLITE_DONE {
      resultLabel.text = "刪除成功"
    }
  } else {
    
  }
  //第三步
  sqlite3_finalize(deleteStatement)
}

代碼說明

  • deleteString:刪除表中Id==2的數(shù)據(jù)。
  • sqlite3_prepare_v2():準(zhǔn)備,sqlite3_step():執(zhí)行刪除statement,sqlite3_finalize():結(jié)束。

查詢一條數(shù)據(jù)

代碼

func queryOneData() {
  let queryString = "SELECT * FROM Computer WHERE Id == 2;"
  var queryStatement: OpaquePointer?
  //第一步
  if sqlite3_prepare_v2(db, queryString, -1, &queryStatement, nil) == SQLITE_OK {
    //第二步
    if sqlite3_step(queryStatement) == SQLITE_ROW {
      //第三步
      let id = sqlite3_column_int(queryStatement, 0)
      
      let queryResultName = sqlite3_column_text(queryStatement, 1)
      let name = String(cString: queryResultName!)
      let weight = sqlite3_column_int(queryStatement, 2)
      let price = sqlite3_column_double(queryStatement, 3)
      
      
      resultLabel.text = "id: \(id), name: \(name), weight: \(weight), price: \(price)"
    } else {
      resultLabel.text = "error"
    }
  }
  //第四步
  sqlite3_finalize(queryStatement)
}

代碼說明

  • queryString:在Computer表中查找所有Id == 2的數(shù)據(jù)。
  • 第二步:注意此時(shí)要判斷的status code為SQLITE_ROW,如果該判斷為true則代表你查詢的數(shù)據(jù)存在在表里。
  • 第三步:sqlite3_column_int()函數(shù)是按照列數(shù)取數(shù)據(jù),第一個(gè)參數(shù)是statement,第二個(gè)參數(shù)則是該字段是第幾列(Id 為表里的第一列,從0開始計(jì)算)。sqlite3_column_text()要略微復(fù)雜一點(diǎn),他需要轉(zhuǎn)換類型通過String(cString: queryResultName!)。
  • 第一步、第四步同上

查詢多條數(shù)據(jù)

代碼

func queryAllData() {
  let queryString = "SELECT * FROM Computer;"
  var queryStatement: OpaquePointer?
  //第一步
  if sqlite3_prepare_v2(db, queryString, -1, &queryStatement, nil) == SQLITE_OK {
    //第二步
    while(sqlite3_step(queryStatement) == SQLITE_ROW) {
      //第三步
      let id = sqlite3_column_int(queryStatement, 0)
      
      let queryResultName = sqlite3_column_text(queryStatement, 1)
      let name = String(cString: queryResultName!)
      let weight = sqlite3_column_int(queryStatement, 2)
      let price = sqlite3_column_double(queryStatement, 3)
      
      
      resultLabel.text = "id: \(id), name: \(name), weight: \(weight), price: \(price)"
    }
  }
  //第四步
  sqlite3_finalize(queryStatement)
}

代碼說明

  • 第二步:此處為while循環(huán),當(dāng)查詢到最后一行時(shí)會(huì)返回SQLITE_DONE狀態(tài)碼來結(jié)束。
  • 第一步第三步第四步同上。

小結(jié)

通過上面我們可以總結(jié)出執(zhí)行一個(gè)statement的大概流程:sqlite3_prepare_v2():準(zhǔn)備,sqlite3_step():執(zhí)行statement,sqlite3_finalize():結(jié)束。好了,到這里SQLite3的增刪改查基本操作也就完事了。下一篇我們來了解一下SQLite的進(jìn)階用法。Bye~

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Swift面試題及答案整理

    Swift面試題及答案整理

    雖然Swift出現(xiàn)的時(shí)間不久,但是它已經(jīng)成為最流行的編程語言之一了。Swift的知識(shí)浩如煙海,但是怎么測(cè)試你掌握了多少?通過下面這篇整理關(guān)于Swift面試題及答案,可能會(huì)對(duì)你所掌握的Swift進(jìn)行一個(gè)判斷,需要的朋友可以參考借鑒。
    2017-01-01
  • Swift教程之類的析構(gòu)詳解

    Swift教程之類的析構(gòu)詳解

    這篇文章主要介紹了Swift教程之類的析構(gòu)詳解,在一個(gè)類的實(shí)例被釋放之前,析構(gòu)函數(shù)會(huì)被調(diào)用,本文即講解了析構(gòu)過程原理、析構(gòu)器操作等內(nèi)容,需要的朋友可以參考下
    2015-01-01
  • swift使用SDPhotoBriwser瀏覽圖片教程

    swift使用SDPhotoBriwser瀏覽圖片教程

    這篇文章主要為大家介紹了swift如何使用SDPhotoBriwser瀏覽圖片的教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • Swift如何使用類型擦除及自定義詳解

    Swift如何使用類型擦除及自定義詳解

    有很多地方會(huì)用到類型擦除,并且它們的作用的各不相同。下面這篇文章主要給大家介紹了關(guān)于Swift如何使用類型擦除及自定義的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-10-10
  • Swift中圖片資源使用流程的優(yōu)化方法詳解

    Swift中圖片資源使用流程的優(yōu)化方法詳解

    這篇文章主要給大家介紹了關(guān)于Swift中圖片資源使用流程的優(yōu)化方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 通過示例分析Swift單例模式

    通過示例分析Swift單例模式

    這篇文章主要介紹了通過示例分析Swift單例模式的三種方法,分別是全局變量,內(nèi)部變量,dispatch_once方式,有需要的小伙伴可以參考下。
    2015-06-06
  • Swift 3.0基礎(chǔ)學(xué)習(xí)之類與結(jié)構(gòu)體

    Swift 3.0基礎(chǔ)學(xué)習(xí)之類與結(jié)構(gòu)體

    最近在學(xué)swift 3.0,主要看的是蘋果的官方文檔,這里只是根據(jù)自己看官方文檔的理解所做的一些記錄,不是完整的翻譯,希望也對(duì)你有所幫助。下面這篇文章主要介紹了Swift 3.0基礎(chǔ)學(xué)習(xí)之類與結(jié)構(gòu)體的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能

    Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能

    這篇文章主要介紹了Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • swift 錯(cuò)誤處理do catch try try!使用詳解

    swift 錯(cuò)誤處理do catch try try!使用詳解

    這篇文章主要介紹了swift 錯(cuò)誤處理do catch try try!使用詳解的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • Swift實(shí)現(xiàn)3D輪播圖效果

    Swift實(shí)現(xiàn)3D輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)3D輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02

最新評(píng)論