iOS sqlite 简单封装使用

欢迎大家关注我的公众号,我会定期分享一些我在项目中遇到问题的解决办法和一些iOS实用的技巧,现阶段主要是整理出一些基础的知识记录下来

文章也会同步更新到我的博客:
ppsheep.com

sqlite几乎在每个APP编码都会涉及到,它是一种轻量级的数据库,在手机端使用起来极其方便,因为SQLite原生的接口都是使用C写的,不是特别友好,所有有一个强大库就出现了FMDB,今天我们基于FMDB来进行二次封装

项目结构

首先来看一下我的项目结构

封装思路

数据层的基本封装思路是:

  • 首先我们需要一个数据库管理类,这个管理类主要是管理数据库文件,因为我们可能会有很多个数据库文件,需要这样一个管理类
  • 一个基础的BaseDBStore,其中主要是我们需要执行的一些基本的操作,包括增、删、改、查,然后每个模块需要使用到数据库的时候,他们有单独的子模块,是从Base继承而来

数据库管理类的实现代码:

#import 
#import "FMDB.h"

@interface PPSDBManager : NSObject


/**
 *  DB队列  还可以定义其他的数据库 这里只是一个示例
 */
@property (nonatomic, strong) FMDatabaseQueue *commonQueue;

+ (PPSDBManager *)sharedInstance;

/**
 创建数据库文件

 @param userId 传入用户id
 @return 数据库文件地址
 */
+ (NSString *)dbPath:(NSString *)userId;

@end复制代码

这里加入了用户思想,即每个用户是一个数据库文件,这样好区分,而且每个用户可以拥有不同的数据库文件,这里只创建了一个,当然还可以创建很多个

#import "PPSDBManager.h"

static PPSDBManager *manager;
@implementation PPSDBManager

+(PPSDBManager *)sharedInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *userID = @"ppsheep";//随便写了一个id
        manager = [[PPSDBManager alloc] initWithUserId:userID];
    });
    return manager;
}


/**
 一般的,如果有用户的APP,这里就可以传入当前用户的id 用以区分数据库
 这里我就随便写了
 @param userId 用户id
 @return 实例
 */
- (instancetype)initWithUserId:(NSString *)userId{
    if (self = [super init]) {
        NSString *commonQueuePath = [PPSDBManager dbPath:userId];
        self.commonQueue = [FMDatabaseQueue databaseQueueWithPath:commonQueuePath];
    }
    return self;
}


/**
 数据库文件地址

 @return 地址
 */
+ (NSString *)dbPath: (NSString *)userId{
     NSString *path = [NSString stringWithFormat:@"%@/User/%@/Setting/DB/", NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0], userId];
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        //创建数据库文件
        NSError *error;
        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
        if (error) {
            NSLog(@"创建数据库文件失败:%@",path);
        }
    }
    return [path stringByAppendingString:@"common.sqlite3"];
}

@end复制代码

BaseStore

#import 
#import "PPSDBManager.h"

@interface PPSDBBaseStore : NSObject


// 数据库操作队列(从NADBManager中获取,默认使用commonQueue)
@property (nonatomic, weak) FMDatabaseQueue *dbQueue;

/**
 *  表创建
 */
- (BOOL)createTable:(NSString*)tableName withSQL:(NSString*)sqlString;

/*
 *  执行带数组参数的sql语句 (增,删,改)
 */
-(BOOL)excuteSQL:(NSString*)sqlString withArrParameter:(NSArray*)arrParameter;

/*
 *  执行带字典参数的sql语句 (增,删,改)
 */
-(BOOL)excuteSQL:(NSString*)sqlString withDicParameter:(NSDictionary*)dicParameter;

/*
 *  执行格式化的sql语句 (增,删,改)
 */
- (BOOL)excuteSQL:(NSString *)sqlString,...;

/**
 *  执行查询指令
 */
- (void)excuteQuerySQL:(NSString*)sqlStr resultBlock:(void (^)(FMResultSet * rsSet))resultBlock;

@end复制代码

Base定义的一些基础的操作,注释都写的很清楚,我就不一一解释了

//查询语句
- (BOOL)excuteSQL:(NSString *)sqlString,...
{
    __block BOOL ok = NO;
    if (self.dbQueue) {
        va_list args;
        va_list *p_args;
        p_args = &args;
        va_start(args, sqlString);
        [self.dbQueue inDatabase:^(FMDatabase *db) {
            ok = [db executeUpdate:sqlString withVAList:*p_args];
        }];
        va_end(args);
    }
    return ok;
}复制代码

带参数的查询方法:

- (BOOL)excuteSQL:(NSString *)sqlString withArrParameter:(NSArray *)arrParameter
{
    __block BOOL ok = NO;
    if (self.dbQueue) {
        [self.dbQueue inDatabase:^(FMDatabase *db) {
            ok = [db executeUpdate:sqlString withArgumentsInArray:arrParameter];
        }];
    }
    return ok;
}复制代码

Base里面的方法,都是调用FMDB

User模块

现在,我们有一个User模块,需要实现用户的存取,首先,我们需要一个装SQL的文件,分离SQL

PPSDBUserSQL.h

#ifndef PPSDBUserSQL_h
#define PPSDBUserSQL_h



#define     USER_TABLE_NAME              @"user"
/**
 *  建表
 *
 *  @param uid   当前用户Corp邮箱前缀
 *  @param fid    好友Corp邮箱前缀
 *  @param email   Corp邮箱
 *
 *  @return
 */
#define     SQL_CREATE_USER_TABLE        
            @"CREATE TABLE IF NOT EXISTS %@(\
                    uid TEXT,\
                    name TEXT,\
                    email TEXT,\
                    phoneNum TEXT,\
                    ext1 TEXT,\
                    ext2 TEXT,\
                    ext3 TEXT,\
                    ext4 INTEGER DEFAULT (0),\
                    ext5 INTEGER DEFAULT (0),\
                    ext6 INTEGER DEFAULT (0),\
                    PRIMARY KEY(uid))"

#define     SQL_ADD_USER      @"INSERT OR REPLACE INTO %@ ( uid, name, email, phoneNum, ext1, ext2, ext3, ext4, ext5, ext6) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

#define     SQL_SELECT_USER   @"SELECT * FROM %@ WHERE uid = '%@'"

#define     SQL_GET_ALL_USER   @"SELECT * FROM %@ "

#define     SQL_DELETE_USER    @"DELETE FROM %@ WHERE uid = '%@'"

#define     SQL_UPDATE_USER    @"UPDATE %@ SET name = ?, email = ?, phoneNum = ? WHERE uid = '%@' "


#endif /* PPSDBUserSQL_h */复制代码

然后是具体的操作User的Store 包含了基本的

#import "PPSDBBaseStore.h"

@class PPSUser;
@interface PPSDBUserStore : PPSDBBaseStore

//改
- (BOOL)updateUserData:(NSArray *)users;

//增
- (BOOL)addUser:(NSArray *)users;

//查
- (NSMutableArray *)usersByUserIds:(NSArray *)userIds;

//删
- (BOOL)deleteUserByUid:(NSArray *)userIds;

- (NSArray *)allUsers;

@end复制代码

批量查询用户,传入id数组

-(NSMutableArray *)usersByUserIds:(NSArray *)userIds{
    NSArray *ids = [userIds copy];
    __block NSMutableArray *data = [[NSMutableArray alloc] init];

    for (NSString *userId in ids) {
      NSString *sqlString = [NSString stringWithFormat:SQL_SELECT_USER, USER_TABLE_NAME, userId];
        [self excuteQuerySQL:sqlString resultBlock:^(FMResultSet *retSet) {
            while ([retSet next]) {
                NSDictionary *dic = @{
                                      @"userId" : [retSet stringForColumn:@"uid"],
                                      @"email" : [retSet stringForColumn:@"email"],
                                      @"name" : [retSet stringForColumn:@"name"],
                                      @"phoneNum" : [retSet stringForColumn:@"phoneNum"],
                                      };
                PPSUser *user = [[PPSUser alloc] initWithDic:dic];
                [data addObject:user];
            }
            [retSet close];
        }];
    }
    return data;
}复制代码

批量更新用户,传入用户数组

-(BOOL)updateUserData:(NSArray *)users{
    NSArray *userCopy = [users copy];
    BOOL ok = YES;
    for (PPSUser *user in userCopy) {
        NSString *sql = [NSString stringWithFormat:SQL_UPDATE_USER, USER_TABLE_NAME, user.userId];
        NSArray *arrPara = [NSArray arrayWithObjects:
                            PPSNoNilString(user.name),
                            PPSNoNilString(user.email),
                            PPSNoNilString(user.phoneNum),
                            @"", @"", @"", @0, @0, @0,  nil];
        ok = [self excuteSQL:sql withArrParameter:arrPara];
    }
    return ok;
}复制代码

使用

为了方便,我就直接在ViewController中写了,在真正的开发中,一般都会在管理类中进行数据库操作

懒加载一个用户数据库

-(PPSDBUserStore *)store{
    if (!_store) {
        _store = [[PPSDBUserStore alloc] init];
    }
    return _store;
}复制代码

初始化用户,直接插入

- (void)initUsers{
    NSMutableArray *arr = [NSMutableArray array];
    for (int i=0; i<10; i++)="" {="" ppsuser="" *user="[[PPSUser" alloc]="" init];="" user.userid="[NSString" stringwithformat:@"%ld_userid",(long)i];="" user.name="[NSString" stringwithformat:@"%ld_username",(long)i];="" user.email="[NSString" stringwithformat:@"%ld_email",(long)i];="" user.phonenum="[NSString" stringwithformat:@"%ld_phonenum",(long)i];="" [arr="" addobject:user];="" }="" [self.store="" adduser:arr];="" }<="" code="">10;>复制代码

我就不再贴代码出来了,项目工程,我放在了

github.com/yangqian111…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值