swift中使用sqlite3
import Foundation
/**
1. 打开数据库
2. 如果没有数据表,需要首先创表
3. 数据操作
*/
class SQLite {
var db: COpaquePointer = nil
/// 打开数据库
///
/// :param: dbname 数据库名称
///
/// :returns: 是否打开成功
func openDatabase(dbname: String) -> Bool {
// UnsafePointer<Int8> UnsafePointer<CChar>
// 对应C语言中的 char*
// filename 必须是完整的路径名
let path = dbname.documentPath()
println(path)
// sqlite3_open 如果如果数据库不存在,会新建数据库文件
// 如果数据库文件已经存在,就直接打开,返回句柄,不会对数据有任何影响
if sqlite3_open(path, &db) == SQLITE_OK {
println("打开数据库成功")
// 本质上只需要运行一次就可以了
if createTable() {
println("创表成功")
// TODO: 测试查询数据
let sql = "SELECT id, DepartmentNo, Name FROM T_Department;"
recordSet(sql)
} else {
println("创表失败")
}
} else {
println("打开数据库失败")
}
return false
}
/// 创建数据表,将系统需要的数据表,一次性创建
private func createTable() -> Bool {
// 准备所有数据表的 SQL
// 1> 每一个 SQL 完成后都有一个 ;
// 2> 将所有创表 SQL 写在一起,每一个换行添加一个 \n
let sql = "CREATE TABLE \n" +
"IF NOT EXISTS T_Department (\n" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" +
"DepartmentNo CHAR(10) NOT NULL DEFAULT '',\n" +
"Name CHAR(50) NOT NULL DEFAULT '' \n" +
"); \n" +
"CREATE TABLE IF NOT EXISTS T_Employee ( \n" +
"'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \n" +
"'name' TEXT NOT NULL, \n" +
"'age' INTEGER NOT NULL, \n" +
"'department_id' INTEGER, \n" +
"CONSTRAINT 'FK_DEP_ID' FOREIGN KEY ('department_id') REFERENCES 'T_Department' ('id') \n" +
");"
return execSQL(sql)
}
/// 执行没有返回值的 SQL 语句
///
/// :param: sql SQL 字符串
///
/// :returns: 是否成功
func execSQL(sql: String) -> Bool {
/**
1. 数据库指针
2. SQL 字符串的 C 语言格式
3. 回调,执行完成 SQL 指令之后的函数回调,通常都是 nil
4. 回调的第一个参数的指针
5. 错误信息,通常也传入 nil
*/
return sqlite3_exec(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil) == SQLITE_OK
}
/// 执行 SQL 返回一个结果集(对象数组)
///
/// :param: sql SQL 字符串
func recordSet(sql: String) {
// 1. 准备语句
var stmt: COpaquePointer = nil
/**
1. 数据库句柄
2. SQL 的 C 语言的字符串
3. SQL 的 C 语言的字符串长度 strlen,-1 会自动计算
4. stmt 的指针
5. 通常传入 nil
*/
if sqlite3_prepare_v2(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, -1, &stmt, nil) == SQLITE_OK {
// 单步获取SQL执行的结果 -> sqlite3_setup 对应一条记录
while sqlite3_step(stmt) == SQLITE_ROW {
// 获取每一条记录的数据
recordData(stmt)
}
}
}
/// 获取每一条数据的记录
///
/// :param: stmt prepared_statement 对象
func recordData(stmt: COpaquePointer) {
// 获取到记录
var count = sqlite3_column_count(stmt)
println("获取到记录,共有多少列 \(count)")
// 遍历每一列的数据
for i in 0..<count {
let type = sqlite3_column_type(stmt, i)
// 根据字段的类型,提取对应列的值
switch type {
case SQLITE_INTEGER:
println("整数 \(sqlite3_column_int64(stmt, i))")
case SQLITE_FLOAT:
println("小树 \(sqlite3_column_double(stmt, i))")
case SQLITE_NULL:
println("空 \(NSNull())")
case SQLITE_TEXT:
let chars = UnsafePointer<CChar>(sqlite3_column_text(stmt, i))
let str = String(CString: chars, encoding: NSUTF8StringEncoding)!
println("字符串 \(str)")
case let type:
println("不支持的类型 \(type)")
}
}
}
}
swift中使用sqlite3的更多相关文章
- 在Swift中实现 oc与swift的混编
在Swift中想要引用OC头文件(import),可采用混编的方法,这里以sqlite为例,采用OC-Swift桥的方式实现添加头文件1引入sqlite数据库的库文件 打开工程配置文件,在build ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON
项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...
- Swift中的可选链与内存管理(干货系列)
干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...
- 在Swift中实现单例方法
在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型
有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...
- swift 中指针的使用UnsafeMutablePointer
在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...
- swift 中数据类型那个的转换
在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,
随机推荐
- Codevs 1312 连续自然数和
1312 连续自然数和 题目描述 Description 对于一个自然数M,求出所有的连续的自然数段,使得这些连续自然数段的全部数字和为M.eg:1998+1999+2000+2001+2002=10 ...
- 解决element 照片墙上传时回显问题
1.先看看样式: <el-upload class="imgList" action="1165165" list-type="picture- ...
- 毕业N年后,请不要像我一样被档案烦死
目录 一. 提醒大学生:深刻重视档案,避免以后麻烦! 二.说说我因为档案造成的烦心事! 三.说说档案这档子事: 四.档案如此重要,为什么有些人却成了弃档族? 五.档案该怎么操作才能不当"弃档 ...
- mysql项目实战经验
一.项目的编码设置 目的:避免出现莫名其妙错误,笔者曾经就碰到因编码不对返回null而浪费大量时间:统一的编码可以减少解析的时间,提高效率 1.1修改my.ini文件 一般在C:\Program ...
- linux模拟http请求命令
Http请求指的是客户端向服务器的请求消息,Http请求主要分为get或post两种,在Linux系统下可以用curl和wget命令来模拟Http的请求.下面就来介绍一下Linux系统如何模拟Http ...
- VLAN-2-私有VLAN
好的设计方式通常要求工程师为每个vlan使用一个ip子网.然而在有些情况下,将设备分割到许多小VLAN中以增加安全性的需求,与节省可用子网的目标相互冲突.通过使用私有vlan,交换机能够分 ...
- JAVASCRIPT一维数转化为二维数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- HTML的基础结构
<html>内容</html> 解释:HTML文档的文档标记,也称为HTML开始标记 功能:这对标记分别位于网页的最前端和最后端 <head>内容</head ...
- React 实践记录 01 组件开发入门
Introduction 本文组成: Ryan Clark文章Getting started with React的翻译. 博主的实践心得. React由Facebook的程序员创建,是一个非常强大的 ...
- kafka客户端发布record(消息)
kafka客户端发布record(消息)到kafka集群. 新的生产者是线程安全的,在线程之间共享单个生产者实例,通常单例比多个实例要快. 一个简单的例子,使用producer发送一个有序的key/v ...