• SQLite的使用--SQLite语句


    一.SQLite的介绍
     
    1.为什么要存储数据?
     
         1.1 手机数据大多都是从网络加载的,不存储,每次滚动界面都要从新发送网络请求加载数据,浪费流量
         1.2 当用户没网的时候,就不能正常显示界面了
         1.3 将数据存储到本地,不用每次加载,没网的时候也可从本地存储的数据拿来显示
     
    2.存储数据的方式
      
         Plist(NSArrayNSDictionary)
              特点: 只能存储系统自带的数据类型, 比如NSDictory, NSArray等等. 自定义的对象无法存储
         Preference(偏好设置NSUserDefaults)
              特点: 本质就是一个plist文件; 也是只能存储系统自带的数据类型, 自定义的对象无法存储
         NSCoding(NSKeyedArchiverNSkeyedUnarchiver)
    特点: 可以存储自己定义的数据类型, 但是都是一次性的全数据操作
         SQLite3
              特点: 存储一些大批量的数据, 排序, 统计等操作
         Core Data
              特点: 对SQLite3的一层面向对象的包装, 本质还是要转换成为对应的SQL语句去执行
         在所有的存储方式中,SQLite速度最快,效率最高.
     
    3.什么是SQLite?
    • SQLite是一款轻型的嵌入式关系数据库
    • 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
    • 目前广泛应用于移动设备中存储数据(Android/iOS)
    • 处理数据的速度非常快,效率非常高
    4.什么是数据库?
    • 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库(类似于excel表格)
    • 数据库可以分为2大种类(了解)
      • 关系型数据库(主流)
      • 对象型数据库 
    5.关系型数据库介绍
     
     
    二.Navicat软件的破解
     
    1.什么是Navicat?
         Navicat是数据库管理软件,支持大部分主流数据库(包括SQLite)(收费,要破解)
         可以通过图形化界面的方式来管理数据库
     
    2.有破解版,可以去网上搜索下载,自己安装,这里不做介绍
     
    三.Navicat软件的使用
     
    1.创建SQLite数据库
     

     
    2.创建表
         2.1 双击打开数据库,在tables中点击右键,选中NewTable
         2.2 创建表中对应的字段,点击”+”添加字段  
         2.3 保存,要设置表格名称. 名称规范:  t_名称 如: t_student
     
     
    3.设置主键,添加数据
         3.1 什么是主键
              主键就相当于身份证一样,用来区分每一条数据
     
     
         3.2 设置主键注意点
     
     
         3.3 添加,删除,修改数据
              3.31 直接点击”+” 添加数据 
                   注意:主键的值不要修改
              3.32 删除,选中一行,点击”-“ 直接删除  
                   注意:删除一组数据后,主键值就不会再被回收使用. 一个主键值只对应一条数据,无论数据是否存在
              3.33 修改数据
                   双击想要修改的数据,直接修改 
     
    四.SQLite的使用步骤
     
    1.创建数据库(一个用于存储数据的文件)
         通常后缀名为: .db 或 .sqlite
     
    2.创建表用于存储数据   
    • 创建表时需要指定该表有哪些字段
    • 比如学生表有:学号/姓名/年龄/身高等
    3.对表进行增删改查操作
    • 比如添加一条学生数据:型号:1/姓名:why/年龄:18/身高:1.88     
    五.SQL简介
     
    1.怎么在程序中使用SQLite?
         真实使用SQLite时用代码来操作的
     
    2.怎么用代码操作SQLite?
         使用SQL语句来操作
     
    3.SQL介绍  不做过多介绍,直接看下定义就行了
     
     
    六.在代码中使用DDL(数据定义语句)
     
    1.先导入libsqlite3.tba框架(c语言)
     
    2.创建桥接文件,配置桥接文件(不会的话,看之前笔记)
     
    3.创建数据库
           // 创建数据库
            // 文件路径 :
            // 1.获取数据库的存放路径(沙盒中)
            let filePath = "/Users/xiaomage/Desktop/123.sqlite"
            let cString = filePath.cStringUsingEncoding(NSUTF8StringEncoding)!
           
            // 2.定义数据库对象(后面还要用,定义一个属性替代)
            // var db : COpaquePointer = nil
           
            // 3.打开/创建 数据库对象
            if sqlite3_open(cString, &db) == SQLITE_OK {
                print("创建/打开数据库成功")
            } else {
                print("失败")
            }
        }
     
    4.创建表
         4.1 创建SQL语句
         4.2 执行语句(要对语句进行判断)  if  语句 == SQLITE_OK 
         4.3 创建表格式
                CREATE TABLE IF NOT EXISTS '表名' (
            '字段名' 类型(INTEGER, REAL, TEXT, BLOB)
                    NOT NULL    不允许为空
                    PRIMARY KEY    主键
                    AUTOINCREMENT 自增长,
            '字段名2' 类型,
            ...
        )
         4.4 语句说明    
    • CREATE TABLE:创建一张表
    • IF NOT EXISTS:不存在则创建
    • 't_student':表的名称
    • NOT NULL:不允许为空
    • PRIMARY KEY:主键
    • AUTOINCREMENT:自动增加
    • 'id' INTEGER:有一个ID字段,类型是INTEGER

     5.删除表
         5.1删除表的格式
         DROP TABLE IF EXISTS '表名';
     
         5.2 语句说明
         DROP TABLE:删除表
         IF EXISTS:存在则删除
         '表名':要删除的表的名称
     1        // 1.获取要执行的SQL语句
     2         let createTableSQL = "DROP TABLE IF EXISTS t_student;"
     3        
     4         // 2.执行语句
     5         if sqlite3_exec(db, createTableSQL.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil) == SQLITE_OK {
     6             print("删除表成功")
     7         } else {
     8             print("删除表失败")
     9         }
    10     }
     
    6.封装SQL语句
         6.1 创建/打开数据库的代码全部一样,可以封装起来
         6.2 创建语句,执行语句步骤都一样,只有 语句的内容不一样,可以把语句当做参数,封装起来
         6.3 封装工具类,最好把实例对象设计为单例
    class SQLiteManager {
       
        // 设计单例对象
        static let shareInstance : SQLiteManager = SQLiteManager()
       
        // 数据库对象
        var db : COpaquePointer = nil
    }
    
    
    // MARK:- 打开数据库的操作
    extension SQLiteManager {
        func openDB(filePath : String) -> Bool {
            // 1.将Swift字符串转成C语言的字符串
            let cString = filePath.cStringUsingEncoding(NSUTF8StringEncoding)!
           
            // 3.打开/创建数据库对象
            return sqlite3_open(cString, &db) == SQLITE_OK
        }
    }
    
    
    // MARK:- 执行SQL语句
    extension SQLiteManager {
        func execSQL(sqlString : String) -> Bool {
            // 1.将Swift字符串转成C语言的字符串
            let cSQLString = sqlString.cStringUsingEncoding(NSUTF8StringEncoding)!
           
            // 2.执行语句
            return sqlite3_exec(db, cSQLString, nil, nil, nil) == SQLITE_OK
        }
    }
     
    七.在代码中使用DML(数据操作语句)
     
    1.插入数据
         1.1 插入数据格式
    INSERT INTO 't_student' (name, age, height) VALUES ('why', 18, 1.88);
         1.2 语句说明
    • INSERT INTO: 插入数据
    • 't_student': 在哪一个表中插入数据
    • (数据的字段): 给哪些字段插入数据
    • VALUES ('why', 18, 1.88): 插入的具体值
     
     // 1.插入数据(获取插入语句)
     let insertSQL = "INSERT INTO t_student (name, age, height) VALUES ('why', 18, 1.88);"
     // 2.执行语句
     SQLiteManager.shareInstance.execSQL(insertSQL)
     
    2.更新数据
         1.1 更新数据格式
    UPDATE 't_student' SET 字段 = '值' WHERE 条件判断;
     
         1.2 语句说明
    • UPDATE: 跟新数据
    • 't_student': 在哪一个表中更新数据
    • SET 字段 = '值': 更新怎样的数据
    • WHERE 条件判断: 更新哪些数据
           // 1.获取更新语句
            let updateSQL = "UPDATE t_student SET name = 'yz';" 
            // 2.执行语句
            SQLiteManager.shareInstance.execSQL(updateSQL)
     
    3.删除数据
         3.1 删除数据格式
    DELETE FROM t_student;
    DELETE FROM t_student WHERE age < 50;
     
         3.2 语句说明
    • DELETE FROM: 从表中删除数据
    • t_student : 表名
    • 可以跟条件也可以不跟:不跟表示删除所有的数据
             // 1.获取删除语句
            let deleteSQL = "DELETE FROM t_student;"  
            // 2.执行语句
            SQLiteManager.shareInstance.execSQL(deleteSQL)
     
    4.真实开发如何插入数据
         4.1 真实开发插入数据,不可能一条一条去写
         4.2 一般来说,我们开发都是面向模型的
         4.3 可以把要插入的数据包装成模型
         4.4 在模型中提供方法,快速插入数据
         4.5 遍历模型数组,利用模型中快速插入数据的方法插入数据
         
     
    5.怎么把数据包装成模型?
         遍历数据,把数据的每一个字段作为模型的属性保存起来
         // 模拟从网络服务器中请求到很多数据(实际中数据是网络来的,这里自己写模拟)
            for _ in 0..<100 {
                let name = "zs(arc4random_uniform(100))"
                let age = Int(10 + arc4random_uniform(10))
                let height = 1 + Double(arc4random_uniform(10)) / 10.0
               
                let stu = Student(name: name, age: age, height: height)
               
                stus.append(stu)
            }
     
    模型中代码:
     1      class Student: NSObject {
     2          var name : String = ""
     3          var age : Int = 0
     4          var height : Double = 0.0
     5    
     6          init(name : String, age : Int, height : Double) {
     7              self.name = name
     8              self.age = age
     9              self.height = height
    10          }
    11      }
    12  
    13      extension Student {
    14          func insertDB() {
    15              // 1.插入数据(获取插入语句)
    16              let insertSQL = "INSERT INTO t_student (name, age, height) VALUES ('(name)', (age), (height));" 
    17              // 2.执行语句
    18              SQLiteManager.shareInstance.execSQL(insertSQL)
    19          }
    20      }
     
    控制器中快速插入     
    for stu in stus {
        stu.insertDB()
     }
     
    6.插入数据的优化
         6.1 如果有大量数据插入,在主线程执行,会阻塞ui
         6.2 插入大量数据怎么优化?
              6.21 在子线程进行数据插入
              6.22 手动开启事务
                    如果一条条数据进行插入时,那么每插入一条数据就会开启一次事务.(开启事务耗时)
                但是如果有明确的开启事务,那么系统就不会在插入每条数据时,再开启事务
     1    dispatch_async(dispatch_get_global_queue(0, 0)) { 
     2           //获取插入数据开始时间
     3             let startTime = CACurrentMediaTime()
     4             // 开启事务
     5             let startSQL = "BEGIN TRANSACTION;"
     6             SQLiteManager.shareInstance.execSQL(startSQL)
     7            
     8             for stu in self.stus {
     9                 stu.insertDB()
    10             }
    11             //关闭事务
    12             let commitSQL = "COMMIT TRANSACTION;"
    13             SQLiteManager.shareInstance.execSQL(commitSQL)
    14               //获取插入数据结束时间
    15             let endTime = CACurrentMediaTime()
    16               //获取插入数据耗时
    17             print(endTime - startTime)
    18         }      
    19     }
     
    八.在代码中使用DQL(数据查询语句)
     
    1.查询语句
      
     
    2.查询数据代码实现步骤
         2.1 获取查询语句
         2.2 执行查询语句(得到的结果保存到数组中,最好是字典数组)
         2.3 遍历数组,字典转模型
         2.4 从模型中读取数据
     
    代码实现:
     1        // 1.获取查询语句
     2         let querySQL = "SELECT * FROM t_student LIMIT 30, 30;";
     3        
     4         // 2.执行语句  (执行语句封装到了一个方法里面)
     5         guard let dictArray = SQLiteManager.shareInstance.querySQL(querySQL) else {
     6             return
     7         }
     8        
     9         // 3.遍历数组
    10         var tempArray = [Student]()
    11         for dict in dictArray {
    12             // 字典转模型
    13             tempArray.append(Student(dict: dict))
    14         }
    15        
    16         for stu in tempArray {
    17             print(stu.name, stu.age)
    18         }
    19  
    20  //执行语句代码实现
    21    func querySQL(querySQL : String) -> [[String : NSObject]]? {
    22         // 0.将Swift字符串转成C语言字符串
    23         let cString = querySQL.cStringUsingEncoding(NSUTF8StringEncoding)!
    24        
    25         // 1.定义游标(指针)
    26         var stmt : COpaquePointer = nil
    27        
    28         // 2.给游标赋值
    29         // 1> 参数一: 数据库对象
    30         // 2> 参数二: SQL语句
    31         // 3> 参数三: 该SQL语句的长度 -1 --> 系统自动计算
    32         // 4> 参数四: 游标的地址
    33         guard sqlite3_prepare_v2(db, cString, -1, &stmt, nil) == SQLITE_OK else {
    34             return nil
    35         }
    36        
    37         // 3.取出所有的数据
    38         // 3.1.定义字典数组
    39         var dictArray = [[String : NSObject]]()
    40        
    41         // 3.2.判断是否有该条数据
    42         while sqlite3_step(stmt) == SQLITE_ROW {
    43             // 3.3.获取字段的个数
    44             let count = sqlite3_column_count(stmt)
    45             // 3.4.定义字典
    46             var dict = [String : NSObject]()
    47             // 3.5.遍历每一个字典
    48             for i in 0..<count {
    49                 // 3.6.取出该列的键
    50                 let ckey = sqlite3_column_name(stmt, i)
    51                 guard let key = String(UTF8String : ckey) else {
    52                     continue
    53                 }
    54                 // 3.7.取出该列的值
    55                 let cvalue = UnsafePointer<Int8>(sqlite3_column_text(stmt, i))   
    56                 //将c语言字符串转成swift字符串 
    57                 let value = String(UTF8String : cvalue)
    58                
    59                 // 3.8.将键值对放入到字典中
    60                 dict[key] = value
    61             }
    62             // 3.9.将字典放入到数组中
    63             dictArray.append(dict)
    64         }
    65         return dictArray
    66     }
    67     }
     
    九.FMDB框架的使用
     
    1.FMDB框架的作用?
         FMDB是用来简化操作数据库的框架
     
    2.FDMB的基本使用
         2.1 创建数据库
    private lazy var db : FMDatabase = FMDatabase(path: "/Users/lgp/Desktop/321.sqlite")
            // 创建FMDatabase对象
            // 打开/创建数据
            if db.open() {
                print("打开成功")
            } else  {
                print("失败")
            } 
     
         2.2 创建/删除 表   插入/更新/删除 数据
              本质都是一样的只有语句的内容不一样
              将语句内容换成对应的操作,就能执行该项操作(和SQLite语句一样)
      
    // 1.获取创建表的语句
    let createSQL = "INSERT INTO t_person (name, age, height) VALUES ('why', 18, 1.88);"   
    // 2.执行语句
    db.executeUpdate(createSQL, withArgumentsInArray: nil)
     
         2.3 查询数据
         var db : FMDatabase?
     
     1     func querySQL(querySQL : String) -> [[String : NSObject]]? {
     2         // 0.判断db是否有值  db定义为属性
     3         guard let db = db else {
     4             return nil
     5         }
     6         // 1.执行查询语句   结果为集合
     7         let results = db.executeQuery(querySQL, withArgumentsInArray: nil)
     8        
     9         // 2.获取数据
    10         // 2.0.定义数据
    11         var dictArray = [[String : NSObject]]()
    12        
    13         // 2.1.判断结果集中是否有内容
    14         while results.next() {
    15            
    16             let count = results.columnCount()
    17            
    18             var dict = [String : NSObject]()
    19            
    20             for i in 0..<count {
    21                 let key = results.columnNameForIndex(i)
    22                 let value = results.stringForColumnIndex(i)
    23                
    24                 dict[key] = value
    25             }
    26             dictArray.append(dict)
    27         }
    28         return dictArray
    29     }
         
     
  • 相关阅读:
    3组Alpha冲刺5/6
    3组Beta冲刺4/5
    3组Alpha冲刺6/6
    3组Beta冲刺2/5
    3组Beta冲刺3/5
    delegate Demo (一个关于System.Timers.Timer的Demo)
    System.Web.HttpException 与 HTTP Error 404.13 Not Found问题解决说明
    常用SQL关于表的操作
    设计模式学习笔记:单例模式
    JS 实践杂记
  • 原文地址:https://www.cnblogs.com/xiaotian666/p/5847185.html
Copyright © 2020-2023  润新知