iOS-數據存儲方式(含FMDB)

1 iOS中的數據存儲方式

1>存儲小數據,會在原路徑覆蓋式存儲mysql

    Plist         (只能存儲NSArray\NSDictionary)
    Preference(偏好設置\NSUserDefaults standardUserDefaults)git

    NSCoding (NSKeyedArchiver\NSkeyedUnarchiver)github

2>存儲大批量數據sql

    SQLite3        純C語言,輕量級,檢索速度快
    Core Data     OC語言數據庫

 

2 SQLite

1>什麼是SQLite

     SQLite是一款輕型的嵌入式數據庫
    它佔用資源很是的低,在嵌入式設備中,可能只須要幾百K的內存就夠了
    它的處理速度比Mysql、PostgreSQL這兩款著名的數據庫都還快api

 

2>字段類型

    SQLite將數據劃分爲如下幾種存儲類型:
    integer : 整型值
    real : 浮點值
    text : 文本字符串
    blob : 二進制數據(好比文件)

實際上SQLite是無類型的
就算聲明爲integer類型,仍是能存儲字符串文本(主鍵除外
建表時聲明啥類型或者不聲明類型均可以,也就意味着創表語句能夠這麼寫:
create table t_student(name, age);安全

 

3>創刪表

    1)建立表多線程

    create table if not exists 表名 (字段名1 字段類型1, 字段名2 字段類型2, …) ;框架

eg:create table t_student (id integer, name text, age inetger, score real) ;異步

    2)刪除表

    drop table if exists 表名 ;

eg:drop table t_student ;

 

4>CRUD(增刪改查語句)

   1)添加數據

    insert into 表名 (字段1, 字段2, …) values (字段1的值, 字段2的值, …) ;

eg:insert into t_student (name, age) values (‘mj’, 10) ; //數據庫中的字符串內容應該用單引號 ’ 括住

   2)刪除數據

    delete from 表名 ;

eg:delete from t_student ;//上面的示例會將t_student表中全部記錄都刪掉

   3)更新數據

    update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值, … ;
eg:update t_student set name = ‘jack’, age = 20 ; //會將表中全部記錄的name都改成jack,age都改成20

   4)查找數據

   select 字段1, 字段2 (或者*) from 表名 where 字段名 = 值

eg:select name, age from t_student ;
    select * from t_student ;

 

5>條件語句

若是隻想更新或者刪除某些固定的記錄,那就必須在DML語句後加上一些條件
條件語句的常見格式
where 字段 = 某個值 ;   // 不能用兩個 =
where 字段 is 某個值 ;   // is 至關於 =
where 字段 != 某個值 ;
where 字段 is not 某個值 ;   // is not 至關於 !=
where 字段 > 某個值 ;
where 字段1 = 某個值 and 字段2 > 某個值 ;  // and至關於C語言中的 &&
where 字段1 = 某個值 or 字段2 = 某個值 ;  //  or 至關於C語言中的 ||

 

6>起別名

別名再錶鏈接查詢很是有用

1)格式(字段和表均可以起別名)
    select 字段1 別名 , 字段2 別名 , … from 表名 別名 ;
    select 字段1 別名, 字段2 as 別名, … from 表名 as 別名 ;(別名能夠直接寫在字段後面,省略as)
    select 別名.字段1, 別名.字段2, … from 表名 別名 ;

eg:select name myname, age myage from t_student ;

     select s.name, s.age from t_student s ;    給t_student表起個別名叫作s,利用s來引用表中的字段

 

7>計算記錄的數量

select count (字段) from 表名 ;
select count ( * ) from 表名 ;
eg:select count (age) from t_student ;
     select count ( * ) from t_student where score >= 60;

 

8>排序

默認是升序

    select * from t_student order by age ;

    select * from t_student order by age desc ;  //降序
    select * from t_student order by age asc ;   // 升序(默認)

也能夠用多個字段進行排序
    select * from t_student order by age asc, height desc ;
    先按照年齡排序(升序),年齡相等就按照身高排序(降序)

 

9>約束

1>簡單約束

    not null :規定字段的值不能爲null
    unique :規定字段的值必須惟一
    default :指定字段的默認值

eg:create table t_student (id integer, name text not null unique, age integer not null default 1) ;

2>主鍵約束

主鍵(Primary Key,簡稱PK)用來惟一地標識某一條記錄
例如t_student能夠增長一個id字段做爲主鍵,至關於人的身份證
主鍵能夠是一個字段或多個字段,也就是說一張表能夠有多個主鍵,但最好只有1個

1)設計原則

    主鍵應當是對用戶沒有意義的
    永遠也不要更新主鍵
    主鍵不該包含動態變化的數據
    主鍵應當由計算機自動生成

若是想要讓主鍵自動增加(必須是integer類型),應該增長autoincrement
create table t_student (id integer primary key autoincrement, name text, age integer) ;

3>外鍵約束

利用外鍵約束能夠用來創建表與表之間的聯繫,一般是多屬性的一個表引用另外一個表的主鍵。
外鍵的通常狀況是:一張表的某個字段,引用着另外一張表的主鍵字段
新建一個外鍵
create table t_student (id integer primary key autoincrement, name text, age integer, class_id integer, constraint fk_student_class foreign key (class) references t_class (id));

constraint  fk_student_class foreign key  外鍵約束名
(class)     t_student表的class字段 
references
t_class (id)  另外一張表的主鍵字段

t_student表中有一個叫作fk_t_student_class_id_t_class_id的外鍵
這個外鍵的做用是用t_student表中的class_id字段引用t_class表的id字段

外鍵約束 還有級聯這個功能

 

10>錶鏈接查詢

1)嵌套查詢

SELECT id FROM t_food_type WHERE name = '粵菜';  //先查找粵菜的ID    
SELECT * From t_food WHERE food_type_id = (SELECT id FROM t_food_type WHERE name = '粵菜' );//經過粵菜的ID查找全部粵菜的信息

2)多表查詢

SELECT * from t_food, food_type_id;  //會查詢出兩個表笛卡爾積的內容
//咱們須要篩選兩邊ID相同的信息(須要用到起別名)
SELECT * From t_food f,t_food_type tf WHERE f.food_type_id = tf.id
//繼續篩選粵菜的信息
SELECT * From t_food f,t_food_type tf WHERE f.food_type_id = tf.id AND tf.name = ‘粵菜‘;

 

11>limit

    使用limit能夠精確地控制查詢結果的數量,好比每次只查詢10條數據
    select * from 表名 limit 數值1, 數值2 ;

    limit經常使用來作分頁查詢,好比每頁固定顯示5條數據,那麼應該這樣取數據
第1頁:limit 0, 5
第2頁:limit 5, 5
第3頁:limit 10, 5

第n頁:limit 5*(n-1), 5

eg:

select * from t_student limit 4, 8 ;
能夠理解爲:跳過最前面4條語句,而後取8條記錄
select * from t_student limit 7 ;
至關於select * from t_student limit 0, 7 ;
表示取最前面的7條記錄

 

12>模糊查詢

  1)使用LIKE代替=

  2)模糊查詢字符的格式 '%xxxx%'

  3)當使用NSString語句的時候,%是轉義字符。因此咱們用%%就代替%,意思就是表示這個%不是轉義支付

   SELECT name,price FROM t_shop WHERE  name LIKE '%李%' OR price LIKE '%2%';

 

3 FMDA

1>什麼是FMDA

FMDB以OC的方式封裝了SQLite的C語言API

FMDB的優勢
使用起來更加面向對象,省去了不少麻煩、冗餘的C語言代碼
對比蘋果自帶的Core Data框架,更加輕量級和靈活
提供了多線程安全的數據庫操做方法,有效地防止數據混亂

FMDB的github地址
https://github.com/ccgus/fmdb

 

2>FMDB有三個主要的類

1)FMDatabase
一個FMDatabase對象就表明一個單獨的SQLite數據庫
用來執行SQL語句

2)FMResultSet
使用FMDatabase執行查詢後的結果集

3)FMDatabaseQueue
用於在多線程中執行多個查詢或更新,它是線程安全的

 

3>建立或打開數據庫

FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
    NSLog(@"數據庫打開失敗!");
}

空字符串@"" 會在臨時目錄建立一個空的數據庫。當FMDatabase鏈接關閉時,數據庫文件也被刪除
nil會建立一個內存中臨時數據庫,當FMDatabase鏈接關閉時,數據庫會被銷燬

 

4>執行更新

在FMDB中,除查詢之外的全部操做,都稱爲「更新」
create、drop、insert、update、delete等      

使用executeUpdate:方法執行更新

- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments

示例  FMDB中SQL語句字符串不須要加''

//插入數據
        [db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
            @"hi'", // look!  I put in a ', and I'm not escaping it!
            [NSString stringWithFormat:@"number %d", i],
            [NSNumber numberWithInt:i],
            [NSDate date],
            [NSNumber numberWithFloat:2.2f]];
    }
    
//更新數據
[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]

 

5>執行查詢

查詢方法

- (FMResultSet *)executeQuery:(NSString*)sql, ...
- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments

示例.遍歷結果集

FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"];

// 遍歷結果集
while ([rs next]) {
    NSString *name = [rs stringForColumn:@"name"];
    int age = [rs intForColumn:@"age"];
    double score = [rs doubleForColumn:@"score"];
}

 

模糊查詢

查詢語句中%%xxx%%表明包含xx字段,%x表明xx開頭字段,x%表明xx結尾字段

+(NSArray*)queryFuzzyContactInfo:(NSString *)item
{
    FMDatabase *database = [FMDatabase databaseWithPath:SQLITEPATH1];
    if (![database open]) {
        NSLog(@"數據庫打開失敗");
    }
    
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
    
    FMResultSet *resultSet = [database executeQuery:@"select * from mysql1 WHERE name like '%%%@%%'",item];
    while ([resultSet next])
    {
        NSString * name = [resultSet stringForColumn:@"name"];
    }
    return array;
}

6>多線程異步執行屢次數據操做

FMDatabase這個類是線程不安全的,若是在多個線程中同時使用一個FMDatabase實例,會形成數據混亂等問題
爲了保證線程安全,FMDB提供方便快捷的FMDatabaseQueue類

1)FMDatabaseQueue的建立

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];

2)簡單使用

[queue inDatabase:^(FMDatabase *db) {
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];
    
    FMResultSet *rs = [db executeQuery:@"select * from t_student"];
    while ([rs next]) {
        // …
    }
}];

3)使用事務

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
    [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];
    
    FMResultSet *rs = [db executeQuery:@"select * from t_student"];
    while ([rs next]) {
        // …
    }
}];
事務回滾
*rollback = YES;
相關文章
相關標籤/搜索