我们在写项目中常常要求数据持久化 在iOS编程中数据持久化的方式有归档/反归档将数据写入本地或者利用数据库将数据接入到本地都可以实现数据持久化 下面就来介绍一下iOS中使用的一种数据库SQLite
SQLite是一种轻型嵌入式数据库 在iOS和安卓开发中都会使用到 它占用内存小 大概几百k 而且数据处理速度要比Mysql、PostgreSQL这两款数据库快
在写数据库时 一定不要把SQL语句写错了 下面我们通过代码来看一下 怎样去实现一个数据库
#import
#import // 3.0 是3的替身文件
@class Student;
NS_ASSUME_NONNULL_BEGIN
@interface SQLiteDataBaseManager : NSObject {
sqlite3 *dbPoint;
}
// 写一个数据库管理类
// 单例 方法一个工程中只包含这一个对象
+ (SQLiteDataBaseManager *)sharedManager;
// 打开数据库
- (BOOL)openSQLite3;
// 关闭数据库
- (BOOL)closeSQLite3;
// 创建表
- (BOOL)createTable;
// 插入 / 添加数据
- (BOOL)insertStu:(Student *)stu;
// 删除数据
- (BOOL)deleteStu:(Student *)stu; // 删除一个
- (BOOL)deleteAll; // 删除全部
// 修改 / gengxin
- (BOOL)updateOldName:(NSString *)oldName newName: (NSString *)newName;
// 查询数据
- (__kindof NSArray *)selectAll;
@end
NS_ASSUME_NONNULL_END
#import "SQLiteDataBaseManager.h"
#import "Student.h"
@implementation SQLiteDataBaseManager
// 单例 创建方式 只有一个对象(在整个程序运行过程中 一直存在 不要给他释放)
// 内存管理中 单例不能被释放
+ (SQLiteDataBaseManager *)sharedManager {
// 静态变量 static + 类名
static SQLiteDataBaseManager *manager = nil;
// 保证线程安全执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 创建
manager = [[SQLiteDataBaseManager alloc] init];
});
return manager;
}
// 打开数据库
- (BOOL)openSQLite3 {
// 获取沙盒
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [array firstObject];
// 数据库SQLite3文件类型.db
NSString *dbPath = [path stringByAppendingPathComponent:@"student.db"];
NSLog(@"%@", dbPath);
// UTF8String: 将OC字符串转换成C语言中的字符串
// 参数1: 数据库文件路径
// 参数2: 指向指针的指针 该指针可以被修改 数据库管理的指针
int result = sqlite3_open([dbPath UTF8String], &dbPoint);
BOOL isOpen = YES;
// sqlite3_open 当路径文件不存在时 路径文件会被sqlite3_open创建 并打开
// 当sqlite3_open 存在时 文件直接被打开
// sqlite3_open 返回值为int型 "0"代表成功(SQLite_OK) "1"代表失败
if (result == SQLITE_OK) {
NSLog(@"打开数据库成功");
isOpen = YES;
} else {
NSLog(@"打开数据库失败");
isOpen = NO;
}
return isOpen;
}
// 关闭数据库
- (BOOL)closeSQLite3 {
// 关闭数据库时 如果数据库是打开状态 会关闭成功
// 关闭数据库时 如果数据库时关闭状态 会显示失败 原因21 库不存在
int result = sqlite3_close(dbPoint);
return [self isOperationResult:result alertText:@"关闭数据库"];
}
// 创建表
- (BOOL)createTable {
// SQL语句 create table 表名 (字段1 类型 约束, 字段2 类型 约束........)
// NSString *createSQL = @"create table stu(stu_id integer primary key, stu_name text)";
// primary key: 一个表有且只有一个主键
// autoincrement: 自增 添加完该字段 系统会自己创建一个数据库表 sqlite_sequence 用来保存自增的值
// not null: 不能为空 如果为空 SQL会报错
// 删除一个表 drop table + 表名(SQL语句)
NSString *createSQL = @"create table stu2(stu_id integer primary key autoincrement, stu_name text NOT NULL)";
// 执行SQL语句 参数1: 数据库指针 参数2:SQL语句 剩下的都是null
int result = sqlite3_exec(dbPoint, [createSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"创建表"];
}
- (BOOL)insertStu:(Student *)stu {
NSString *insertSQL = [NSString stringWithFormat:@"insert into stu2 values (null, '%@')", stu.stu_name];
// 如果设置了自增 将值填写为null 默认从1开始 如果填写其他值 例如:填入7 值将会从7开始计算 并存储在sqlite_sequence
// NSString *insertSQL = @"insert into stu7 values (null, 'Eason')";
int result = sqlite3_exec(dbPoint, [insertSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"插入数据"];
}
- (BOOL)deleteStu:(Student *)stu {
NSString *deleteSQL = [NSString stringWithFormat:@"delete from stu2 where stu_id = %ld", stu.stu_id];
int result = sqlite3_exec(dbPoint, [deleteSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"删除一条数据"];
}
- (BOOL)deleteAll {
NSString *deleteSQL = @"delete from stu2 where 1=1";
int result = sqlite3_exec(dbPoint, [deleteSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"删除全部"];
}
- (BOOL)updateOldName:(NSString *)oldName newName:(NSString *)newName {
// update 表名 字段名 = 新值 where 字段名 = 旧值
NSString *updateSQL = [NSString stringWithFormat:@"update stu2 set stu_name = '%@' where stu_name = '%@'", newName, oldName];
int result = sqlite3_exec(dbPoint, [updateSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"更新"];
}
- (__kindof NSArray *)selectAll {
sqlite3_stmt *stmt = NULL;
NSString *selectAll = @"select * from stu2";
// 参数1: 数据库指针
// 参数2: SQL语句
// 参数3: SQL语句长度 -1
// 参数4: 替身 将查询到的内容放到替身中 并将替身返回
int result = sqlite3_prepare(dbPoint, [selectAll UTF8String], -1, &stmt, NULL);
NSMutableArray *stuArray = [NSMutableArray array];
if (result == SQLITE_OK) {
// 循环 遍历替身内容 直到 SQLITE_DONE
// step 查询替身中有没有其他数据 当包含有其他数据时 结果为SQLITE_ROW 当不包含其他数据时 结果为 SQLITE_DONE 结束执行
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 取对应的每一列数据
int stu_id = sqlite3_column_int(stmt, 0); // 取第0列
const unsigned char *stu_name = sqlite3_column_text(stmt, 1); //
Student *stu = [[Student alloc] init];
stu.stu_id = stu_id;
stu.stu_name = [NSString stringWithUTF8String:(const char *)stu_name];
[stuArray addObject:stu];
}
}
// 替身用完了要销毁
sqlite3_finalize(stmt);
return stuArray;
}
- (BOOL)isOperationResult:(int)result alertText:(NSString *)alertText {
BOOL isOperation = YES;
if (result == SQLITE_OK) {
NSLog(@"%@成功", alertText);
isOperation = YES;
} else {
NSLog(@"%@失败", alertText);
isOperation = NO;
}
return isOperation;
}
@end
#import
@interface Student : NSObject
@property (nonatomic, assign) NSInteger stu_id;
@property (nonatomic, copy) NSString *stu_name;
@end
#import "ViewController.h"
#import "SQLiteDataBaseManager.h"
#import "Student.h"
@interface ViewController ()
@property (nonatomic, strong) SQLiteDataBaseManager *dataBaseManager;
@end
@implementation ViewController
- (IBAction)openSQLiteButton:(id)sender {
[_dataBaseManager openSQLite3];
// 注意: 使用SQLite需要引入sqlite3.0.tdb
// sqlite3.tdb 和sqlite3.0.tdb区别
// sqlite3.0.tdb 是sqlite3.tdb的提审文件 放置误删
}
- (IBAction)closeSQLite:(id)sender {
[_dataBaseManager closeSQLite3];
}
- (IBAction)createTable:(id)sender {
[_dataBaseManager createTable];
}
- (IBAction)insertStu:(id)sender {
Student *stu = [[Student alloc] init];
stu.stu_id = 17;
stu.stu_name = @"Andy";
[_dataBaseManager insertStu:stu];
}
- (IBAction)deleteStu:(id)sender {
Student *stu = [[Student alloc] init];
stu.stu_id = 17;
stu.stu_name = @"Andy";
// [_dataBaseManager deleteStu:stu];
[_dataBaseManager deleteAll];
}
- (IBAction)update:(id)sender {
[_dataBaseManager updateOldName:@"Andy" newName:@"Mary"];
}
- (IBAction)selectAll:(id)sender {
NSArray *array = [_dataBaseManager selectAll];
NSLog(@"%@", array);
}