SQLite3是嵌入到ios中的关系型数据库。对存储大规模的数据非常实用,使得不必将每个对象加到内存中。

支持NULL、INTEGER、REAL(浮点数字)、TEXT(字符串和文本)、BLOB(二进制对象)数据类型。

1、通过Firefox中的SQLite Manager组件创建一个数据库文件,并在其中创建创建一个Table,添加相关的参数。

2、将创建好的文件推到Xcode项目中,并在Link Binary With Libraries中添加libsqlite3.dylib依赖库。

3、新建一个C语言类型文件,对话框会自动添加桥接文件,在文件中添加语句#import<sqlite3.h>。

4、然后创建一个DataBaseOperations.swift文件来管理数据库。

在DataBaseOperation.swift文件中,申明一个数据库指针。

  1. //不透明指针,对应C语言里面的void *,这里指sqlite3指针
  2. private var db:COpaquePointer = nil

创建一个初始化方法,在初始化方法中执行打开数据库操作。

  1. //初始化方法打开数据库
  2. required init(dbPath:String)
  3. {
  4. print("db path:" + dbPath)
  5.  
  6. //String类的路径,转换成cString
  7. let cpath = dbPath.cStringUsingEncoding(NSUTF8StringEncoding)
  8.  
  9. //打开数据库
  10. let error = sqlite3_open(cpath!, &db)
  11.  
  12. //数据库打开失败处理
  13. if error != SQLITE_OK {
  14. sqlite3_close(db)
  15. }
  16. }
  1. deinit{
  2. self.colseDb()
  3. }
  4.  
  5. //关闭数据库
  6. func colseDb(){
  7.  
  8. sqlite3_close(db)
  9. }
  1. //代码创建表
  2. func createTable() -> Bool{
  3.  
  4. //sql语句
  5. let sql = "CREATE TABLE UserTable(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL, email TEXT, age INTEGER)"
  6.  
  7. //执行sql语句
  8. let execResult = sqlite3_exec(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil);
  9.  
  10. //判断是否执行成功
  11. if (execResult != SQLITE_OK) {
  12. return false
  13. }
  14.  
  15. return true
  16. }
  1. //插入一条信息
  2. func addUser(user: Person) -> Bool
  3. {
  4. //sql语句
  5. let sql = "INSERT INTO UserTable (username, password, email, age) VALUES (?, ?, ?, ?);";
  6. //sql语句转换成cString类型
  7.  
  8. let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
  9.  
  10. //sqlite3_stmt 指针
  11. var stmt:COpaquePointer = nil
  12.  
  13. //1.编译sql
  14. let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
  15.  
  16. //判断如果失败,获取失败信息
  17. if prepare_result != SQLITE_OK {
  18. sqlite3_finalize(stmt)
  19. if let error = String.fromCString(sqlite3_errmsg(self.db)) {
  20. let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
  21. print(msg)
  22. self.alert(msg)
  23. }
  24. return false
  25. }
  26.  
  27. //2.bind 绑定参数
  28. //第2个参数:索引从1开始
  29. //最后一个参数为函数指针
  30. sqlite3_bind_text(stmt, , user.name!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
  31. sqlite3_bind_text(stmt, , user.password!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
  32. sqlite3_bind_text(stmt, , user.email!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
  33. sqlite3_bind_int(stmt, , CInt(user.age!));
  34.  
  35. //3.step执行
  36. let step_result = sqlite3_step(stmt)
  37.  
  38. //判断执行结果,如果失败,获取失败信息
  39. if step_result != SQLITE_OK && step_result != SQLITE_DONE {
  40. sqlite3_finalize(stmt)
  41. if let err = String.fromCString(sqlite3_errmsg(self.db)) {
  42. let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
  43. print(msg)
  44. self.alert(msg)
  45. }
  46. return false
  47. }
  48.  
  49. //4.finalize
  50. sqlite3_finalize(stmt);
  51.  
  52. return true
  53. }
  1. //查询
  2. func readAllUsers() -> [Person]{
  3.  
  4. //声明一个Person对象数组(查询的信息会添加到该数组)
  5. var usersArr = [Person]()
  6.  
  7. //查询sql语句
  8. let sql = "SELECT * FROM UserTable;";
  9.  
  10. //sqlite3_stmt 指针
  11. var stmt:COpaquePointer = nil
  12. let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
  13.  
  14. //1.编译sql
  15. let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
  16. if prepare_result != SQLITE_OK {
  17. sqlite3_finalize(stmt)
  18. if let error = String.fromCString(sqlite3_errmsg(self.db)) {
  19. let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
  20. print(msg)
  21. self.alert(msg)
  22. }
  23. return usersArr
  24. }
  25.  
  26. //2.step
  27. while (sqlite3_step(stmt) == SQLITE_ROW) {
  28. let user = Person()
  29.  
  30. //循环 从数据库获取数据,添加到数组中
  31. let cName = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
  32. let cPwd = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
  33. let cEmail = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
  34. let cAge = sqlite3_column_int(stmt, )
  35.  
  36. user.name = String.fromCString(cName)
  37. user.password = String.fromCString(cPwd)
  38. user.email = String.fromCString(cEmail)
  39. user.age = Int(cAge)
  40.  
  41. usersArr += [user]
  42. }
  43.  
  44. //3.finalize
  45. sqlite3_finalize(stmt);
  46.  
  47. return usersArr
  48. }
  1. //更新一条信息
  2. func updateUser(name: String , toName:String) -> Bool
  3. {
  4. //更新sql语句
  5. let sql = "update UserTable set username = '\(toName)' where username = '\(name)'";
  6.  
  7. //sqlite3_stmt 指针
  8. var stmt:COpaquePointer = nil
  9. let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
  10.  
  11. //1.编译sql
  12. let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
  13.  
  14. //判断如果失败,获取失败信息
  15. if prepare_result != SQLITE_OK {
  16. sqlite3_finalize(stmt)
  17. if let error = String.fromCString(sqlite3_errmsg(self.db)) {
  18. let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
  19. print(msg)
  20. self.alert(msg)
  21. }
  22. return false
  23. }
  24.  
  25. //2.step执行
  26. let step_result = sqlite3_step(stmt)
  27.  
  28. //判断执行结果,如果失败,获取失败信息
  29. if step_result != SQLITE_OK && step_result != SQLITE_DONE {
  30. sqlite3_finalize(stmt)
  31. if let err = String.fromCString(sqlite3_errmsg(self.db)) {
  32. let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
  33. print(msg)
  34. self.alert(msg)
  35. }
  36. return false
  37. }
  38.  
  39. //4.finalize
  40. sqlite3_finalize(stmt);
  41.  
  42. return true
  43. }
  1. //删除一条信息
  2. func deleteUser(username: String) -> Bool
  3. {
  4. //删除sql语句
  5. let sql = "delete from UserTable where username = '\(username)'";
  6.  
  7. //sqlite3_stmt 指针
  8. var stmt:COpaquePointer = nil
  9. let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
  10.  
  11. //1.编译sql
  12. let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
  13.  
  14. //判断如果失败,获取失败信息
  15. if prepare_result != SQLITE_OK {
  16. sqlite3_finalize(stmt)
  17. if let error = String.fromCString(sqlite3_errmsg(self.db)) {
  18. let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
  19. print(msg)
  20. self.alert(msg)
  21. }
  22. return false
  23. }
  24.  
  25. //3.step执行
  26. let step_result = sqlite3_step(stmt)
  27.  
  28. //判断执行结果,如果失败,获取失败信息
  29. if step_result != SQLITE_OK && step_result != SQLITE_DONE {
  30. sqlite3_finalize(stmt)
  31. if let err = String.fromCString(sqlite3_errmsg(self.db)) {
  32. let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
  33. print(msg)
  34. self.alert(msg)
  35. }
  36. return false
  37. }
  38.  
  39. //4.finalize
  40. sqlite3_finalize(stmt);
  41.  
  42. return true
  43. }
  1. //定义一个报警器
  2. func alert(msg:String) {
  3. dispatch_async(dispatch_get_main_queue()) {
  4. let alert = UIAlertView(title: "SQLiteDB", message:msg, delegate: nil, cancelButtonTitle: "OK")
  5. alert.show()
  6. }
  7. }

因为工程数据库文件打包之后,会在NSBundle.mainBundle()路径下,该路径是只读的,不允许修改,所以必须把该路径下的数据库拷贝一份到Documents路径下,以后整个工程都将操作Documents路径下的数据库。

在ViewController中,添加一下代码。

  1. //声明一个Documents下的路径
  2. let dbPath = NSHomeDirectory() + "/Documents/RWDataTest.sqlite"
  3.  
  4. //判断数据库文件是否存在
  5. if !NSFileManager.defaultManager().fileExistsAtPath(dbPath)
  6. {
  7. //获取安装包内数据库路径
  8. let bundleDBPath = NSBundle.mainBundle().pathForResource("RWDataTest", ofType: "sqlite")!
  9.  
  10. //将安装包内数据库拷贝到Documents目录下
  11. do
  12. {
  13. try NSFileManager.defaultManager().copyItemAtPath(bundleDBPath, toPath: dbPath)
  14. }
  15. catch let error as NSError {
  16. print(error)//如果创建失败,error 会返回错误信息
  17. }
  18. }
  1. //打开数据库
  2. let dbOperation = DatabaseOperations(dbPath: dbPath)
  3.  
  4. //添加一张表
  5. dbOperation.createTable();
  6.  
  7. //插入一条信息, 通过Person对象来传值
  8. let person:Person = Person(name: "刘明洋", pwd: "liumingyang", email: "liumingyang@leadingdo.com", age: )
  9.  
  10. dbOperation.addUser(person)
  11.  
  12. //查询
  13. let personArray:[Person] = dbOperation.readAllUsers()
  14. print("共搜索到:\(personArray.count) 条数据" )
  15.  
  16. //更新
  17. dbOperation.updateUser("刘明洋", toName: "刘蕙通")
  18.  
  19. //删除
  20. dbOperation.deleteUser("刘蕙通")
  21.  
  22. //关闭数据库
  23. dbOperation.colseDb()

读写应用程序数据-SQLite3的更多相关文章

  1. 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作

    ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...

  2. 读写应用程序数据-CoreData

    coreData数据最终的存储类型可以是:SQLite数据库.XML.二进制.内存里.自定义的数据类型. 和SQLite区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性. 1.创建工程 ...

  3. C# 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC

    本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 官方 ...

  4. python 读写三菱PLC数据,使用以太网读写Q系列,L系列,Fx系列的PLC数据

    本文将使用一个gitHub开源的组件技术来读写三菱的plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...

  5. java android 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC

    本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...

  6. C#读写西门子PLC数据

    C#读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC 本文将使用一个gitHub开源的组件技术来读写西门子plc数 ...

  7. C#读写三菱PLC数据 使用TCP/IP 协议

    本文将使用一个Github开源的组件库技术来读写三菱PLC和西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能 ...

  8. 由于检索用户的本地应用程序数据路径时出错,导致无法生成 SQL Server 的用户实例

    /”应用程序中的服务器错误. 由于检索用户的本地应用程序数据路径时出错,导致无法生成 SQL Server 的用户实例.请确保该用户在此计算机上有本地用户配置文件.该连接将关闭. 堆栈跟踪: [Sql ...

  9. 微信小程序数据请求方法wx.request小测试

    微信小程序数据请求方法 wx.request wxml文件: <view> <textarea value="{{textdata}}"/> </vi ...

随机推荐

  1. ip_conntrack 实现

    启动时首先在ip_conntrack_standalone.c中调用 static int __init ip_conntrack_standalone_init(void) //proc相关部分省略 ...

  2. 【HDOJ】1042 N!

    肯定是大叔,本来以为用加法做乘法,后来想想这样麻烦,还是可以使用乘法的,按位乘,ov可以看成不止一位,程序如下所示: #include <stdio.h> #define MAX 4000 ...

  3. Oracle并行更新的两种方式(merge/update内联视图)

    对于Oracle的两表联合更新的场景(有A.B两表,以A.id=B.id关联,根据B表中的记录更新A表中的相应字段),一般有update内联视图和merge两种方式,下面举例介绍:   创建用例表: ...

  4. hdu4323Magic Number(dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=4323 去年的多校 编辑距离的变形 暴力居然过了 还想了好久别的方法,想得很头疼 #include <ios ...

  5. Servlet能读到JSessionID,读不到其它cookie问题

    Servlet的Cookie值保存与获取 今天测试设置和获取Cookie遇到了一点小问题,很奇怪的问题: 把J2ee服务部署在本地 8080端口:访问任何一个服务时,如果客户端没有cookie,则下发 ...

  6. MyEclipse常用操作技巧

    1.源码和帮助文档的的关连 下面以关联struts2-core-2.3.14.2.jar源代码为例: 如下为示意图 2.拷贝项目的时候,要注意 将项目的web-root fold改成更新后的名字项目名 ...

  7. C#实现调用Java类中方法

    基本思路: 用C#实现调用Java编写的类中的方法:重点是将Java编写的程序打包成Jar,然后使用开源工具IKVM将其转化成DLL控件,在.NET环境下调用. 分为以下步骤: 1.下载JDK6(注: ...

  8. 了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密

    关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据. 有些数据库,包括SQL Se ...

  9. [liu yanling]规范软件测试流程

    测试计划 做任何事情都会有输入输出,对于测试过程我们可以把输入理解为测试计划.测试环境准备.测试工具的选择等等,输出可以理解为测试结果.测试用例设计即可以理解为以测试计划为输入的输出,也可以理解为以测 ...

  10. 韦东山yy公开课笔记(1)--各种杂的问题

    1,第四期的智能猫眼会有打电话和发短信的功能吗?   答:会有打电话功能,硬件上支持打电话就会支持发短信,只是软件上是否实现发短信现在未定.因为短信延迟太严重,不是可靠的. 2,请问关于makefil ...