数据库

IOS框架:使用数据库类框架

2020-11-05  本文已影响0人  时光啊混蛋_97boy

目录

一、FMDB

a、简介

FMDB是用OC语言封装了SQLite API的数据库框架。

优点
缺点
使用
b、FMDB的简单Demo
UserModel
@interface UserModel : NSObject

@property (nonatomic, strong) NSString *userId;
@property (nonatomic, strong) NSString *userName;
@property (nonatomic, strong) NSString *passWord;

@end

@implementation UserModel

@end
FMDBManager.h文件
@interface FMDBManager : NSObject

// 单例获取对象
+ (FMDBManager *)sharedFMDB;

// 创建表
- (void)createTable;

// 插入记录
- (void)insertUserWithUserName:(NSString *)userName password:(NSString *)password;

// 获取所有记录
- (NSMutableArray *)getAllUser;

// 删除某人所有信息
- (BOOL)deleteUser:(NSInteger)userID;

@end
FMDBManager.m文件
@interface FMDBManager()
{
    NSString *_dataBasePath;// 数据库的路径
    FMDatabase *_fmdbDataBase;// 数据库对象
    BOOL _isFMDBopen;// 是否打开了数据库
}
@end

static FMDBManager *_sharedFMDB = nil;// 单例

@implementation FMDBManager

// 共享实例
+ (FMDBManager *)sharedFMDB
{
    
    if (_sharedFMDB == nil)
    {
        _sharedFMDB = [[FMDBManager alloc] init];
    }
    return _sharedFMDB;
}

// 初始化
- (id)init
{
    self = [super init];
    if (self)
    {
        // 打开数据库
        [self openDataBase];
    }
    return self;
}

@end
打开数据库
- (void)openDataBase
{
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dataBasePath = [documentPath stringByAppendingPathComponent:@"FMDBDemo.sqlite"];
    _dataBasePath = dataBasePath;
    
    // 创建数据库
    if (_dataBasePath.length > 0)
    {
        _fmdbDataBase = [FMDatabase databaseWithPath:dataBasePath];
    }
    
    // 成功打开了数据库
    if ([_fmdbDataBase open])
    {
        _isFMDBopen = YES;
    }
    else
    {
        _isFMDBopen = NO;
        NSLog(@"打开数据库发生了错误");
    }
}
判断数据库中是否存在某张表
- (BOOL)isExistTable:(NSString *)tableName
{
    // 执行查询表的语句
    FMResultSet *resultSet = [_fmdbDataBase executeQuery:@"select count(*) as 'count' from sqlite_master where type ='table' and name = ?", tableName];
    
    while ([resultSet next])
    {
        // 表数
        NSInteger count = [resultSet intForColumn:@"count"];
        
        if (0 == count)
        {
            NSLog(@"表不存在");
            return NO;
        }
        else
        {
            NSLog(@"表已存在");
            return YES;
        }
    }
    
    return NO;
}
创建表
- (void)createTable
{
    NSString *createTableSQL = [NSString stringWithFormat:@"CREATE TABLE 'LuckCoffeeUser' ('userID' INTEGER PRIMARY KEY AUTOINCREMENT  NOT NULL, 'userName' text, 'passWord' text)"];
    
    // 不存在瑞幸咖啡用户这张表格则进行创建
    if (![self isExistTable:@"LuckCoffeeUser"])
    {
        BOOL isSuccess = [_fmdbDataBase executeUpdate:createTableSQL];
        if (!isSuccess)
        {
            NSLog(@"当创建瑞幸咖啡用户表的时候发生了错误");
        }
        else
        {
            NSLog(@"成功创建了瑞幸咖啡用户表");
        }
    }
}
插入数据
- (void)insertUserWithUserName:(NSString *)userName password:(NSString *)password
{
    NSString *insertUserSQL = [NSString stringWithFormat:@"insert into LuckCoffeeUser (userName, passWord) values(?, ?) "];
    BOOL isSuccess = [_fmdbDataBase executeUpdate:insertUserSQL,userName,password];
    
    if (!isSuccess)
    {
        NSLog(@"插入数据到瑞幸咖啡用户表的时候发生了错误");
    }
    else
    {
        NSLog(@"成功插入数据到瑞幸咖啡用户表");
    }
}
获取所有记录
- (NSMutableArray *)getAllUser
{
    NSMutableArray *userList = [[NSMutableArray alloc] init];
    
    NSString *queryAllUserSQL = [NSString stringWithFormat:@"select * from LuckCoffeeUser"];
    FMResultSet *resultSet = [_fmdbDataBase executeQuery:queryAllUserSQL];
    
    while ([resultSet next])
    {
        UserModel *user = [[UserModel alloc] init];
        user.userId = [NSString stringWithFormat:@"%d",[resultSet intForColumn:@"userID"]];
        user.userName = [resultSet stringForColumn:@"userName"];
        user.passWord = [resultSet stringForColumn:@"passWord"];
        [userList addObject:user];
    }
    
    return userList;
}
删除某一条记录
- (BOOL)deleteUser:(NSInteger)userID
{
    NSString *deleteUserSQL = [NSString stringWithFormat:@"delete from LuckCoffeeUser where userID=%ld",(long)userID];
    return [_fmdbDataBase executeUpdate:deleteUserSQL];
}
使用方式
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [[FMDBManager sharedFMDB] createTable];// 创建表
    // 插入
    [[FMDBManager sharedFMDB] insertUserWithUserName:@"XieJiaPei" password:@"1525122040"];
    [[FMDBManager sharedFMDB] insertUserWithUserName:@"BaiLuoMei" password:@"1625122040"];
    [[FMDBManager sharedFMDB] insertUserWithUserName:@"FanYiCheng" password:@"1725122040"];
    [[FMDBManager sharedFMDB] insertUserWithUserName:@"SunWuKong" password:@"1825122040"];
    [[FMDBManager sharedFMDB] insertUserWithUserName:@"LinFengMian" password:@"1925122040"];

    // 看看插入后的表格情况
    NSArray *userListAfterInsert = [[FMDBManager sharedFMDB] getAllUser];
    for (UserModel *user in userListAfterInsert)
    {
        NSLog(@"用户ID:%@,用户名称:%@,用户密码:%@",user.userId,user.userName,user.passWord);
    }
    
    [[FMDBManager sharedFMDB] deleteUser:2];
    
    // 看看删除后的表格情况
    NSArray *userListAfterDelete = [[FMDBManager sharedFMDB] getAllUser];
    for (UserModel *user in userListAfterDelete)
    {
        NSLog(@"用户ID:%@,用户名称:%@,用户密码:%@",user.userId,user.userName,user.passWord);
    }
}
输出结果

创建表格:

2020-10-20 18:17:41.461224+0800 框架Demo[28427:4977235] 表不存在
2020-10-20 18:17:41.462389+0800 框架Demo[28427:4977235] 成功创建了瑞幸咖啡用户表

插入数据:

2020-10-20 18:17:41.463243+0800 框架Demo[28427:4977235] 成功插入数据到瑞幸咖啡用户表
2020-10-20 18:17:41.463945+0800 框架Demo[28427:4977235] 成功插入数据到瑞幸咖啡用户表
2020-10-20 18:17:41.464546+0800 框架Demo[28427:4977235] 成功插入数据到瑞幸咖啡用户表
2020-10-20 18:17:41.465169+0800 框架Demo[28427:4977235] 成功插入数据到瑞幸咖啡用户表
2020-10-20 18:17:41.465786+0800 框架Demo[28427:4977235] 成功插入数据到瑞幸咖啡用户表

2020-10-20 18:17:41.465993+0800 框架Demo[28427:4977235] 用户ID:1,用户名称:XieJiaPei,用户密码:1525122040
2020-10-20 18:17:41.466070+0800 框架Demo[28427:4977235] 用户ID:2,用户名称:BaiLuoMei,用户密码:1625122040
2020-10-20 18:17:41.466127+0800 框架Demo[28427:4977235] 用户ID:3,用户名称:FanYiCheng,用户密码:1725122040
2020-10-20 18:17:41.466189+0800 框架Demo[28427:4977235] 用户ID:4,用户名称:SunWuKong,用户密码:1825122040
2020-10-20 18:17:41.466262+0800 框架Demo[28427:4977235] 用户ID:5,用户名称:LinFengMian,用户密码:1925122040

删除数据:

2020-10-20 18:17:41.467637+0800 框架Demo[28427:4977235] 用户ID:1,用户名称:XieJiaPei,用户密码:1525122040
2020-10-20 18:17:41.467712+0800 框架Demo[28427:4977235] 用户ID:3,用户名称:FanYiCheng,用户密码:1725122040
2020-10-20 18:17:41.467781+0800 框架Demo[28427:4977235] 用户ID:4,用户名称:SunWuKong,用户密码:1825122040
2020-10-20 18:17:41.467853+0800 框架Demo[28427:4977235] 用户ID:5,用户名称:LinFengMian,用户密码:1925122040
c、FMDB下载缓存图片的Demo
运行效果
运行效果
CreateDatabase.h文件
/** 用来缓存网络图片的数据库 */
@interface CreateDatabase : NSObject

/** 创建表单 */
- (BOOL)createTable;
/** 查询数据 */
- (NSString *)selectData:(NSString *)remoteUrl;
/** 删除数据 */
- (BOOL)deleteData:(NSString *)remoteUrl;
/** 添加数据 */
- (BOOL)addData:(NSString *)imageUrl remoteUrl:(NSString *)remoteUrl;

@end
CreateDatabase.m文件
#import <FMDB.h>

@interface CreateDatabase ()

@property (nonatomic, strong, readwrite) FMDatabase *db;// 数据库
@property (nonatomic, strong, readwrite) FMDatabaseQueue *queue;// 任务队列

@end

@implementation CreateDatabase
.......
@end
初始化数据库
- (instancetype)init
{
    self = [super init];
    if (self)
    {
        NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *path = [documentPath stringByAppendingString:@"/xiejiapei.db"];
        NSURL *url = [NSURL URLWithString:path];
        
        NSLog(@"数据库地址为:%@", url);
        
        // 创建数据库和任务队列
        _queue = [FMDatabaseQueue databaseQueueWithURL:url];
        _db = [FMDatabase databaseWithURL:url];
        
        if (![_db open]) {
            NSLog(@"打开数据库失败");
        }
    }
    return self;
}
创建表单
- (BOOL)createTable
{
    // 打开数据库
    [_db open];
    
    // 创建表单的SQL语句
    NSString *sql = @"CREATE TABLE IF NOT EXISTS Image (remote_url text PRIMARY KEY NOT NULL, image_url text NOT NULL)";
    
    // 执行SQL语句
    BOOL success = [_db executeUpdate:sql];
    if (!success || [_db hadError])// 创建表单失败
    {
        // 关闭数据库
        [_db close];
        return NO;
    }
    else
    {
        // 关闭数据库
        [_db close];
        return YES;
    }
}
查询数据库
- (NSString *)selectData:(NSString *)remoteUrl
{
    // 打开数据库
    [_db open];
    
    // 查询SQL语句
    FMResultSet *userResult = [_db executeQuery:[NSString stringWithFormat:@"SELECT * FROM image where remote_url = '%@';", remoteUrl]];
    
    // 获取查询结果
    NSString *imageUrl = [[NSString alloc] init];
    while ([userResult next])
    {
        imageUrl = [userResult stringForColumn:@"image_url"];
    }
    
    // 关闭数据库
    [_db close];
    
    return imageUrl;
}
删除数据
- (BOOL)deleteData:(NSString *)remoteUrl
{
    // 打开数据库
    [_db open];
    
    // 删除数据的SQL语句
    BOOL success = [_db executeUpdate:@"delete from image where image_url = ?", remoteUrl];
    
    if (!success || [_db hadError])// 删除数据失败
    {
        // 关闭数据库
        [_db close];
        return NO;
    }
    else
    {
        // 关闭数据库
        [_db close];
        return YES;
    }
}
添加数据
- (BOOL)addData:(NSString *)imageUrl remoteUrl:(NSString *)remoteUrl
{
    // 打开数据库
    [_db open];
    
    // 添加数据的SQL语句
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        [_db executeUpdate:@"INSERT INTO image ('image_url','remote_url') VALUES (?,?);", imageUrl ,remoteUrl];
    }];
    
    if ([_db hadError])// 添加数据失败
    {
        // 关闭数据库
        [_db close];
        return NO;
    }
    else
    {
        // 关闭数据库
        [_db close];
        return YES;
    }
}
FMDBViewController.m文件
@interface FMDBViewController ()

// 获取得到的图片
@property (nonatomic,assign) UIImage *image;
// 图片缓存字典
@property (nonatomic, strong) NSMutableDictionary *imageCacheDict;
// 数据库
@property (nonatomic, strong) CreateDatabase *dataBase;
// 图像
@property (nonatomic, strong) UIImageView *imageView;

@end

@implementation FMDBViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self createSubviews];
}

- (void)createSubviews
{
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIImageView *imageView = [[UIImageView alloc] init];
    imageView.frame = CGRectMake(100, 100, 150, 150);
    [self.view addSubview:imageView];
    self.imageView = imageView;
    
    self.imageCacheDict = [[NSMutableDictionary alloc] init];
    self.dataBase = [[CreateDatabase alloc] init];
    [self.dataBase createTable];
    
    [self showImageWithURLString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602901210&di=ce8b81d6dd50cf12263f36843f7bccd4&imgtype=jpg&er=1&src=http%3A%2F%2Fpics4.baidu.com%2Ffeed%2F3801213fb80e7bec1f568379f76a1e3e9a506b61.png%3Ftoken%3D84b2fa3895a800155fdf9802d26ca6c5"];
}

.......

@end
显示图片
- (void)showImageWithURLString:(NSString *)imageURL
{
    // 根据imageURL查询数据库后将URL保存到图片缓存字典,imageURL作为key
    self.imageCacheDict[imageURL] = [NSURL URLWithString:[self.dataBase selectData:[imageURL lastPathComponent]]];
    // 获取刚才保存的URL
    NSURL *cachedImageURL = self.imageCacheDict[imageURL];
    
    // 有效期为一天,过期删除
    NSArray *timeArray = [[cachedImageURL.path lastPathComponent] componentsSeparatedByString:@"+"];
    NSTimeInterval time = [[NSDate date] timeIntervalSince1970] * 1000;
    BOOL isValid = (time - [timeArray[1] integerValue]) < 24 *3600;
    
    // 获取图片
    UITableViewCell *cell;
    if (cachedImageURL && isValid)// 缓存图片存在且有效
    {
        // 从URL中读取图片并显示
        self.imageView.image = [self imageForURL:cachedImageURL];
    }
    else if (cachedImageURL && !isValid)// 缓存图片存在但是无效
    {
        // 从字典和数据库中移除缓存图片
        [self.imageCacheDict removeObjectForKey:imageURL];
        [self.dataBase deleteData:[imageURL lastPathComponent]];
        
        // 下载新的图片并显示
        [self downloadImage:imageURL forCell:cell];
    }
    else// 缓存图片不存在
    {
        // 下载新的图片并显示
        [self downloadImage:imageURL forCell:cell];
    }
}

// 从URL中读取图片
- (UIImage *)imageForURL:(NSURL *)imageURL
{
    NSData *data = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:data];
    return image;
}
下载(异步加载)
- (void)downloadImage:(NSString *)imageURL forCell:(UITableViewCell *)cell
{
    // 下载远端图片数据
    __weak FMDBViewController *weakself = self;

    NSURL *downloadURL = [NSURL URLWithString:imageURL];
    NSURLSession *URLSession = [NSURLSession sharedSession];
    NSURLSessionDownloadTask *task = [URLSession downloadTaskWithURL:downloadURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        // 获取图片的URL
        NSURL *cachedImageURL = [self writeImageToCacheFromLocation:location forDownloadURL:downloadURL];
        // 在主线程更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            // 保存到图片缓存字典
            weakself.imageCacheDict[imageURL] = cachedImageURL;
            // 保存到数据库
            [weakself.dataBase addData:[NSString stringWithFormat:@"%@", cachedImageURL] remoteUrl:[NSString stringWithFormat:@"%@", [imageURL lastPathComponent]]];
            // 更新UI
            weakself.imageView.image = [self imageForURL:cachedImageURL];
        });
    }];
    [task resume];
}
写入缓存
- (NSURL *)writeImageToCacheFromLocation:(NSURL *)location forDownloadURL:(NSURL *)downloadURL
{
    // 创建缓存图片目录
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *applocationSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
    NSString *imageDirPath = [applocationSupportURL.path stringByAppendingPathComponent:@"image"];
    if (![fileManager fileExistsAtPath:imageDirPath])
    {
        [fileManager createDirectoryAtPath:imageDirPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    // 给路径传一个有效时间
    NSTimeInterval time = [[NSDate date] timeIntervalSince1970] * 1000;
    NSString *fileName = [downloadURL.path lastPathComponent];
    NSString *imagePath = [imageDirPath stringByAppendingPathComponent:fileName];
    NSString *imagePathWithTime = [imagePath stringByAppendingString:[NSString stringWithFormat:@"%@%f",@"+" , time]];
    
    // 拷贝下载的图片到目标路径
    NSURL *imageURL = [NSURL fileURLWithPath:imagePathWithTime];
    [fileManager copyItemAtURL:location toURL:imageURL error:nil];
    return imageURL;
}

Demo

Demo在我的Github上,欢迎下载。
UseFrameworkDemo

参考文献

上一篇 下一篇

猜你喜欢

热点阅读