美文网首页IosiOS开发程序员
一篇文章教会你如何使用数据库

一篇文章教会你如何使用数据库

作者: 尕小天 | 来源:发表于2016-08-23 13:17 被阅读3286次

    一.SQLite的介绍

    1.为什么要存储数据?

    1.1 手机数据大多都是从网络加载的,不存储,每次滚动界面都要从新发送网络请求加载数据,浪费流量

    1.2 当用户没网的时候,就不能正常显示界面了

    1.3 将数据存储到本地,不用每次加载,没网的时候也可从本地存储的数据拿来显示

    2.存储数据的方式

    • Plist(NSArray\NSDictionary)
      特点: 只能存储系统自带的数据类型, 比如NSDictory, NSArray等等. 自定义的对象无法存储

    • Preference(偏好设置\NSUserDefaults)
      特点: 本质就是一个plist文件; 也是只能存储系统自带的数据类型, 自定义的对象无法存储

    • NSCoding(NSKeyedArchiver\NSkeyedUnarchiver)
      特点: 可以存储自己定义的数据类型, 但是都是一次性的全数据操作

    • SQLite3
      特点: 存储一些大批量的数据, 排序, 统计等操作

    • Core Data
      特点: 对SQLite3的一层面向对象的包装, 本质还是要转换成为对应的SQL语句去执行

    在所有的存储方式中,SQLite速度最快,效率最高.

    3.什么是SQLite?

    • SQLite是一款轻型的嵌入式关系数据库
    • 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
    • 目前广泛应用于移动设备中存储数据(Android/iOS)
    • 处理数据的速度非常快,效率非常高

    4.什么是数据库?

    • 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库(类似于excel表格)
    • 数据库可以分为2大种类(了解)
      • 关系型数据库(主流)
      • 对象型数据库

    5.关系型数据库介绍

    Paste_Image.png

    二.Navicat软件的破解

    1.什么是Navicat?

    Navicat是数据库管理软件,支持大部分主流数据库(包括SQLite)(收费,要破解)
    可以通过图形化界面的方式来管理数据库

    2.有破解版,可以去网上搜索下载,自己安装,这里不做介绍

    .

    三.Navicat软件的使用

    .

    1.创建SQLite数据库

    Paste_Image.png Paste_Image.png

    2.创建表

    2.1 双击打开数据库,在tables中点击右键,选中NewTable

    2.2 创建表中对应的字段,点击”+”添加字段

    2.3 保存,要设置表格名称. 名称规范: t_名称 如: t_student

    Paste_Image.png

    3.设置主键,添加数据

    .
    3.1 什么是主键
    主键就相当于身份证一样,用来区分每一条数据


    Paste_Image.png

    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介绍 不做过多介绍,直接看下定义就行了

    Paste_Image.png

    六.在代码中使用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
    Paste_Image.png

    5.删除表

    5.1删除表的格式

     DROP TABLE IF EXISTS '表名';
    

    5.2 语句说明

     DROP TABLE:删除表
     IF EXISTS:存在则删除
     '表名':要删除的表的名称
    
       // 1.获取要执行的SQL语句
        let createTableSQL = "DROP TABLE IF EXISTS t_student;"
    
        // 2.执行语句
        if sqlite3_exec(db, createTableSQL.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil) == SQLITE_OK {
            print("删除表成功")
        } else {
            print("删除表失败")
        }
    }
    

    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)
        }
    

    模型中代码:

     class Student: NSObject {
         var name : String = ""
         var age : Int = 0
         var height : Double = 0.0
    
         init(name : String, age : Int, height : Double) {
             self.name = name
             self.age = age
             self.height = height
         }
     }
    
     extension Student {
         func insertDB() {
             // 1.插入数据(获取插入语句)
             let insertSQL = "INSERT INTO t_student (name, age, height) VALUES ('\(name)', \(age), \(height));"
             // 2.执行语句
             SQLiteManager.shareInstance.execSQL(insertSQL)
         }
     }
    

    控制器中快速插入

       for stu in stus {
                 stu.insertDB()
             }
    

    6.插入数据的优化

    6.1 如果有大量数据插入,在主线程执行,会阻塞ui

    6.2 插入大量数据怎么优化?

    6.21 在子线程进行数据插入

    6.22 手动开启事务
    如果一条条数据进行插入时,那么每插入一条数据就会开启一次事务.(开启事务耗时)
    但是如果有明确的开启事务,那么系统就不会在插入每条数据时,再开启事务

     dispatch_async(dispatch_get_global_queue(0, 0)) {
          //获取插入数据开始时间
            let startTime = CACurrentMediaTime()
            // 开启事务
            let startSQL = "BEGIN TRANSACTION;"
            SQLiteManager.shareInstance.execSQL(startSQL)
    
            for stu in self.stus {
                stu.insertDB()
            }
            //关闭事务
            let commitSQL = "COMMIT TRANSACTION;"
            SQLiteManager.shareInstance.execSQL(commitSQL)
              //获取插入数据结束时间
            let endTime = CACurrentMediaTime()
              //获取插入数据耗时
            print(endTime - startTime)
        }
    }
    

    八.在代码中使用DQL(数据查询语句)

    .

    1.查询语句

    Paste_Image.png

    2.查询数据代码实现步骤

    2.1 获取查询语句
    2.2 执行查询语句(得到的结果保存到数组中,最好是字典数组)
    2.3 遍历数组,字典转模型
    2.4 从模型中读取数据

    代码实现:

       // 1.获取查询语句
        let querySQL = "SELECT * FROM t_student LIMIT 30, 30;";
    
        // 2.执行语句  (执行语句封装到了一个方法里面)
        guard let dictArray = SQLiteManager.shareInstance.querySQL(querySQL) else {
            return
        }
    
        // 3.遍历数组
        var tempArray = [Student]()
        for dict in dictArray {
            // 字典转模型
            tempArray.append(Student(dict: dict))
        }
    
        for stu in tempArray {
            print(stu.name, stu.age)
        }
    
     //执行语句代码实现
     func querySQL(querySQL : String) -> [[String : NSObject]]? {
        // 0.将Swift字符串转成C语言字符串
        let cString = querySQL.cStringUsingEncoding(NSUTF8StringEncoding)!
    
        // 1.定义游标(指针)
        var stmt : COpaquePointer = nil
    
        // 2.给游标赋值
        // 1> 参数一: 数据库对象
        // 2> 参数二: SQL语句
        // 3> 参数三: 该SQL语句的长度 -1 --> 系统自动计算
        // 4> 参数四: 游标的地址
        guard sqlite3_prepare_v2(db, cString, -1, &stmt, nil) == SQLITE_OK else {
            return nil
        }
    
        // 3.取出所有的数据
        // 3.1.定义字典数组
        var dictArray = [[String : NSObject]]()
    
        // 3.2.判断是否有该条数据
        while sqlite3_step(stmt) == SQLITE_ROW {
            // 3.3.获取字段的个数
            let count = sqlite3_column_count(stmt)
            // 3.4.定义字典
            var dict = [String : NSObject]()
            // 3.5.遍历每一个字典
            for i in 0..<count {
                // 3.6.取出该列的键
                let ckey = sqlite3_column_name(stmt, i)
                guard let key = String(UTF8String : ckey) else {
                    continue
                }
                // 3.7.取出该列的值
                let cvalue = UnsafePointer<Int8>(sqlite3_column_text(stmt, i))
                //将c语言字符串转成swift字符串
                let value = String(UTF8String : cvalue)
    
                // 3.8.将键值对放入到字典中
                dict[key] = value
            }
            // 3.9.将字典放入到数组中
            dictArray.append(dict)
        }
        return dictArray
    }
    }
    

    九.FMDB框架的使用

    .
    1.FMDB框架的作用?
    FMDB是用来简化操作数据库的框架

    2.FDMB的基本使用

    2.1 创建数据库

    private lazy var db : FMDatabase = FMDatabase(path: "/Users/xiaomage/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?
    
    func querySQL(querySQL : String) -> [[String : NSObject]]? {
        // 0.判断db是否有值  db定义为属性
        guard let db = db else {
            return nil
        }
        // 1.执行查询语句   结果为集合
        let results = db.executeQuery(querySQL, withArgumentsInArray: nil)
    
        // 2.获取数据
        // 2.0.定义数据
        var dictArray = [[String : NSObject]]()
    
        // 2.1.判断结果集中是否有内容
        while results.next() {
    
            let count = results.columnCount()
    
            var dict = [String : NSObject]()
    
            for i in 0..<count {
                let key = results.columnNameForIndex(i)
                let value = results.stringForColumnIndex(i)
    
                dict[key] = value
            }
            dictArray.append(dict)
        }
        return dictArray
    }

    相关文章

      网友评论

      本文标题:一篇文章教会你如何使用数据库

      本文链接:https://www.haomeiwen.com/subject/bgtnsttx.html