常用關(guān)鍵字:
select串绩、insert缺虐、update、delete礁凡、from高氮、create慧妄、where、desc剪芍、order腰涧、by、group紊浩、table窖铡、alter、view坊谁、index等费彼;數(shù)據(jù)庫中不可以使用關(guān)鍵字來命名表、字段口芍。
SQLite數(shù)據(jù)庫存儲的數(shù)據(jù)形式:
- NULL:表示該值為NULL值
- INTEGER:無符號整型值
- REAL:浮點值
- TEXT:文本字符串
- BLOB:二進(jìn)制數(shù)據(jù)(比如文件)
注意:實際上SQLite是無類型的箍铲,就算聲明為integer類型,還是能存儲字符串文本鬓椭,聲明類型是為了方便程序員之間的交流颠猴。
- DDL(Data Definition Language)數(shù)據(jù)定義語言
語句包括動詞CREATE(創(chuàng)建表)、DROP(刪除表) - DML(Data Manipulation Language)數(shù)據(jù)操作語言
語句包括INSERT(插入行)小染、UPDATE(修改行)翘瓮、DELETE(刪除行) - DQL(Data Query Language)數(shù)據(jù)查詢語句
語句包括SELECT,查詢數(shù)據(jù)
DDL語句
- 創(chuàng)建表:
CREATE TABLE 表明(字段名1 字段類型1裤翩,字段名2 字段類型2资盅,…);
CREATE TABLE if not exists 表明(字段名1 字段類型1踊赠,字段名2 字段類型2呵扛,…);
示例:
create table t_person(id integer, name text, age integer);
create table if not exists t_person(id integer, name text, age integer);
- 刪表:
drop table 表名筐带;
示例:
drop table t_person;
- 簡單約束:
建表的時候可以給特定的字段設(shè)置一些約束條件
1.用 not null 指定字段的值不能為null
2.用 unique 指定字段的值必須唯一
3.用 default 指定字段的默認(rèn)值
示例:
CREATE TABLE t_student(id integer, name text NOT NULL UNIQUE, age integer NOT NULL DEFAULT 1);
以上語句約束表示:
1.name字段不能為NULL今穿,并且唯一
2.age字段不能為NULL,并且默認(rèn)為1
DML語句
- 插入數(shù)據(jù)(insert)
insert into 表名(字段1伦籍,字段2蓝晒,…)values(字段1的值,字段2的值鸽斟,...);
eg:
insert into t_person(name, age) values(“jack”, 10);
注意:數(shù)據(jù)庫中的字符串內(nèi)容應(yīng)該用引號括住
- 更新數(shù)據(jù)(update)
update 表名 set 字段1=字段1的值拔创,字段2=字段2的值,…富蓄;
eg:
update t_person set name = ‘jack’, age = 20;
這條語句會將t_person表中所有記錄的name都改為jack剩燥,age都改為20
- 刪除數(shù)據(jù)(delete)
delete from 表名;
eg:
delete from t_person;
這條語句會將t_person 表中所有記錄都刪掉
引入:通過上面例子發(fā)現(xiàn),以上語句會更新\刪除表中所有記錄灭红,如果我們只想更新或刪除某些固定的記錄侣滩,那就必須在DML語句后加上一些條件,即條件語句变擒。
- 條件語句
格式:
1.where 字段=某個值 and 字段 > 某個值君珠;// and相當(dāng)于&&
2.where 字段=某個值 or 字段=某個值;// or相當(dāng)于 ||
舉例:
//1.將年齡大于10且姓名不等于jack的記錄年齡改為5:
update t_person set age = 5 where age > 10 and name != ‘jack’;
//2.刪除年齡小于等于10或者年齡大于30的記錄:
delete from t_person where age <= 10 or age >30;
DQL語句
即查詢語句娇斑,格式如下:
- 查詢格式:
select 字段1策添,字段2,...from 表名毫缆;
select name唯竹,age from t_person; - 如果想查詢所有的字段可以用:
select * from 表名;
select * from t_person; - 也可以添加條件語句
select * from t_person where age > 20; - 計算記錄的數(shù)量可以用count(字段) 或者 count()
select count() from t_person;
select count(age) from t_person where height < 1.80;
查詢排序
- 語法
select * from t_person order by 字段苦丁; - 示例
select * from t_person order by age desc; // 降序
select * from t_person order by age asc; // 升序(默認(rèn)浸颓,asc可不寫)
限制查詢數(shù)量
- 語法:select * from 表名 limit 數(shù)值1,數(shù)值2旺拉;
- 示例:select * from t_person limit 4, 8; // 跳過最前面4條語句产上,然后取8條記錄。
limit語句可以被用于強制SELECT語句返回指定的記錄數(shù)蛾狗,LIMIT接收一個或兩個數(shù)字參數(shù)晋涣,參數(shù)必須是一個整數(shù)常量,如果給定兩個參數(shù)淘太,第一個參數(shù)指定第一個返回記錄行的偏移量姻僧,第二個參數(shù)指定返回記錄行的最大數(shù)目,初始記錄行的偏移量是0而不是1蒲牧。
主鍵約束(pk)
當(dāng)t_person有些記錄的name屬性和age屬性都一樣時,那么就無法區(qū)分這些數(shù)據(jù)赌莺,造成數(shù)據(jù)庫的記錄不唯一冰抢,不方便管理數(shù)據(jù);為了保證每條記錄的唯一性艘狭,增加了主鍵約束挎扰;主鍵是用來唯一地標(biāo)識某一條記錄的,可以是一個字段或多個字段巢音,比如t_person可以增加一個id字段作為主鍵遵倦,相當(dāng)于身份證號,主鍵必須具有唯一性官撼。
主鍵設(shè)計原則:
- 主鍵應(yīng)當(dāng)是對用戶沒有意義的
- 永遠(yuǎn)不要更新主鍵
- 主鍵不應(yīng)該包含動態(tài)變化的數(shù)據(jù)
- 主鍵應(yīng)當(dāng)由計算機自動生成
在創(chuàng)建表的時候用 primary key 聲明一個主鍵梧躺,只要聲明為 primary key,就說明是一個主鍵字段,主鍵字段默認(rèn)包含了 not null 和 unique 兩個約束掠哥。
eg:
CREATE TABLE t_student (id integer PRIMARY KEY, name text, age integer);
如果想讓主鍵自動增長(integer)巩踏,應(yīng)該增加AUTOINCREMENT
eg:
CREATE TABLE t_student (id integer PRIMARY KEY AUTOINCREMENT, name text, age integer);
外鍵約束(FK)
外鍵約束可以用來建立表與表之間的聯(lián)系(例如每個班級都有不同的老師,老師群體又有自己的數(shù)據(jù)庫续搀,所以要建立班級表與老師表之間的聯(lián)系)
- 新建一個外鍵:
CREATE TABLE class (class_id integer PRIMARY KEY AUTOINCREMENT, teacher_id integer REFERENCES teacher(id));
- JOIN和ON用來建立兩個表之間的關(guān)聯(lián)關(guān)系:
SELECT s.name, s.age FROM t_movie s JOIN t_director b ON s.dir_id = b.id WHERE s.name = ‘Matrix'塞琼;
數(shù)據(jù)庫操作流程:
(3.0版本SQLite,使用前需要導(dǎo)入libsqlite3.0.dylib)
- 打開數(shù)據(jù)庫
- 編譯SQL語句
- 執(zhí)行SQL語句
- 語句完結(jié)
- 關(guān)閉數(shù)據(jù)庫
SQLite3.0使用的是C的函數(shù)接口禁舷,常用函數(shù)有:
sqlite3_open() //打開數(shù)據(jù)庫
sqlite3_close() //關(guān)閉數(shù)據(jù)庫
sqlite3_exec() //執(zhí)行SQL語句彪杉,例如創(chuàng)建表
sqlite3_prepare_v2() //編譯SQL語句
sqlite3_step() //執(zhí)行查詢SQL語句
sqlite3_finalize() //結(jié)束SQL語句
sqlite3_bind_text() //綁定參數(shù)
sqlite3_column_text() //查詢字段上的數(shù)據(jù)
簡單使用數(shù)據(jù)庫示例代碼:
#import "ViewController.h"
#import <sqlite3.h>
@interface ViewController ()
@end
sqlite3 *_sql;
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
/*
0. 導(dǎo)入依賴庫并導(dǎo)入<sqlite3.h>頭文件
1. 需要一個數(shù)據(jù)庫文件
2. 在數(shù)據(jù)庫文件中創(chuàng)建一個表格
3. 向表格中插入數(shù)據(jù)
4. 關(guān)閉數(shù)據(jù)庫
*/
#pragma mark - 1.打開數(shù)據(jù)庫/創(chuàng)建數(shù)據(jù)庫文件并打開數(shù)據(jù)庫
NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/mySql.db"];
NSLog(@"%@",filePath);
//sqlite3_open 打開數(shù)據(jù)庫 但是如果路徑下沒有數(shù)據(jù)庫文件的話會先創(chuàng)建一個數(shù)據(jù)庫文件,再執(zhí)行打開的操作
int isOpen = sqlite3_open([filePath UTF8String], &_sql);
NSLog(@"%d",isOpen);
if (isOpen == SQLITE_OK) {
NSLog(@"打開數(shù)據(jù)庫成功");
}else {
return;
}
#pragma mark - 2.創(chuàng)建表格
NSString *createSQL = @" create table t_class (id integer primary key autoincrement, className text, teacher text); ";
char *error = nil;
/*
1. 打開的一個數(shù)據(jù)庫對象
2. 需要執(zhí)行的sql語句
*/
int isOK = sqlite3_exec(_sql, [createSQL UTF8String], NULL, NULL, &error);
if (isOK == SQLITE_OK) {
NSLog(@"創(chuàng)建表格成功");
}
#pragma mark - 3.添加數(shù)據(jù)
NSString *insertSQL = @" insert into t_class (className,teacher) values (\"class01\",\"tank\"); ";
int insertOK = sqlite3_exec(_sql, [insertSQL UTF8String], NULL, NULL, &error);
if (insertOK == SQLITE_OK) {
NSLog(@"添加數(shù)據(jù)成功");
}
#pragma mark - 4.數(shù)據(jù)查詢
NSString *selectSQL = @"select * from t_class where id = ?; ";
// SQL語句的句柄
sqlite3_stmt *stmt = nil;
/* 替代SQL語句
1. 向句柄中插入數(shù)據(jù)(需要在SQL語句中設(shè)置占位符牵咙,占位符在句柄中的位置從1開始)
2. 從句柄中獲取數(shù)據(jù)(當(dāng)數(shù)據(jù)查詢時使用派近,查詢后獲取的字段信息在句柄中的位置從0開始)
*/
/*
參數(shù)3:查詢數(shù)據(jù)的字節(jié)限制 設(shè)置為-1 則不對查詢結(jié)果做任何的設(shè)置
參數(shù)4:一個SQL語句的句柄 用來作為查詢結(jié)果的存放集合
*/
//sqlite3_prepare_v2 編譯SQL語句,判斷SQL語句是否合法霜大,并將SQL語句和句柄相互綁定
int prepare = sqlite3_prepare_v2(_sql, [selectSQL UTF8String], -1, &stmt, NULL);
if (prepare == SQLITE_OK) {
NSLog(@"語句合法");
sqlite3_bind_int(stmt, 1, 1);
// 執(zhí)行句柄 開始查詢語句
int step = sqlite3_step(stmt);
_models = [[NSMutableArrayalloc] init];
while (step == SQLITE_ROW) {
// 說明還有一條數(shù)據(jù)待查詢
int c_id = sqlite3_column_int(stmt, 0);
constunsignedchar *className = sqlite3_column_text(stmt, 1);
constunsignedchar *teacher = sqlite3_column_text(stmt, 2);
ClassModel *model = [[ClassModelalloc] init];
model.c_id = c_id;
model.className = [NSStringstringWithUTF8String:className];
model.teacher = [NSStringstringWithUTF8String:teacher];
[_modelsaddObject:model];
}
}
NSLog(@"%@",_models);
#pragma mark - 5.關(guān)閉數(shù)據(jù)庫
sqlite3_close_v2(_sql);
}
FMDB的使用
FMDB是iOS平臺的SQLite數(shù)據(jù)庫框架构哺,以O(shè)C的方式封裝了SQLite的C語言API。
FMDB使用起來更加面向?qū)ο笳嚼ぃ∪チ讼鄬θ哂嗟腃語言代碼曙强;而相對于蘋果自帶的Core Data框架,F(xiàn)MDB更加輕量級途茫;FMDB還提供了多線程安全的數(shù)據(jù)庫操作方法碟嘴,有效地防止數(shù)據(jù)混亂。
FMDB主要有三個類:
1.FMDatabase:一個FMDatabase對象就代表一個單獨的SQLite數(shù)據(jù)庫囊卜,執(zhí)行SQL語句娜扇。
2.FMResultSet:使用FMDatabase執(zhí)行查詢后的結(jié)果集栅组。
3.FMDatabaseQueue:用于在多線程中執(zhí)行多個查詢或更新(它是線程安全的)
FMDB簡單使用代碼示例:
/*
1. 創(chuàng)建一個數(shù)據(jù)庫文件
2. 創(chuàng)建表格
*/
NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/sql.db"];
FMDatabase *db = [FMDatabasedatabaseWithPath:filePath];
NSLog(@"%@",filePath);
BOOL isOpen = [db open];// 打開數(shù)據(jù)庫文件如果沒有數(shù)據(jù)庫則創(chuàng)建之后再打開
if (!isOpen) {
NSLog(@"打開失敗");
return;
}
// 創(chuàng)建表格
NSString *createSQL = @" CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL); ";
BOOL createSuc = [db executeUpdate:createSQL];
if (createSuc) {
NSLog(@"創(chuàng)建表格成功");
}
// 添加數(shù)據(jù)
for (int i = 10; i < 20; i ++) {
NSString *name = [NSStringstringWithFormat:@"tank%d號",i+1];
BOOL insertSuc = [db executeUpdateWithFormat:@"insert into t_student(name, age) values (%@,%d)",name,20];
if (insertSuc) {
NSLog(@"添加數(shù)據(jù)成功");
}
}
// 刪除數(shù)據(jù)
BOOL deleteSuc = [db executeUpdate:@" delete from t_student where id > 10; "];
if (deleteSuc) {
NSLog(@"刪除數(shù)據(jù)成功");
}
// 刷新數(shù)據(jù)
BOOL updataSuc = [db executeUpdate:@" update t_student set name = \"carol\" where id < 10; "];
if (updataSuc) {
NSLog(@"刷新數(shù)據(jù)成功");
}
// 數(shù)據(jù)查詢
FMResultSet *set = [db executeQuery:@" select * from t_student; "];
// 循環(huán)遍歷所有的查詢結(jié)果
while ([set next]) {
NSString *name = [set stringForColumn:@"name"];
int age = [set intForColumn:@"age"];
NSLog(@"%@ %d",name, age);
}
//關(guān)閉數(shù)據(jù)庫
[db close];