欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS-SQLite在项目中实际使用(Objective-C)

程序员文章站 2022-09-18 11:36:56
实际开发中,掌握并熟练使用SQLite数据库对app内数据进行操作是移动开发人员至关重要的技能,iOS中封装的coreData固然也是对SQLite的二层封装,强大的https:/...

实际开发中,掌握并熟练使用SQLite数据库对app内数据进行操作是移动开发人员至关重要的技能,iOS中封装的coreData固然也是对SQLite的二层封装,强大的https://github.com/ccgus/fmdb‘>FMDB也会帮程序员减轻很多不必要的麻烦,提高工作效率,既然是封装.性能自然不如直接操作SQL语句

创建数据库管理类SQLiteManager

设置类方法创建单例对象-OC中创建单例可以单独生成类方法创建单例对象,也可使用原始init方法创建普通对象

.h
@interface SQLiteManager : NSObject
//类方法生成单例对象
+(instancetype)shareInstance;
@end

.m
@implementation SQLiteManager
static SQLiteManager *instance;
+(instancetype)shareInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
@end

操作数据库

首先需要在项目中导入libsqlite3.tbd框架
iOS-SQLite在项目中实际使用(Objective-C)
然后在SQLiteManager数据库管理类引入头文件

#import 

打开数据库

在.h文件中暴露打开数据库的接口

//打开数据库
-(BOOL)openDB;

.m文件中轻松加愉快的实现使用原生SQLite框架的各种操作数据库的方法.
SQL语句建议直接复制粘贴备忘录中的语句,以免拼写出错(有可能是博客中最没用的一句话)

#pragma mark - 打开/创建数据库
-(BOOL)openDB{
    //app内数据库文件存放路径-一般存放在沙盒中
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *DBPath = [documentPath stringByAppendingPathComponent:@"appDB.sqlite"];
    //创建(指定路径不存在数据库文件)/打开(已存在数据库文件) 数据库文件
    //sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)  filename:数据库路径  ppDb:数据库对象
    if (sqlite3_open(DBPath.UTF8String, &_db) != SQLITE_OK) {
        //数据库打开失败
        return NO;
    }else{
        //打开成功创建表
        return [self creatTable];
    }
}
-(BOOL)creatTable{
    //创建表的SQL语句
    //用户 表
    NSString *creatUserTable = @"CREATE TABLE IF NOT EXISTS 't_User' ( 'ID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'name' TEXT,'age' INTEGER,'icon' TEXT);";
    //车 表
    NSString *creatCarTable = @"CREATE TABLE IF NOT EXISTS 't_Car' ('ID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'type' TEXT,'output' REAL,'master' TEXT)";
    //项目中一般不会只有一个表
    NSArray *SQL_ARR = [NSArray arrayWithObjects:creatUserTable,creatCarTable, nil];
    return [self creatTableExecSQL:SQL_ARR];
}
-(BOOL)creatTableExecSQL:(NSArray *)SQL_ARR{
    for (NSString *SQL in SQL_ARR) {
        //参数一:数据库对象  参数二:需要执行的SQL语句  其余参数不需要处理
        if (![self execSQL:SQL]) {
            return NO;
        }
    }
    return YES;
}
#pragma 执行SQL语句
-(BOOL)execSQL:(NSString *)SQL{
    return sqlite3_exec(self.db, SQL.UTF8String, nil, nil, nil) == SQLITE_OK;
}

数据库内SQL操作

#pragma 执行SQL语句
-(BOOL)execSQL:(NSString *)SQL{
    return sqlite3_exec(self.db, SQL.UTF8String, nil, nil, nil) == SQLITE_OK;
}

如果需要更新数据库对应表中数据,直接调用SQL执行方法即可实现

-(void)updateIcon{
    //更新对应的SQL语句
    NSString *SQL = [NSString stringWithFormat:@"UPDATE 't_User' SET icon='%@' WHERE name = '%@'",@"https://qiuxuewei.com/newIcon.png",@"name_6"];
    if ([[SQLiteManager shareInstance] execSQL:SQL]) {
        NSLog(@"对应数据修改成功");
    }
}

项目中的Model自定义对象可以自定义一个将自身插入数据库的方法

-(BOOL)insertSelfToDB{
    //插入对象的SQL语句
    NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO 't_User' (name,age,icon) VALUES ('%@',%ld,'%@');",self.name,self.age,self.icon];
    return [[SQLiteManager shareInstance] execSQL:insertSQL];
}

查询数据库中对应表中所有数据

#pragma mark - 查询数据库中数据
-(NSArray *)querySQL:(NSString *)SQL{
    //准备查询
    // 1> 参数一:数据库对象
    // 2> 参数二:查询语句
    // 3> 参数三:查询语句的长度:-1
    // 4> 参数四:句柄(游标对象)
//    sqlite3_prepare_v2(<#sqlite3 *db#>, <#const char *zSql#>, <#int nByte#>, <#sqlite3_stmt **ppStmt#>, <#const char **pzTail#>)
    sqlite3_stmt *stmt = nil;
    if (sqlite3_prepare_v2(self.db, SQL.UTF8String, -1, &stmt, nil) != SQLITE_OK) {
        NSLog(@"准备查询失败!");
        return NULL;
    }
    //准备成功,开始查询数据
    //定义一个存放数据字典的可变数组
    NSMutableArray *dictArrM = [[NSMutableArray alloc] init];
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        //一共获取表中所有列数(字段数)
        int columnCount = sqlite3_column_count(stmt);
        //定义存放字段数据的字典
        NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
        for (int i = 0; i < columnCount; i++) {
            // 取出i位置列的字段名,作为字典的键key
            const char *cKey = sqlite3_column_name(stmt, i);
            NSString *key = [NSString stringWithUTF8String:cKey];

            //取出i位置存储的值,作为字典的值value
            const char *cValue = (const char *)sqlite3_column_text(stmt, i);
            NSString *value = [NSString stringWithUTF8String:cValue];

            //将此行数据 中此字段中key和value包装成 字典
            [dict setObject:value forKey:key];
        }
        [dictArrM addObject:dict];
    }
    return dictArrM;
}

在自定义模型中有必要定义个工厂方法可将数据库对应表中所有数据取出,以模型数组的形式输出

+(NSArray *)allUserFromDB{
    //查询表中所有数据的SQL语句
    NSString *SQL = @"SELECT name,age,icon FROM 't_User'";
    //取出数据库用户表中所有数据
    NSArray *allUserDictArr = [[SQLiteManager shareInstance] querySQL:SQL];
    NSLog(@"%@",allUserDictArr);
    //将字典数组转化为模型数组
    NSMutableArray *modelArrM = [[NSMutableArray alloc] init];
    for (NSDictionary *dict in allUserDictArr) {
        [modelArrM addObject:[[User alloc] initWithDict:dict]];
    }
    return modelArrM;
}

当然,github已经上传源代码:https://github.com/qxuewei/Swift-test/tree/master/SQLite%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C-0C