封装使用代码示例
1 .h 文件
#import <Foundation/Foundation.h>
@interface SQliteManager : NSObject
+ (instancetype)shareSQLite;
/// 建表/删表/插入数据/更新数据/删除数据 等操作
- (BOOL)executeSQLite:(NSString *)sqlString;
/// 查询操作
- (NSArray *)selectSQLite:(NSString *)sqlString;
@end
2 .m 文件
#import "SQliteManager.h"
#import <sqlite3.h>
/// 存储文件
static NSString *const SQLiteFile = @"SQLiteFile.db";
//static NSString *const SQLiteFile = @"SQLiteFile.sqlite3";
@interface SQliteManager ()
{
// 数据库
sqlite3 *dataBase;
BOOL isOpenDataBase;
}
@property (nonatomic, strong) NSString *filePath;
@end
@implementation SQliteManager
- (instancetype)init
{
self = [super init];
if (self) {
NSLog(@"filePath = %@", self.filePath);
}
return self;
}
+ (instancetype)shareSQLite
{
static SQliteManager *staticSQliteManager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
staticSQliteManager = [[self alloc] init];
assert(staticSQliteManager != nil);
});
return staticSQliteManager;
}
#pragma mark -
- (BOOL)isValidSQL:(NSString *)sql
{
return (sql && [sql isKindOfClass:NSString.class] && sql.length > 0);
}
- (NSString *)filePath
{
if (_filePath == nil) {
// doucment
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
// NSString *filePath = [paths objectAtIndex:0];
// 缓存
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_filePath = [paths objectAtIndex:0];
_filePath = [_filePath stringByAppendingPathComponent:SQLiteFile];
NSLog(@"filepath: %@", _filePath);
}
return _filePath;
}
- (BOOL)openSQLite
{
const char *fileName = self.filePath.UTF8String;
int execStatus = sqlite3_open(fileName, &dataBase);
if (execStatus == SQLITE_OK) {
NSLog(@"数据库打开成功");
isOpenDataBase = YES;
return YES;
} else {
NSLog(@"数据库打开失败:%s", sqlite3_errmsg(dataBase));
isOpenDataBase = NO;
return NO;
}
}
- (void)closeSQLite
{
if (isOpenDataBase) {
// 关闭数据库
isOpenDataBase = NO;
int execStatus = sqlite3_close(dataBase);
if (execStatus == SQLITE_OK) {
NSLog(@"数据库关闭成功");
} else {
NSLog(@"数据库关闭失败:%s", sqlite3_errmsg(dataBase));
}
}
}
int callback(void *param, int f_num, char **f_value, char **f_name)
{
printf("%s:这是回调函数!\n", __FUNCTION__);
return 0;
}
- (BOOL)executeSQLite:(NSString *)sqlString
{
BOOL result = NO;
@synchronized (self) {
if ([self isValidSQL:sqlString]) {
if (self.openSQLite) {
char *errorMsg;
int execStatus = sqlite3_exec(dataBase, sqlString.UTF8String, callback, NULL, &errorMsg);
if (execStatus == SQLITE_OK) {
NSLog(@"[%@]执行成功", sqlString);
result = YES;
} else {
NSLog(@"[%@]执行失败:%s", sqlString, errorMsg);
}
[self closeSQLite];
}
}
}
return result;
}
- (NSArray *)selectSQLite:(NSString *)sqlString
{
NSMutableArray *array = [[NSMutableArray alloc] init];
if ([self isValidSQL:sqlString]) {
if (self.openSQLite) {
sqlite3_stmt *statement;
int execStatus = sqlite3_prepare_v2(dataBase, sqlString.UTF8String, -1, &statement, NULL);
if (execStatus == SQLITE_OK) {
// 循环判断,取得数据集合
while (sqlite3_step(statement) == SQLITE_ROW) {
// 根据数据类型,及字段所有列数获取信息(列数从0~n)
int index = sqlite3_column_int(statement, 0);
char *name = (char *)sqlite3_column_text(statement, 1);
char *gender = (char *)sqlite3_column_text(statement, 2);
int age = sqlite3_column_int(statement, 3);
char *education = (char *)sqlite3_column_text(statement, 4);
//
NSString *idStr = [[NSString alloc] initWithFormat:@"%d", index];
NSString *nameStr = [[NSString alloc] initWithUTF8String:name];
NSString *sexStr = [[NSString alloc] initWithUTF8String:gender];
NSString *ageStr = [[NSString alloc] initWithFormat:@"%d", age];
NSString *eduStr = [[NSString alloc] initWithUTF8String:education];
//
NSDictionary *dict = @{@"personId":idStr, @"personName":nameStr, @"personGender":sexStr, @"personAge":ageStr, @"personEducation":eduStr};
[array addObject:dict];
}
}
// 释放sqlite3_stmt对象资源
sqlite3_finalize(statement);
[self closeSQLite];
}
}
return array;
}
@end
3 使用及注意事项
// 创建表
NSString *sql = @"CREATE TABLE IF NOT EXISTS PERSON (id INTEGER PRIMARY KEY, name TEXT, gender TEXT, age INTEGER, education TEXT)";
[SQliteManager.shareSQLite executeSQLite:sql];
定义字段及其类型(
NULL
NULL 值,INTEGER
整数,REAL
8字节浮点值,TEXT
UTF8编码文本字符串,BLOB
blob 数据,完全根据它的输入存储),并使用PRIMARY KEY
定义表中的关键字
// 删除表
NSString *sql = @"DROP TABLE PERSON";
[SQliteManager.shareSQLite executeSQLite:sql];
// 插入数据
NSString *sql = [NSString stringWithFormat:@"insert into PERSON (id, name, gender, age, education) values (NULL, \"%@\", \"%@\", \"%d\", \"%@\")", @"devZhang", @"男", 26, @"本科"];
[SQliteManager.shareSQLite executeSQLite:sql];
values 中对应字段值,需要使用单引号
``
,或双引号""
,否则会报异常,从而导致sql 语句执行失败
// 更新数据
NSString *sql = [NSString stringWithFormat:@"UPDATE PERSON SET education = '%@' where name = '%@'", @"学士", @"devZhang"];
[SQliteManager.shareSQLite executeSQLite:sql];
// 删除数据,指定数据
NSString *sql = [NSString stringWithFormat:@"DELETE FROM PERSON where NAME = '%@'", @"devZhang"];
// 或 删除所有数据
NSString *sql = @"DELETE FROM PERSON";
[SQliteManager.shareSQLite executeSQLite:sql];
// 查找数据,指定数据
NSString *sql = @"SELECT * FROM PERSON where name = 'devZhang'";
// 或 查找所有数据
NSString *sql = @"SELECT * FROM PERSON";
NSArray *array = [SQliteManager.shareSQLite selectSQLite:sql];
NSLog(@"select: %@", array);
4 说明
sqlite3_exec
函数只能用于创建表、删除表、插入数据、更新数据、删除数据等的操作,而不能用于查找数据操作。- 查找数据操作相对复杂,即查找的数据可能是一条数据记录,也可能是一个数据集合,故在查找操作时,需要多个函数配合使用,如
sqlite3_prepare_v2
,sqlite3_step
,sqlite3_column_int
,sqlite3_column_text
等。 - 注意资源的释放,避免造成使用异常,如:
sqlite3
数据库打开sqlite3_open
VS 关闭sqlite3_close
,sqlite3_stmt
资源打开sqlite3_prepare_v2
VS 释放sqlite3_finalize
。