读写应用程序数据-SQLite3
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文件中,申明一个数据库指针。
- //不透明指针,对应C语言里面的void *,这里指sqlite3指针
- private var db:COpaquePointer = nil
创建一个初始化方法,在初始化方法中执行打开数据库操作。
- //初始化方法打开数据库
- required init(dbPath:String)
- {
- print("db path:" + dbPath)
- //String类的路径,转换成cString
- let cpath = dbPath.cStringUsingEncoding(NSUTF8StringEncoding)
- //打开数据库
- let error = sqlite3_open(cpath!, &db)
- //数据库打开失败处理
- if error != SQLITE_OK {
- sqlite3_close(db)
- }
- }
- deinit{
- self.colseDb()
- }
- //关闭数据库
- func colseDb(){
- sqlite3_close(db)
- }
- //代码创建表
- func createTable() -> Bool{
- //sql语句
- let sql = "CREATE TABLE UserTable(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL, email TEXT, age INTEGER)"
- //执行sql语句
- let execResult = sqlite3_exec(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil);
- //判断是否执行成功
- if (execResult != SQLITE_OK) {
- return false
- }
- return true
- }
- //插入一条信息
- func addUser(user: Person) -> Bool
- {
- //sql语句
- let sql = "INSERT INTO UserTable (username, password, email, age) VALUES (?, ?, ?, ?);";
- //sql语句转换成cString类型
- let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
- //sqlite3_stmt 指针
- var stmt:COpaquePointer = nil
- //1.编译sql
- let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
- //判断如果失败,获取失败信息
- if prepare_result != SQLITE_OK {
- sqlite3_finalize(stmt)
- if let error = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //2.bind 绑定参数
- //第2个参数:索引从1开始
- //最后一个参数为函数指针
- sqlite3_bind_text(stmt, , user.name!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
- sqlite3_bind_text(stmt, , user.password!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
- sqlite3_bind_text(stmt, , user.email!.cStringUsingEncoding(NSUTF8StringEncoding)!, -, nil);
- sqlite3_bind_int(stmt, , CInt(user.age!));
- //3.step执行
- let step_result = sqlite3_step(stmt)
- //判断执行结果,如果失败,获取失败信息
- if step_result != SQLITE_OK && step_result != SQLITE_DONE {
- sqlite3_finalize(stmt)
- if let err = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //4.finalize
- sqlite3_finalize(stmt);
- return true
- }
- //查询
- func readAllUsers() -> [Person]{
- //声明一个Person对象数组(查询的信息会添加到该数组)
- var usersArr = [Person]()
- //查询sql语句
- let sql = "SELECT * FROM UserTable;";
- //sqlite3_stmt 指针
- var stmt:COpaquePointer = nil
- let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
- //1.编译sql
- let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
- if prepare_result != SQLITE_OK {
- sqlite3_finalize(stmt)
- if let error = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
- print(msg)
- self.alert(msg)
- }
- return usersArr
- }
- //2.step
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- let user = Person()
- //循环 从数据库获取数据,添加到数组中
- let cName = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
- let cPwd = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
- let cEmail = UnsafePointer<CChar>(sqlite3_column_text(stmt, ))
- let cAge = sqlite3_column_int(stmt, )
- user.name = String.fromCString(cName)
- user.password = String.fromCString(cPwd)
- user.email = String.fromCString(cEmail)
- user.age = Int(cAge)
- usersArr += [user]
- }
- //3.finalize
- sqlite3_finalize(stmt);
- return usersArr
- }
- //更新一条信息
- func updateUser(name: String , toName:String) -> Bool
- {
- //更新sql语句
- let sql = "update UserTable set username = '\(toName)' where username = '\(name)'";
- //sqlite3_stmt 指针
- var stmt:COpaquePointer = nil
- let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
- //1.编译sql
- let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
- //判断如果失败,获取失败信息
- if prepare_result != SQLITE_OK {
- sqlite3_finalize(stmt)
- if let error = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //2.step执行
- let step_result = sqlite3_step(stmt)
- //判断执行结果,如果失败,获取失败信息
- if step_result != SQLITE_OK && step_result != SQLITE_DONE {
- sqlite3_finalize(stmt)
- if let err = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //4.finalize
- sqlite3_finalize(stmt);
- return true
- }
- //删除一条信息
- func deleteUser(username: String) -> Bool
- {
- //删除sql语句
- let sql = "delete from UserTable where username = '\(username)'";
- //sqlite3_stmt 指针
- var stmt:COpaquePointer = nil
- let cSql = sql.cStringUsingEncoding(NSUTF8StringEncoding)
- //1.编译sql
- let prepare_result = sqlite3_prepare_v2(self.db, cSql!, -, &stmt, nil)
- //判断如果失败,获取失败信息
- if prepare_result != SQLITE_OK {
- sqlite3_finalize(stmt)
- if let error = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to prepare SQL: \(sql), Error: \(error)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //3.step执行
- let step_result = sqlite3_step(stmt)
- //判断执行结果,如果失败,获取失败信息
- if step_result != SQLITE_OK && step_result != SQLITE_DONE {
- sqlite3_finalize(stmt)
- if let err = String.fromCString(sqlite3_errmsg(self.db)) {
- let msg = "SQLiteDB - failed to execute SQL: \(sql), Error: \(err)"
- print(msg)
- self.alert(msg)
- }
- return false
- }
- //4.finalize
- sqlite3_finalize(stmt);
- return true
- }
- //定义一个报警器
- func alert(msg:String) {
- dispatch_async(dispatch_get_main_queue()) {
- let alert = UIAlertView(title: "SQLiteDB", message:msg, delegate: nil, cancelButtonTitle: "OK")
- alert.show()
- }
- }
因为工程数据库文件打包之后,会在NSBundle.mainBundle()路径下,该路径是只读的,不允许修改,所以必须把该路径下的数据库拷贝一份到Documents路径下,以后整个工程都将操作Documents路径下的数据库。
在ViewController中,添加一下代码。
- //声明一个Documents下的路径
- let dbPath = NSHomeDirectory() + "/Documents/RWDataTest.sqlite"
- //判断数据库文件是否存在
- if !NSFileManager.defaultManager().fileExistsAtPath(dbPath)
- {
- //获取安装包内数据库路径
- let bundleDBPath = NSBundle.mainBundle().pathForResource("RWDataTest", ofType: "sqlite")!
- //将安装包内数据库拷贝到Documents目录下
- do
- {
- try NSFileManager.defaultManager().copyItemAtPath(bundleDBPath, toPath: dbPath)
- }
- catch let error as NSError {
- print(error)//如果创建失败,error 会返回错误信息
- }
- }
- //打开数据库
- let dbOperation = DatabaseOperations(dbPath: dbPath)
- //添加一张表
- dbOperation.createTable();
- //插入一条信息, 通过Person对象来传值
- let person:Person = Person(name: "刘明洋", pwd: "liumingyang", email: "liumingyang@leadingdo.com", age: )
- dbOperation.addUser(person)
- //查询
- let personArray:[Person] = dbOperation.readAllUsers()
- print("共搜索到:\(personArray.count) 条数据" )
- //更新
- dbOperation.updateUser("刘明洋", toName: "刘蕙通")
- //删除
- dbOperation.deleteUser("刘蕙通")
- //关闭数据库
- dbOperation.colseDb()
读写应用程序数据-SQLite3的更多相关文章
- 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作
ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...
- 读写应用程序数据-CoreData
coreData数据最终的存储类型可以是:SQLite数据库.XML.二进制.内存里.自定义的数据类型. 和SQLite区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性. 1.创建工程 ...
- C# 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 官方 ...
- python 读写三菱PLC数据,使用以太网读写Q系列,L系列,Fx系列的PLC数据
本文将使用一个gitHub开源的组件技术来读写三菱的plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...
- java android 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...
- C#读写西门子PLC数据
C#读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC 本文将使用一个gitHub开源的组件技术来读写西门子plc数 ...
- C#读写三菱PLC数据 使用TCP/IP 协议
本文将使用一个Github开源的组件库技术来读写三菱PLC和西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能 ...
- 由于检索用户的本地应用程序数据路径时出错,导致无法生成 SQL Server 的用户实例
/”应用程序中的服务器错误. 由于检索用户的本地应用程序数据路径时出错,导致无法生成 SQL Server 的用户实例.请确保该用户在此计算机上有本地用户配置文件.该连接将关闭. 堆栈跟踪: [Sql ...
- 微信小程序数据请求方法wx.request小测试
微信小程序数据请求方法 wx.request wxml文件: <view> <textarea value="{{textdata}}"/> </vi ...
随机推荐
- ip_conntrack 实现
启动时首先在ip_conntrack_standalone.c中调用 static int __init ip_conntrack_standalone_init(void) //proc相关部分省略 ...
- 【HDOJ】1042 N!
肯定是大叔,本来以为用加法做乘法,后来想想这样麻烦,还是可以使用乘法的,按位乘,ov可以看成不止一位,程序如下所示: #include <stdio.h> #define MAX 4000 ...
- Oracle并行更新的两种方式(merge/update内联视图)
对于Oracle的两表联合更新的场景(有A.B两表,以A.id=B.id关联,根据B表中的记录更新A表中的相应字段),一般有update内联视图和merge两种方式,下面举例介绍: 创建用例表: ...
- hdu4323Magic Number(dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4323 去年的多校 编辑距离的变形 暴力居然过了 还想了好久别的方法,想得很头疼 #include <ios ...
- Servlet能读到JSessionID,读不到其它cookie问题
Servlet的Cookie值保存与获取 今天测试设置和获取Cookie遇到了一点小问题,很奇怪的问题: 把J2ee服务部署在本地 8080端口:访问任何一个服务时,如果客户端没有cookie,则下发 ...
- MyEclipse常用操作技巧
1.源码和帮助文档的的关连 下面以关联struts2-core-2.3.14.2.jar源代码为例: 如下为示意图 2.拷贝项目的时候,要注意 将项目的web-root fold改成更新后的名字项目名 ...
- C#实现调用Java类中方法
基本思路: 用C#实现调用Java编写的类中的方法:重点是将Java编写的程序打包成Jar,然后使用开源工具IKVM将其转化成DLL控件,在.NET环境下调用. 分为以下步骤: 1.下载JDK6(注: ...
- 了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密
关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据. 有些数据库,包括SQL Se ...
- [liu yanling]规范软件测试流程
测试计划 做任何事情都会有输入输出,对于测试过程我们可以把输入理解为测试计划.测试环境准备.测试工具的选择等等,输出可以理解为测试结果.测试用例设计即可以理解为以测试计划为输入的输出,也可以理解为以测 ...
- 韦东山yy公开课笔记(1)--各种杂的问题
1,第四期的智能猫眼会有打电话和发短信的功能吗? 答:会有打电话功能,硬件上支持打电话就会支持发短信,只是软件上是否实现发短信现在未定.因为短信延迟太严重,不是可靠的. 2,请问关于makefil ...