iOS 技巧iOS基础类

iOS-OC 新手 数据库之FMDB 看这篇就够了(附Demo)

2020-06-03  本文已影响0人  洧中苇_4187

1. FMDB数据存储 - 概念篇

首先FMDB是对苹果sqlite的封装,sqlite是苹果自带的,FMDB给我们封装了很多好用的接口.那么数据库可以存储哪些类型数据呢,我们来一一解答

这个就是苹果自带的,可以操作数据库的包 image.png

1.1 FMDB可以存储哪些类型数据
* INTEGER 整型
* TEXT 文本
* REAL 浮点型
* BLOB 二进制

对应到OC里面就是
INTEGER ->int,
TEXT -> NSString,
REAL -> float,
BLOB -> NSData.
所以 如果我们要存储对象,或者图片的话,需要将其转换成NSData格式,
存储对象类型还需要进行必要的归档操作.

1.2 归档操作的步骤如下

1.需要实现这个协议 NSSecureCoding,
@interface MJPerson : NSObject  <NSCoding,NSSecureCoding>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@end

2. 必须要实现这个方法,因为之前的归档,苹果认为是不安全的,会出现数据错乱的情况,所以修改了归解档的方法,
@implementation MJPerson
+ (BOOL)supportsSecureCoding{
    return YES;
}

3. 再实现归解档
//归档的时候调用
//告诉编码器该如何归档
//将这个对象哪些属性编码起来
- (void)encodeWithCoder:(NSCoder *)encoder{//归档
    [encoder encodeObject:self.name forKey:@"name"];
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(省略内容)
}
@end

上述是在模型操作,接下来是和NSData - MJPerson的转换

归档: 转化为NSData----------------------------------------------------------------
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person
 requiringSecureCoding:YES error:nil];

解档: 转化为MJPerson模型----------------------------------------------------------------
NSData *tmpData = [result objectForColumn:@"data"];//打印 "data"列
MJPerson *tmpPerson2 = [NSKeyedUnarchiver unarchivedObjectOfClass:
[MJPerson class] fromData:tmpData error:nil];

2. FMDB数据存储 - SQlite篇

在对数据库进行 增删改查 之前,必须要先 打开 数据库,操作完成之后,关闭数据库

2.1 创建一个数据库 - 以我的Demo工程为例
2.1.1首先创建一个从操作数据库的单例

@implementation GirlsDBTool

static FMDatabase *db_;
+ (instancetype)shareInstance{
    static GirlsDBTool *mydb = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mydb = [[GirlsDBTool alloc]init];
    });
    //创建数据库
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"person.db"];
    NSLog(@"path: %@",path);
    
    db_ = [FMDatabase databaseWithPath:path];
    return mydb;
}

- (FMDatabase *)db{
    return db_;
}

@end

2.1.2 用数据库单例创建一张表(girls_table)

 GirlsDBTool *girsDB = [GirlsDBTool shareInstance];

    BOOL isOpen = [girsDB.db open];
    if (isOpen) {
        NSString *sql = @"create table if not exists girls_table
        (id INTEGER primary key autoincrement,name TEXT not null ,
        height REAL not null ,weight REAL not null ,
        age INTEGER not null default 0,hobits TEXT not null,
        birthPlace TEXT not null,photo BLOB)";
}

参数说明 - 所有的sql 语句 大小写都支持,不管你的数据类型 是TEXT 还是text都可以

NSString *sql = @"
create table if not exists girls_table **如果不存在girls_table,则创建它
(id INTEGER primary key autoincrement, **主键 id,它会随着你数据递增
name TEXT not null , **创建name,数据类型为 字符串
height REAL not null , **创建height,浮点型
weight REAL not null ,
age INTEGER not null default 0, **创建age,整型
hobits TEXT not null,
birthPlace TEXT not null,
photo BLOB)"; **创建photo,NSData类型

2.1.3 将数据库语句 在这执行 每执行一条sql语句就会返回一个BOOL值,YES表示执行成功

BOOL isSuccess = [girsDB.db executeUpdate:sql];

如果成功,接下来就可以存数据了
BOOL isSaved = [girsDB.db executeUpdateWithFormat:
@"insert into girls_table(name,height,weight, age,hobits, birthPlace, photo)
 values(%@,%f,%f,%d,%@,%@,%@)", value0,value1.floatValue,value2.floatValue,
value3.intValue,value4,value5,value6];

 完成操作后关闭数据库
 if ([girsDB.db close]) {
     NSLog(@"关闭数据库");
 }

小结:上述步骤就是如下几点
1.获取数据库单例,打开数据库, BOOL isOpen = [girsDB.db open];

  1. 执行sql语句 ,先建表,
  2. 存储你需要存储的数据,
    4.关闭数据库,

我这里使用了数据库可视化软件 Navicat Premium可以查看数据库变更容易,里面数据库的地址就是单例里面的那个路径(NSTemporaryDirectory()),每次操作完之后,快捷键command + R 刷新数据库

3DLKSBBOTr.gif

3. FMDB API的一些说明

除开查询(query),其他的操作都可以认为是更新操作,修改-删除-新增都是(update)
FMDatabase操作的数据库表,
FMResultSet查询返回的结果集
FMDatabaseQueue多线程操作数据库

查询

查询语句执行之后返回一个结果集FMResultSet,然后你在while循环里取你要的参数,为什么要搞一个while循环??? 因为API就是这个设计的,

   打开数据库
   [self.db open];
    
    /**此种方式后面拼接的参数必须为对象 不可以为int double等基本数据类型*/
    [self.db executeQuery:@"select * from t_table"];
    
    /**此种方式后面拼接的参数可以为int double等基本数据类型 因为是使用的占位符*/
    [self.db executeQueryWithFormat:@"SELECT name, age, score from t_table where name = %@", @"Jake"];
    
    /**此种方式后面拼接的参数必须为对象 不可以为int double等基本数据类型 将对象依次防近视数组*/
    FMResultSet *result = [self.db executeQuery:@"select *from t_table where age > ?" withArgumentsInArray:@[@12]];
    while (result.next) {
        
        这里按照你的需求取值,取某个特定的名字,身高,某种数据类型,某一列.....
        NSLog(@"从数据库查询成功");
    }


    FMResultSet根据column name获取对应数据的方法
    intForColumn:
    longForColumn:
    longLongIntForColumn:
    boolForColumn:
    doubleForColumn:
    stringForColumn:
    dataForColumn:
    dataNoCopyForColumn:
    UTF8StringForColumnIndex:
    objectForColumn:

修改

 [self.db open];
   0.直接sql语句
  BOOL result = [db executeUpdate:@"update 'yp_table' set ID = 110 where name = 'x1'"];
  1.
  BOOL result = [db executeUpdate:@"update 'yp_table' set ID = ? where name = ?",@111,@"x2" ];
  2.
  BOOL result = [db executeUpdateWithFormat:@"update 'yp_table' set ID = %d where name = %@",113,@"x3" ];
  3.
  BOOL result = [self.db executeUpdate:@"update 'yp_table' set ID = ? where name = ?" withArgumentsInArray:@[@113,@"x3"]];
    if (result) {
        NSLog(@"update 'yp_table' success");
    } else {
        NSLog(@"insert into 't_studet' fail");
    }
    [self.db close];

插入

    [self.db open];

    此种方式后面拼接的参数必须为对象 不可以为int double等基本数据类型
    [self.db executeUpdate:@"insert into t_table(name, age, score, data) values(?, ? , ?, ?)", @"jake", @12, @91.0, [NSData data]];
    /**此种方式后面拼接的参数可以为int double等基本数据类型 因为是使用的占位符*/
    [self.db executeUpdateWithFormat:@"insert into t_table(name, age, score, data) values(%@, %d , %f, %@)", @"jake", 12, 91.0, [NSData data]];
    /**此种方式后面拼接的参数必须为对象 不可以为int double等基本数据类型 将对象依次放进数组*/
    [self.db executeUpdate:@"insert into t_table(name, age, score, data) values(?, ? , ?, ?)" withArgumentsInArray:@[@12, @91.0, [NSData data]]];

    BOOL result = [self.db executeUpdate:@"insert into 'yp_table'(ID,name,phone,score) values(?,?,?,?)" withArgumentsInArray:@[@113,@"x3",@"13",@53]];
    if (result) {
       NSLog(@"insert into 't_studet' success");
    } else {
       NSLog(@"insert into 't_studet' fail");
    }
    
    [self.db close];

删除

    [self.db open];
  0.直接sql语句
   BOOL result = [db executeUpdate:@"delete from 'yp_table' where ID = 110"];
  1.
  BOOL result = [db executeUpdate:@"delete from 'yp_table' where ID = ?",@(111)];
  2.
  BOOL result = [db executeUpdateWithFormat:@"delete from 'yp_table' where ID = %d",112];
  3.
  BOOL result = [self.db executeUpdate:@"delete from 'yp_table' where ID = ?" withArgumentsInArray:@[@113]];
    if (result) {
        NSLog(@"delete from 'yp_table' success");
    } else {
        NSLog(@"insert into 't_studet' fail");
    }
    [self.db close];
这个是运行的demo-包含增删改查-没有模拟多线程的情况

附上Demo地址 - 戳我

如果有错误-表达不够清晰的地方,评论区留言 - let me know

上一篇下一篇

猜你喜欢

热点阅读