ios學(xué)習(xí)筆記之SQLite初學(xué)者手冊(上)

一 前言

SQLite學(xué)習(xí)筆記

二 ios中數(shù)據(jù)存儲的方式

① Plist
特點:只能存儲系統(tǒng)自帶的數(shù)據(jù)類型,比如:NSDictionary,NSArray等等,自定義的對象無法存儲
② Preference (偏好設(shè)置,NSUserDefaults)
特點:本質(zhì)就是一個Plist文件,也是只能存儲系統(tǒng)自帶的數(shù)據(jù)類型,自定義的對象無法存儲
③ NSCoding(NSKeyedArchiver\NSKeyedUnarchiver)
特點:可以存儲自己定義的數(shù)據(jù)類型,但是都是一次性的全數(shù)據(jù)操作
④ SQLite3
特點:存儲一些大批量的數(shù)據(jù),排序,統(tǒng)計等操作
⑤ Core Data
特點:對SQLite3的一層面向?qū)ο蟮陌b,本質(zhì)還是要轉(zhuǎn)換成為對應(yīng)的SQLite語句去執(zhí)行
⑥ 鑰匙串
特點:1 APP之間數(shù)據(jù)共享
2 系統(tǒng)級別的加密,安全性高
3 當(dāng)APP被刪除時,存儲的數(shù)據(jù)依然存在

三 安裝數(shù)據(jù)庫管理工具

Navicat premium是一款數(shù)據(jù)庫管理工具,是一個可多重連線資料庫的管理工具,它可以讓你以單一程式同時連線到 MySQL、SQLite、Oracle 及 PostgreSQL 資料庫,讓管理不同類型的資料庫更加的方便。

下載地址:http://soft.macx.cn/
補(bǔ)丁也要下載。安裝好Navicat premium后,會有提示如何安裝補(bǔ)丁。

四 推薦SQLite教程

http://www.phpstudy.net/e/sql/sql_intro.html

五 基礎(chǔ)知識

數(shù)據(jù)庫的功能,增刪改查,簡稱CRUD,
create,retrieve,update,delete。

SQLite語句的種類分三種:
數(shù)據(jù)定義語句DDL(Data Definition Language):包括create、drop、alert等,在數(shù)據(jù)庫中創(chuàng)建新表或刪除表

數(shù)據(jù)操作語句DML(Data Manipulation Language):包括insert、delegate、update等,用于添加、刪除、修改表中的數(shù)據(jù)

數(shù)據(jù)查詢語句DQL(Data Query Language):關(guān)鍵字select在DQL中用的最多,可用于查詢表中的數(shù)據(jù),其他DQL常用的關(guān)鍵字有where、order by、group by、having

六 利用Navicat Premium練習(xí)常用語句
1 DDL:

創(chuàng)建表
CREATE TABLE if not EXISTS t_stu3(id integer PRIMARY KEY AUTOINCREMENT,name text not NULL,age integer,score real default 60)

說明:if not 代表如果不存在該表,才創(chuàng)建,primary key 是該表的關(guān)鍵字,AUTOINCREMENT表示自增長,
name text not NULL 表示name列為text類型,且不為空,score real default 60 表示score 是浮點型,默認(rèn)是60

刪除表
DROP TABLE if EXISTS t_stu3
在刪除時,要加上 if EXISTS 如果存在再刪

2 DML:

插入
insert INTO t_weibo(title,content,person_id) VALUES('你好','你好',2) // 給表t_weibo插入

刪除行
DELETE FROM t_weibo WHERE id > 5 //刪除id大于5的行
DELETE FROM t_weibo // 刪除所有行

更新
UPDATE t_stu2 SET age = 10 // 將表t_stu2的age字段,全部改成10

3 DQL:

LIMIT
分頁:
SELECT * from t_weibo LIMIT 0,2 //參數(shù)1:代表跳過多少行,參數(shù)2:代表一共取多少條
SELECT * from t_weibo LIMIT 2 //特殊用法,跳過0行,一共取2行

列出某列
SELECT title FROM t_weibo // 列出title列
SELECT title,content FROM t_weibo // 列出“title,content”兩列
SELECT * FROM t_weibo // 列出所有列

avg(x)
求平均值
SELECT avg(person_id) FROM t_weibo // 如果某行的person_id值為null,則不計算該列,但如果是0,則計算在內(nèi)

sum(x)
求某列的和
SELECT sum(person_id) FROM t_weibo

max(x)
最大值
SELECT max(person_id) from t_weibo

min(x)
最小值
SELECT min(person_id) FROM t_weibo

ORDER BY
按照指定規(guī)則列出所有列
SELECT * FROM t_weibo ORDER BY person_id ASC , id DESC // 按person_id列升序,id列降序排列(后面還可以再加規(guī)則)

兩個表相關(guān)聯(lián):

創(chuàng)建兩個表:t_weibo和t_person

t_weibo

QQ20170223-3@2x.png

t_person

QQ20170223-1@2x.png

設(shè)置t_weibo的person_id為外部關(guān)鍵字,對應(yīng)的是t_person的id
就是說person_id的取值,必須是t_person表的id值,無法取到t_person表里id值以外的值。


QQ20170223-2@2x.png

創(chuàng)建該外部關(guān)鍵字的代碼寫法可查看DDL:

CREATE TABLE "t_weibo" (
     "id" INTEGER NOT NULL,
     "title" TEXT,
     "content" TEXT,
     "person_id" INTEGER,
    PRIMARY KEY("id"),
    CONSTRAINT "forignKeyName" FOREIGN KEY ("person_id") REFERENCES "t_person" ("id")   // 為外部關(guān)鍵字person_id取名forignKeyName
)

查詢兩個表:
為表取別名:t_weibo AS tw
給t_weibo取別名tw

為即將顯示的字段取別名
count(*) as num

舉例:
SELECT count(*) as num from t_person AS tp , t_weibo AS tw WHERE person_id = tp.id // 外部關(guān)鍵字person_id = t_person.id
結(jié)果:

QQ20170223-4@2x.png

從兩個表中列出tpid(t_person.id的別名),twid(同理,t_weibo.id的別名),name 和 title 這四個列
SELECT tp.id as tpid, tw.id AS twid ,name,title from t_person AS tp , t_weibo AS tw WHERE person_id = tp.id

七 實戰(zhàn)演練

在swift項目中引用數(shù)據(jù)庫
① 先在項目里導(dǎo)入SQLite的文件,選擇libsqlite3.0.tbd

QQ20170223-1@2x.png

② 由于sqlite里面很多是用c語言寫的,我們必須要橋接才能用
command + n 快速創(chuàng)建一個文件,選擇創(chuàng)建橋接頭文件,然后將創(chuàng)建的文件刪除
(如果是想創(chuàng)建橋接頭文件,我們在oc項目里,創(chuàng)建文件時選中swift文件,這樣就好提示你是否需要創(chuàng)建橋接頭文件,同樣的,在swift項目里,你創(chuàng)建oc文件時,也會問你是否需要橋接頭文件,選是,就會主動把你創(chuàng)建了。)

在橋接頭文件里,引入sqlite3,輸入有誤不會有提示,需要到項目里敲出sqlite3的函數(shù),看看是否有提示,有,就引入正確

#import"sqlite3.h"

(所有函數(shù)都是以sqlite3開頭)

創(chuàng)建數(shù)據(jù)庫,選擇第一個方法

QQ20170223-5@2x.png

封裝一個簡單的工具類SQLiteTool,以便被調(diào)用

import UIKit

class SQLiteTool: NSObject {
    
    static let shareInstance = SQLiteTool()  // 將工具類設(shè)置成單例模式
    
    var db : OpaquePointer? = nil

// 初始化的時候就要創(chuàng)建好數(shù)據(jù)庫
    override init(){
        super.init()
        
        //        1 創(chuàng)建一個數(shù)據(jù)庫,一般選open這個方法,是用utf8編碼的,
        //        創(chuàng)建數(shù)據(jù)庫,如果數(shù)據(jù)庫路徑不存在,就幫你創(chuàng)建,如果存在,就直接打開,并且賦值給參數(shù)二
        //        參數(shù)一:數(shù)據(jù)庫路徑
        //        參數(shù)二:一個已經(jīng)打開的數(shù)據(jù)庫(如果后期要執(zhí)行sql語句,都需要借助這個對象)
        //        關(guān)于SQLite的后綴名,沒有要求,一般是sqlite,db,db3
        
        let path = "/Users/huwenkuan/Desktop/database/demo.sqlite" //創(chuàng)建路徑
        //        有返回值,如果是SQLITE_OK,就說明打開成功
        
        if sqlite3_open(path, &db) == SQLITE_OK{ 
            print("執(zhí)行成功")
        }else{
            print("執(zhí)行失敗")
        }
        
    }
    
    // 創(chuàng)建一個表
    func createTable() -> () {
        let sql = "create table if not exists t_stu(id integer Primary key autoincrement,name text not null,age integer,score real default 60)"; // 創(chuàng)建表的執(zhí)行語句
        
        let result = execute(sql: sql)
        
        if result {
            print("創(chuàng)建表成功")
        }else{
            print("創(chuàng)建表失敗")
        }
        
        

    }
    
    
    // 刪除表
    func dropTable() -> () {
        let sql = "drop table if exists t_stu"
        
        
        let result = execute(sql: sql)
        
        if result {
            print("刪除表成功")
        }else{
            print("刪除表失敗")
        }
        
        

    }
    
// sqlite3_exec語句會被頻繁用到,而不同的只有sql執(zhí)行語句,所以干脆將sql語句當(dāng)參數(shù)傳入,將方法封裝
    func execute(sql:String) -> Bool {
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
//對sqlite3_exec的參數(shù)進(jìn)行說明
//        參數(shù)一:已經(jīng)打開的數(shù)據(jù)庫
        //        參數(shù)二:要執(zhí)行的sql語句
        //        參數(shù)三:回調(diào)
        //        參數(shù)四:參數(shù)三 參數(shù)一
        //        參數(shù)五:錯誤信息
    }
    
    
}

創(chuàng)建另外一個類Student

import UIKit

class Student: NSObject {

    // 成員變量
    var name:String = ""
    var age:Int = 0
    var score:Float = 0.0
    
// 初始化
    init(name:String, age:Int, score:Float) {
        super.init()
        self.name = name
        self.age = age
        self.score = score
    }
    

// 插入一行數(shù)據(jù)到表
    func insertStudent() -> () {
        
        let sql = "insert into t_stu(name,age,score) values('\(name)',\(age),\(score))"
        
        if SQLiteTool.shareInstance.execute(sql: sql) {
            print("插入行成功")
        }else{
            print("插入行失敗")
        }
        
        
    }
    
    // 類方法,刪除某一行
   class  func deleteStu(name:String) -> () {
        let sql = "delete from t_stu where name = '\(name)'"
        
        if SQLiteTool.shareInstance.execute(sql: sql) {
            print("刪除行成功")
        }else{
            print("刪除行失敗")
        }
    }
    

// 更新表中數(shù)據(jù)
    func alertStu(newStu:Student) -> () {
        let sql = "update t_stu set name = '\(newStu.name)', age = \(newStu.age) ,score = \(newStu.score) where name = '\(name)'" // 更新條件說明:當(dāng)表中name等于當(dāng)前對象的name值時,再更新
        
     //    print(sql) //假如修改失敗,那么打印語句,然后拷貝到Navicat Premium里面執(zhí)行,查看報錯
        
        if SQLiteTool.shareInstance.execute(sql: sql) {
            print("修改行成功")
        }else{
            print("修改行失敗")
        }
        
    }
      
}

注意:假如修改失敗,那么打印語句,然后拷貝到Navicat Premium里面執(zhí)行,再查看報錯,例如: print(sql)

在控制器里

import UIKit

class ViewController: UIViewController { 
    override func viewDidLoad() {
        super.viewDidLoad()
}
    
// 點擊屏幕,依次執(zhí)行方法下面①②③④,隨時在Navicat premium查看執(zhí)行情況,及時刷新
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//   ①     SQLiteTool.shareInstance.createTable() // 創(chuàng)建表
        
//   ②     let stu = Student(name:"zhangsan",age:20,score:40)
//        stu.insertStudent() // 插入一行數(shù)據(jù)
        
//   ③    Student.deleteStu(name: "zhangsan") //類方法刪除一行
        
//  ④    let stu = Student(name:"lisi",age:40,score:99)
 //       let stu2 = Student(name: "wangwu", age: 18, score: 99.5)     
 //       stu.alertStu(newStu: stu2) // 更新數(shù)據(jù)
        
        
    }
    
  
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容