介绍

一、sqlite是纯C语言中底层的数据库,在OC和Swift中都是经常使用的数据库,在开发中,可以使用代码创建数据库,可以使用图形化界面创建数据库。例如SQLiteManager、SQLiteStudio等

二、对常用的一些方法进行解释如下:

OpaquePointer: *db,数据库句柄,跟文件句柄FIFL类似,这里是sqlite3指针;

sqlite3_stmt: *stmt,相当于ODBC的Command对象,用于保存编译好的SQL语句;

sqlite3_open(): 打开数据库,没有数据库时创建;

sqlite3_exec(): 执行非查询的SQL语句;

sqlite3_step(): 在调用sqlite3_prepare后,使用这个函数在记录集中移动;

sqlite3_close():关闭数据库文件;

sqlite3_column_text():取text类型的数据;

sqlite3_column_blob():取blob类型的数据;

sqlite3_column_int():取int类型的数据;

三、使用SQLiteStudio创建数据库,然后导出到桌面,再拖到项目中,最后通过代码拷贝到Documens下进行操作,并获取数据库路径

  

Person.swift

//  Person.swift
// swiftDemo
//
// Created by 夏远全 on 2017/2/20.
// Copyright © 2017年 夏远全. All rights reserved.
// import UIKit class Person: NSObject { var name:String?
var password:String?
var email:String?
var age:Int?
}

DatabaseOperation.swift

(1)打开数据库

    //不透明指针,对应C语言中的void *,这里指sqlit3指针
private var db:OpaquePointer? = nil //初始化方法打开数据库
required init(dbPath:String) {
print("db path:" + dbPath) //String类的路径,转换成cString
let cpath = dbPath.cString(using: .utf8) //打开数据库
let error = sqlite3_open(cpath!,&db) //数据库打开失败
if error != SQLITE_OK {
sqlite3_close(db)
}
}

(2)关闭数据库

    //关闭数据库
deinit {
self.closeDB()
}
func closeDB() -> Void {
sqlite3_close(db)
}

(3)创建表

//创建表
func creatTable() -> Bool {
//sql语句
let sql = "CREATE TABLE UserTable(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,username TEXT NOT NULL, password TEXT NOT NULL,email TEXT NOT NULL,age INTEGER)" //执行sql语句
let excuResult = sqlite3_exec(db, sql.cString(using: .utf8), nil, nil, nil) //判断是否执行成功
if excuResult != SQLITE_OK {
return false
}
return true
}

(4)插入数据

//插入数据
func addUser(user:Person) -> Bool { //sql语句
let sql = "INSERT INTO UserTable(username,password,email,age) VALUES(?,?,?,?);"; //sql语句转换成cString类型
let cSql = sql.cString(using: .utf8) //sqlite3_stmt指针
var stmt:OpaquePointer? = nil //编译
let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -1, &stmt, nil) //判断如果失败,获取失败信息
if prepare_result != SQLITE_OK {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to prepare SQL:\(sql)"
print(msg)
}
return false
} //绑定参数
//第二个参数,索引从1开始
//最后一个参数为函数指针
sqlite3_bind_text(stmt, 1, user.name!.cString(using: .utf8), -1, nil)
sqlite3_bind_text(stmt, 2, user.password!.cString(using: .utf8), -1, nil)
sqlite3_bind_text(stmt, 3, user.email!.cString(using: .utf8), -1, nil)
sqlite3_bind_int(stmt, 4, Int32(Int(user.age!))) //step执行
let step_result = sqlite3_step(stmt) //判断执行结果
if step_result != SQLITE_OK && step_result != SQLITE_DONE {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to execute SQL:\(sql)"
print(msg)
}
return false
} //finalize
sqlite3_finalize(stmt) return true
}

(5)查询数据

//查询数据
func readAllUsers() -> [Person] { //声明一个Person对象数组(查询的信息会添加到数组中)
var userArr = [Person]() //查询sql语句
let sql = "SELECT * FROM UserTable;"; //sqlite3_stmt指针
var stmt:OpaquePointer? = nil
let cSql = sql.cString(using: .utf8) //编译
let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -1, &stmt, nil)
if prepare_result != SQLITE_OK {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to prepare SQL:\(sql)"
print(msg)
}
} //step
while (sqlite3_step(stmt) == SQLITE_ROW) {
let user = Person() //循环从数据库数据,添加到数组
let cName = UnsafePointer(sqlite3_column_text(stmt, 0))
let cPwd = UnsafePointer(sqlite3_column_text(stmt, 1))
let cEmail = UnsafePointer(sqlite3_column_text(stmt, 2))
let cAge = sqlite3_column_int(stmt, 3) user.name = String.init(cString: cName!)
user.password = String.init(cString: cPwd!)
user.email = String.init(cString: cEmail!)
user.age = Int(cAge) userArr += [user]
} //finalize
sqlite3_finalize(stmt) return userArr
}

(6)更新数据

//更新数据
func updateUser(name:String,toName:String) -> Bool { //更新sql语句
let sql = "update UserTable set username = '\(toName)' where username = '\(name)'"; //sqlite3_stmt指针
var stmt:OpaquePointer? = nil
let cSql = sql.cString(using: .utf8) //编译sql
let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -1, &stmt, nil) //判断如果失败,获取失败信息
if prepare_result != SQLITE_OK {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to prepare SQL:\(sql)"
print(msg)
}
return false
} //step执行
let step_result = sqlite3_step(stmt) //判断执行结果,如果失败,获取失败信息
if step_result != SQLITE_OK && step_result != SQLITE_DONE {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to execute SQL:\(sql)"
print(msg)
}
return false
} //finalize
sqlite3_finalize(stmt) return true
}

(7)删除数据

//删除数据
func deleteUser(username:String) -> Bool { //删除sql语句
let sql = "delete from UserTable where username = '\(username)'"; //sqlite3_stmt指针
var stmt:OpaquePointer? = nil
let cSql = sql.cString(using: .utf8) //编译sql
let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -1, &stmt, nil) //判断如果失败,获取失败信息
if prepare_result != SQLITE_OK {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to prepare SQL:\(sql)"
print(msg)
}
return false
} //step执行
let step_result = sqlite3_step(stmt) //判断执行结果,如果失败,获取失败信息
if step_result != SQLITE_OK && step_result != SQLITE_DONE {
sqlite3_finalize(stmt)
if (sqlite3_errmsg(self.db)) != nil {
let msg = "SQLiteDB - failed to execute SQL:\(sql)"
print(msg)
}
return false
} //finalize
sqlite3_finalize(stmt) return true
}

(8)复制数据库路径

//将Bundle.main路径下的数据库文件复制到Documents下
class func loadDBPath() -> String { //声明一个Documents下的路径
let dbPath = NSHomeDirectory() + "/Documents/RWDataTest.db" //判断数据库文件是否存在
if !FileManager.default.fileExists(atPath: dbPath) { //获取安装包内是否存在
let bundleDBPath = Bundle.main.path(forResource: "RWDataTest", ofType:"db")! //将安装包内的数据库到Documents目录下
do {
try FileManager.default.copyItem(atPath: bundleDBPath, toPath: dbPath)
} catch let error as NSError {
print(error)
}
} return dbPath
}

ViewController.swift测试

//  Created by 夏远全 on 2017/1/13.
// Copyright © 2017年 夏远全. All rights reserved.
// import UIKit class ViewController: UIViewController { override func viewDidLoad() {
super.viewDidLoad() //打开数据库
let path = DatabaseOperations.loadDBPath()
let dbOpearion = DatabaseOperations.init(dbPath:path)
print(path) //添加一张表
let person:Person = Person()
person.name = "张三"
person.password = "123566"
person.email = "zhangsan@163.com"
person.age = 30 //插入一条信息,通过Person对象来传值
let addBool = dbOpearion.addUser(user: person)
print(addBool) //查询
let personArray:[Person] = dbOpearion.readAllUsers()
print("共搜索到:\(personArray.count) 条数据") //更新
let updateBool = dbOpearion.updateUser(name: "张三", toName: "李四")
print(updateBool) //删除
let deleteBool = dbOpearion.deleteUser(username: "李四")
print(deleteBool) //关闭数据库
dbOpearion.closeDB()
}
}

swift3.0:sqlite3的使用的更多相关文章

  1. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)

    本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...

  3. Swift3.0变化分享

    Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...

  4. swift3.0变化总结

    Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...

  5. 关于for循环------swift3.0

    在程序开发当中,for循环使用的频率无疑是最高的.常用的swift循环是递增式遍历.当然各种循环,swift都能办到.但其大多采用关键字形式实现,大部分开发者更喜欢直接使用C式循环代码.在swift3 ...

  6. Swift2.3 --> Swift3.0 的变化

    Swift3.0语法变化 首先和大家分享一下学习新语法的技巧: 用Xcode8打开自己的Swift2.3的项目,选择Edit->Convert->To Current Swift Synt ...

  7. Swift3.0都有哪些变化

    从写第一篇Swift文章的时候到现在Swift已经从1.2发展到了今天的3.0,这期间由于Swift目前还在发展阶段并不能向下兼容,因此第一篇文章中的部分代码在当前的Xcode环境中已经无法运行.在W ...

  8. iOS开发 swift3.0中文版

    swift3.0中文版: http://pan.baidu.com/s/1nuHqrBb

  9. swift3.0的改变

    Swift在这2年的时间内,发展势头迅猛,在它开源后,更是如井喷一样,除了 iOS.mac 平台,还支持了 Linux. 而今年下半年, Swift 3.0 也会随之发布.https://github ...

  10. Swift3.0语言教程字符串与URL的数据转换与自由转换

    Swift3.0语言教程字符串与URL的数据转换与自由转换 Swift3.0语言教程字符串与URL的数据转换 Swift3.0语言教程字符串与URL的数据转换与自由转换,字符串中的字符永久保存除了可以 ...

随机推荐

  1. leetcode 二叉搜索树中第K小的元素 python

          二叉搜索树中第K小的元素     给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元 ...

  2. 23.python中的类属性和实例属性

    在上篇的时候,我们知道了:属性就是属于一个对象的数据或者函数,我们可以通过句点(.)来访问属性,同时 python 还支持在运作中添加和修改属性. 而数据变量,类似于: name = 'scolia' ...

  3. android activity 启动模式

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 1,标准的, 2,单个 顶部 3,单个 任务 4,单个 实例 标准的 就是 每启动一次这 ...

  4. Gym 100646 Problem E: Su-Su-Sudoku 水题

    Problem E: Su-Su-Sudoku/center> 题目连接: http://codeforces.com/gym/100646/attachments Description By ...

  5. 使用 IntraWeb (24) - 基本控件之 TIWFileUploader、TIWFile

    TIWFileUploader 是基于 Ajax 的上传控件, 最初是 Andrew Valums 开发, 从 IntraWeb XIV 纳入并替换 TIWFile. 虽然从组件面板上还能看到 TIW ...

  6. IMG镜像写盘工具physdiskwrite,用于MikroTik RouterOS的安装(Windows)

    常用img的备份: 1.linux下使用dd,Windows下使用WinImage 2.或者还有很多,比如再生龙等等. img还原: 1.Win32DiskImager 2.physdiskwrite ...

  7. Java中的锁(转)

    Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...

  8. HDU 4763 Theme Section (2013长春网络赛1005,KMP)

    Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. Revit API过滤元素类别(FamilySymbol与FamilyInstance)

    仅OfCategory()过滤的元素包含系统FamilySymbolOfClass(typeof(FamilyInstance))过滤出来文档中族实例. ;         ;         ;   ...

  10. 采用模拟账号读取Exchange server未读邮件的注意事项(链接邮箱问题)【转】

    最近做项目碰到Exchange中,用EWS API方法读取的未读邮箱(ConnectingIdType.PrincipalName设置该属性的方法)附带代码部分: 核心代码 using Microso ...