新手开发文,iOS开发中经常会有数据需要进行本地存储,将数据存储在本地,就会减少一些不必要的操作,也不需要经常添加MBProgreHUD类似的插件,例如一些app进行登录之后,下次再登录的时候就可以直接自动登录,这方面就有用到数据本地存储。常用的数据存储方式,大家应该也都有了解,有Plist存储,归档,NSUserDefault等等方式,但是这几种方式有个挺严重的问题,当数据量偏大的时候,它们是无法进行全部存储的,所以今天写这篇文就是为了让新手对可以存储大量数据的SQLite进行初步的了解。但是由于iOS中原生的SQLite API在使用上相当不方便。于是,就出现了一系列将SQLite API进行封装的库,例如FMDB、PlausibleDatabase、sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款简洁、易用的封装库,说是说对数据库的简单操作,不如说是对FMDB的简单实用。
简单的介绍一下SQLite,SQLite是一款轻型的嵌入式数据库,安卓和ios开发使用的都是SQLite数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快。一般移动客户端常用存储数据都会sqlite。数据库的存储结构和excel很像,以表(table)为单位 。表由多个字段(列、属性、column)组成,表里面的每一行数据称为记录。数据库存储数据的步骤一般就是先新建一张表(table),然后添加多个字段(column,列,属性)或者添加多行记录(row,record,每行存放多个字段对应的值)。
本文就先介绍对新建一个个人基本信息的存储,页面如下
页面比较粗糙,大家可以忽略,这个demo就是简单的将数据库操作囊括进去。就是增删改查这几个功能。
下面简单的数一下几个步骤,首先就是创建工程,添加使用sqlite的库libsqlite3.dylib就如下图所示点击添加
5A49C71D-FAF2-439A-B484-15BD9BECFB58.png
在Linked Frameworks and Libraries下面点击那个加号。进行添加
添加完之后,就可以把下载的FMDB的文件拖进工程。
这一步做完,基础工作就算做完了,下面就是进行代码工作,我习惯于全代码方式实现,所以没有sb和xib出现。
1,在AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
//appdelegate
_window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor whiteColor];
[_window makeKeyAndVisible];
ViewController *vc = [[ViewController alloc]init];
UINavigationController *na = [[UINavigationController alloc]initWithRootViewController:vc];
_window.rootViewController = na;
return YES;
}
接下来是页面设置,添加输入文本框,按钮之类的,同时需要导入头文件”FMDB“,然后定义。代码如下
#import "ViewController.h"
#import "FMDB.h"
@interface ViewController ()
//三个输入框
@property (nonatomic,strong) UITextField *nameText;
@property (nonatomic,strong) UITextField *ageText;
@property (nonatomic,strong) UITextField *salaryText;
//三个标签
@property (nonatomic,strong) UILabel *nameLabel;//姓名
@property (nonatomic,strong) UILabel *ageLabel;//年龄
@property (nonatomic,strong) UILabel *salaryLabel;//工资
//四个按钮,增删改查
@property (nonatomic,strong) UIButton *createBtn;//创建
@property (nonatomic,strong) UIButton *insertBtn;//插入
@property (nonatomic,strong) UIButton *clearBtn;//清除
@property (nonatomic,strong) UIButton *queryBtn;//查询
@property (nonatomic,strong) UITextView *describeView;//显示框
//FMDatabase数据库属性
@property (nonatomic,strong) FMDatabase *database;
@end
@implementation ViewController
@synthesize nameLabel,ageLabel,salaryLabel;
@synthesize nameText,ageText,salaryText;
@synthesize createBtn,insertBtn,clearBtn,queryBtn;
@synthesize describeView;
//主程序
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"数据库操作";
self.view.backgroundColor = [UIColor whiteColor];
[self setLabels];//设置标签的方法
[self setTextFields];//设置文本框的方法
[self setButtons];//设置按钮的方法
}
//设置标签的方法
-(void)setLabels
{
if (!self.nameLabel)
{
self.nameLabel = [[UILabel alloc]init];
[self.view addSubview:nameLabel];
}
if (!self.ageLabel)
{
self.ageLabel = [[UILabel alloc]init];
[self.view addSubview:ageLabel];
}
if (!self.salaryLabel)
{
self.salaryLabel = [[UILabel alloc]init];
[self.view addSubview:salaryLabel];
}
nameLabel.text = @"姓名";
nameLabel.frame = CGRectMake(20, 100, 40, 20);
nameLabel.font = [UIFont systemFontOfSize:14];
nameLabel.textColor = [UIColor blackColor];
ageLabel.text = @"年龄";
ageLabel.frame = CGRectMake(20, 150, 40, 20);
ageLabel.font = [UIFont systemFontOfSize:14];
ageLabel.textColor = [UIColor blackColor];
salaryLabel.text = @"工资";
salaryLabel.frame = CGRectMake(20, 200, 40, 20);
salaryLabel.font = [UIFont systemFontOfSize:14];
salaryLabel.textColor = [UIColor blackColor];
}
//设置文本框的方法
-(void)setTextFields
{
if (!self.nameText)
{
self.nameText = [[UITextField alloc]init];
[self.view addSubview:nameText];
}
if (!self.ageText)
{
self.ageText = [[UITextField alloc]init];
[self.view addSubview:ageText];
}
if (!self.salaryText)
{
self.salaryText = [[UITextField alloc]init];
[self.view addSubview:salaryText];
}
if (!self.describeView)
{
self.describeView = [[UITextView alloc]init];
[self.view addSubview:describeView];
}
nameText.frame = CGRectMake(90, 100, 250, 20);
nameText.placeholder = @"请输入姓名";
nameText.font = [UIFont systemFontOfSize:14];
nameText.borderStyle = UITextBorderStyleRoundedRect;
ageText.frame = CGRectMake(90, 150, 250, 20);
ageText.placeholder = @"请输入年龄";
ageText.font = [UIFont systemFontOfSize:14];
ageText.borderStyle = UITextBorderStyleRoundedRect;
salaryText.frame = CGRectMake(90, 200, 250, 20);
salaryText.placeholder = @"请输入工资";
salaryText.font = [UIFont systemFontOfSize:14];
salaryText.borderStyle = UITextBorderStyleRoundedRect;
describeView.frame = CGRectMake(30, 250, 315, 200);
describeView.font = [UIFont systemFontOfSize:14];
describeView.backgroundColor = [UIColor cyanColor];
}
//设置按钮的方法
-(void)setButtons
{
if (!self.createBtn)
{
self.createBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:createBtn];
}
if (!self.insertBtn)
{
self.insertBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:insertBtn];
}
if (!self.clearBtn)
{
self.clearBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:clearBtn];
}
if (!self.queryBtn)
{
self.queryBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:queryBtn];
}
createBtn.frame = CGRectMake(30, 500,120, 40);
createBtn.backgroundColor = [UIColor cyanColor];
[createBtn setTitle:@"创建" forState:UIControlStateNormal];
[createBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
createBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[createBtn addTarget:self action:@selector(createData) forControlEvents:UIControlEventTouchUpInside];
insertBtn.frame = CGRectMake(225, 500,120, 40);
insertBtn.backgroundColor = [UIColor cyanColor];
[insertBtn setTitle:@"插入" forState:UIControlStateNormal];
[insertBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
insertBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[insertBtn addTarget:self action:@selector(insertData) forControlEvents:UIControlEventTouchUpInside];
clearBtn.frame = CGRectMake(30, 560,120, 40);
clearBtn.backgroundColor = [UIColor cyanColor];
[clearBtn setTitle:@"清除" forState:UIControlStateNormal];
[clearBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
clearBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[clearBtn addTarget:self action:@selector(clearData) forControlEvents:UIControlEventTouchUpInside];
queryBtn.frame = CGRectMake(225, 560,120, 40);
queryBtn.backgroundColor = [UIColor cyanColor];
[queryBtn setTitle:@"查询" forState:UIControlStateNormal];
[queryBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
queryBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[queryBtn addTarget:self action:@selector(queryData) forControlEvents:UIControlEventTouchUpInside];
}
以上就是设置页面的基本样子,呈现出来的样子就是本文一开始的样子。但是没法进行操作,下面即使要实现点击事件的方法。
FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。所以数据库操作呢,首先得创建一个数据库,当数据库文件不存在时,fmdb会自己创建一个。 如果你传入的参数是空串:@"" ,则fmdb会在临时文件目录下创建这个数据库,数据库断开连接时,数据库文件被删除。如果你传入的参数是 NULL,则它会建立一个在内存中的数据库,数据库断开连接时,数据库文件被删除。
//创建数据库文件
self.database = [FMDatabase databaseWithPath:sqlitePath];
//数据库打开与关闭
[self.database open];
[self.database close];
在进行操作的时候,创建增加插入等操作都调用了executeUpdate方法,在查询的时候调用了executeQuery方法
第一个就是创建数据库表的方法了
//创建
-(void)createData
{
NSLog(@"创建数据库和表");
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *sqlitePath = [documentsPath stringByAppendingPathComponent:@"person.sqlite"];
//创建数据库文件
self.database = [FMDatabase databaseWithPath:sqlitePath];
//打开数据库
if ([self.database open])
{
//创建表(更新操作)
BOOL isSucess = [self.database executeUpdate:@"create table if not exists employee (id integer primary key, name text, age integer, salary real)"];
if (!isSucess)
{
NSLog(@"创建表失败%@", [self.database lastError]);
}
}
//关闭数据库
[self.database close];
}
第二步实现插入的方法
//插入
-(void)insertData
{
NSLog(@"插入数据");
if ([self.database open])
{
//插入数据:方式一、带有参数的插入sql语句
NSString *name = nameText.text;
NSNumber *age = @(ageText.text.intValue);
NSNumber *salary = @(self.salaryText.text.doubleValue);
BOOL isSucess = [self.database executeUpdate:@"insert into employee (name,age,salary) values (?,?,?)",name,age,salary];
//方式二、带有参数的插入sql语句
/*
NSString *str = [NSString stringWithFormat:@"insert into employee (name,age,salary) values (%@,%d,%lf)",self.nameTextField.text,self.ageTextField.text.intValue ,self.salaryTextField.text.doubleValue];
BOOL isSucess = [self.database executeUpdate:str];
*/
if (!isSucess)
{
NSLog(@"插入数据失败%@", [self.database lastError]);
}
}
[self.database close];
}
第三步是实现查询的方法
//查询
-(void)queryData
{
NSLog(@"查询数据");
if ([self.database open])
{
FMResultSet *resultSet = [self.database executeQuery:@"select *from employee"];
//执行查询操作
while ([resultSet next])
{
//一句插入数据的类型,调用方法名字不同
int employee = [resultSet intForColumn:@"id"];
NSString *name = [resultSet stringForColumn:@"name"];
int age = [resultSet intForColumn:@"age"];
double salary = [resultSet doubleForColumn:@"salary"];
//更新到界面UITextView
self.describeView.text = [self.describeView.text stringByAppendingFormat:@"\n%d,%@,%D,%.2lf",employee,name,age,salary];
}
}
//关闭
[self.database close];
}
最后一步就是实现清除的方法
//清除
-(void)clearData
{
NSLog(@"清除数据");
if ([self.database open])
{
BOOL isSuccess = [self.database executeUpdate:@"delete from employee"];
if (!isSuccess)
{
NSLog(@"清除数据失败%@",[self.database lastError]);
}
}
[self.database close];
}
顺便添加一个点击空白处,键盘收起的代码,因为用的iphone6的尺寸,所以键盘弹出的时候,如果不添加让界面失去第一响应者的话,键盘就会挡着下面的按钮,就没法好好的玩耍了,代码如下
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
在最后我就贴上github里demo的链接吧简单数据库操作 。
在上面有什么问题的话希望能与我一起交流,作为新手码农,很多问题都需要学习,发现问题的话希望大家指正。
网友评论