iOS——sqlite3的使用(iOS嵌入式关系数据库)
1>添加sqlite3动态库:libsqlite3.dylib,CoreGraphics.framework,UIKit.framework,Foundation.framework
2>导入头文件:#import<sqlite3.h>
3>利用C函数创建/打开数据库,编写SQL语句
自定义一个类DataBaseHandle继承NSObject
#import <Foundation/Foundation.h>
#import "Strategy.h"
@interface DataBaseHandle : NSObject
+(DataBaseHandle *)sharedInstance;
//打开数据库
-(void)openDB;
//关闭数据库
-(void)closeDB;
//插入新的数据
-(void)insertNewModel:(NSString *)name Data:(NSData *)data;
//删除某个保存的数据
-(void)deleteModelWithName:(NSString *)name;
//获取某个保存的数据
-(NSData *)selectModelWithName:(NSString *)name;
//获取所有的数据
-(NSArray *)selectAllModel;
//判断数据是否被保存
-(BOOL)isLoadModelWithName:(NSString *)name;
@end
下面是m文件的实现:
DataBaseHandle.m
#import "DataBaseHandle.h"
#import <sqlite3.h>
@implementation DataBaseHandle
static DataBaseHandle * handle = nil;
+(DataBaseHandle *)sharedInstance
{
if (handle == nil) {
handle = [[DataBaseHandle alloc] init];
}
return handle;
}
static sqlite3 *db=nil;
//打开数据库
-(void)openDB
{
if (db!=nil) {
return;
}
//存放数据库的路径和文件
NSString *path=NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
NSString *filePath=[path stringByAppendingPathComponent:@"Strategy.sqlite"];
// NSLog(@"db filePath=%@",filePath);
//打开数据库
int result=sqlite3_open([filePath UTF8String], &db);
if (result==SQLITE_OK) {
// NSLog(@"打开数据库成功");
NSString * createActivitySql = @"CREATE TABLE StrategyList (NAME TEXT PRIMARY KEY , data BLOB)";
//执行sql语句
sqlite3_exec(db, [createActivitySql UTF8String], NULL, NULL, NULL);
}
}
//关闭数据库
-(void)closeDB
{
int result=sqlite3_close(db);
if (result==SQLITE_OK) {
// NSLog(@"关闭数据库成功");
db=nil;
}
}
//插入新的数据
-(void)insertNewModel:(NSString *)name Data:(NSData *)data
{
[self openDB];
sqlite3_stmt *stmt=nil;
NSString *sql= @"insert into StrategyList (NAME,data) values (?,?)";
//验证sql语句
int result=sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil);
if (result==SQLITE_OK) {
//绑定数据
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);
sqlite3_bind_blob(stmt, 2, [data bytes], (int)[data length], nil);
sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
}
//删除某个保存的数据
-(void)deleteModelWithName:(NSString *)name
{
[self openDB];
sqlite3_stmt *stmt=nil;
NSString *sql= @"delete from StrategyList where NAME = ?";
//验证sql语句
int result=sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil);
if (result==SQLITE_OK) {
//绑定数据
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);
sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
}
//获取某个保存的数据
-(NSData *)selectModelWithName:(NSString *)name
{
[self openDB];
sqlite3_stmt * stmt = nil;
NSString * sql = @"select data from StrategyList where NAME = ?";
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
NSData * data = nil;
if (result == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, NULL);
if (sqlite3_step(stmt) == SQLITE_ROW) {
//bytes length
data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];
}
}
sqlite3_finalize(stmt);
return data;
}
//获取所有的数据
-(NSArray *)selectAllModel
{
[self openDB];
sqlite3_stmt * stmt = nil;
NSString * sql = @"select NAME from StrategyList";
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
NSMutableArray * travelArray = [NSMutableArray array];
if (result == SQLITE_OK) {
while (sqlite3_step(stmt) == SQLITE_ROW) {
NSString * name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 0)];
[travelArray addObject:name];
}
}
sqlite3_finalize(stmt);
return travelArray;
}
//判断数据是否被保存
-(BOOL)isLoadModelWithName:(NSString *)name
{
NSData * data = [self selectModelWithName:name];
if (data == nil) {
return NO;
}
return YES;
}
@end
SQLite3在存储和检索大量的数据非常有效,结构化查询语言能够对数据进行复杂的聚合,与使用对象执行这些操作相比,获得的结果的速度更快。
假设app需要计算其中所有对象的特色字段的总和或者需要只符合特定条件的对象的总和,SQLite3可以不需要将所有对象加载到内存中就获取到这些信息。
SQLite3获取聚合比所有对象加载到内存,然后计算它们值的总和要快。
#import "ViewController.h"
#import <sqlite3.h>
@interface ViewController ()
@property(strong,nonatomic)IBOutletCollection(UITextField)NSArray *lineFields;
@end
@implementation ViewController
-(NSString *)dataFilePath{
//查找Document目录并在其后附加数据文件的文件名,这样就得到了数据文件的完整的路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:@"data.sqlite"];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//打开数据库,如果在打开时遇到问题则关闭它并抛出一个断言错误
sqlite3 *database;
if (sqlite3_open([[self dataFilePath] UTF8String],&database)!= SQLITE_OK ){
sqlite3_close(database);
NSAssert(0, @"Failed to open database");
}
//创建一个CREATE 表来保存我们的数据,通过IF NOT EXISTS 可以防止数据库覆盖现有数据,如果有相同名称 的表此命令会直接退出不执行任何操作
NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS" "(ROW INTEGER PRIMARY KEY,FIELD_DATA TEXT);";
char *errorMsg;
if (sqlite3_exec (database,[createSQL UTF8String],NULL,NULL,&errorMsg)!= SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, @"Error creating table:%s",errorMsg);
}
//使用SELECT语句加载数据,请求所有行,告诉sqlite3按行号排序各行,以便我们以相同顺序获取它们
NSString *query = @"SELECT ROW,FIELD_DATA FROW FIELDS ORDER BY ROW";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database,[query UTF8String],-1,&statement,nil) == SQLITE_OK) {
//遍历返回的每一行
while (sqlite3_step(statement)== SQLITE_ROW) {
//抓取行号并将它存储在一个int变量中,然后抓取字段数据保存到C语言字符串中
int row = sqlite3_column_int(statement,0);
char *rowData = (char *)sqlite3_column_int(statement,1);
//利用数据库获取的值设置相应的字段
NSString *fileValue = [[NSString alloc]initWithUTF8String:rowData];
UITextField *theField = self.lineFields[row];
theField.text = fileValue;
}
//关闭数据库连接,操作到此结束
sqlite3_finalize(statement);
}
sqlite3_close(database);
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
}
//应用在终止运行或者进去后台之前保存数据
-(void)applicationWillResignActive:(NSNotification *)notification{
//再次打开数据库
sqlite3 *database;
if (sqlite3_open([[self dataFilePath] UTF8String],&database)!= SQLITE_OK ){
sqlite3_close(database);
NSAssert(0, @"Failed to open database");
}
for (int i =0; i< 4; i++) {
UITextField *theField = self.lineFields[i];
//生成4条独立命令来更新数据库中的每一行
char *update = "INSERT OR REPLACE INTO FIELDS (ROW,FIELD_DATA)""VALUED(?,?);";
char *errorMsg = NULL;
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database,update,-1,&stmt,nil) == SQLITE_OK) {
sqlite3_bind_int(stmt,1,i);
sqlite3_bind_text(stmt,2,[theField.text UTF8String],-1,NULL);
}
//step语句执行更新。
if (sqlite3_step(stmt)!= SQLITE_DONE){
NSAssert(0, @"Error update table:%s",errorMsg);
sqlite3_finalize(stmt);
}
}
sqlite3_close(database);
}
@end
iOS——sqlite3的使用(iOS嵌入式关系数据库)的更多相关文章
- iOS sqlite3 的基本使用(增 删 改 查)
iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...
- iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
iOS开发UI篇—IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n 新建项目 cmd + n 新建文 ...
- iOS开发UI篇—iOS开发中三种简单的动画设置
iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...
- iOS开发UI篇—ios应用数据存储方式(偏好设置)
iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...
- iOS开发UI篇—ios应用数据存储方式(归档)
iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...
- Xamarin.iOS调试提示需要iOS SDK
Xamarin.iOS调试提示需要iOS SDK 错误信息:The version of Xamarin.iOS requires th iOS 9.3 SDK (shipped with Xco ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- 【译】UI设计基础(UI Design Basics)--为iOS设计(Design for iOS)(二)
2.1 为iOS设计(Design for iOS) iOS体现以下主题: 遵从:UI帮助用户理解界面内容并与内容交互,但绝不会与内容相互冲突. 清晰:文本在任何尺寸下都是清晰易读,图标精确易懂,装饰 ...
- iOS开发UI篇—ios应用数据存储方式(归档) :转发
本文转发至:文顶顶http://www.cnblogs.com/wendingding/p/3775293.html iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist ...
随机推荐
- ggplot2入门与进阶(上)
出处:http://www.cellyse.com/how_to_use_gggplot2_part1/ ggplot2包是基于Wilkinson在<Grammar of Graphics> ...
- 《流畅的Python》Data Structures--第2章序列array
第二部分 Data Structure Chapter2 An Array of Sequences Chapter3 Dictionaries and Sets Chapter4 Text vers ...
- BZOJ 3884——欧拉降幂和广义欧拉降幂
理论部分 欧拉定理:若 $a,n$ 为正整数,且 $a,n$ 互质,则 $a^{\varphi (n)} \equiv 1(mod \ n)$. 降幂公式: $$a^b=\begin{cases}a^ ...
- k8s 命令自动补全
yum install -y bash-completion source /usr/share/bash-completion/bash_completion source <(kubectl ...
- SQL的左连接与右链接
1.准备工作 Oracle 外连接(OUTER JOIN)包括以下: 左外连接(左边的表不加限制) 右外连接(右边的表不加限制) 全外连接(左右两表都不加限制) 对应SQL:LEFT/RIGHT/F ...
- BZOJ 2169 连边 DP
思路:DP 提交:\(1\)次(课上刚讲过) 题解: 如果不管重边的话,我们设\(f[i][j]\)表示连了\(i\)条边,\(j\)个点的度数是奇数的方案数,那么显然我们可以分三种状态转移: \(f ...
- 【题解】[Noip2010]机器翻译-C++
题目Description小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章.这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件 ...
- set/unset
自定义一个变量 name=value 查看现有变量 删除变量或函数 unset name
- 二十九、SELinux简介
一.基础 1)访问模型 Linux原有访问模型:自主访问控制 DAC 安全隐患: 进程所能访问资源的范围 为用户所能访问的资源范围 后门: rootkit程序 进程被胁持: 基于进程作为跳板,就有了进 ...
- CF1030C
CF1030C 题意: 给你一个数字,问能否拆分成k段,使得每一段的每一位数字相加结果相等. 解法: 考虑数位DP. 暴力按位考虑每一位是否满足条件 CODE: #include<cstdio& ...