iOS數(shù)據(jù)庫簡單入門
什么是數(shù)據(jù)庫
言簡意賅:字面上的理解,保存數(shù)據(jù)的倉庫.
維基百科:可視為電子化的文件柜——存儲電子文件的處所立砸,用戶可以對文件中的數(shù)據(jù)運(yùn)行新增索赏、截取、更新、刪除等操作.
類似于EXCEL表格
常見數(shù)據(jù)庫
- Oracle
- DB2
- SQL Server
- Postgre SQL
- MySQL
相關(guān)術(shù)語
DBS(Database System):數(shù)據(jù)庫系統(tǒng)
- 數(shù)據(jù)庫 DB(Database)
- 數(shù)據(jù)庫管理系統(tǒng)DBMS(Database Management System)
- 應(yīng)用開發(fā)工具
- 管理員及用戶
SQL語言(Structured Query Language)結(jié)構(gòu)化查詢語言
DDL (Data Definition Language) 數(shù)據(jù)庫定義語言
數(shù)據(jù)定義語言DDL用來創(chuàng)建數(shù)據(jù)庫中的各種對象-----表介蛉、視圖、
索引溶褪、同義詞币旧、聚簇等如:
CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
| | | | |
表 視圖 索引 同義詞 簇
主要語句:
Create語句:可以創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)庫的一些對象。
Drop語句:可以刪除數(shù)據(jù)表猿妈、索引吹菱、觸發(fā)程序、條件約束以及數(shù)據(jù)表的權(quán)限等彭则。
Alter語句:修改數(shù)據(jù)表定義及屬性鳍刷。DML(Data Manipulation Language) 數(shù)據(jù)庫操作語言
數(shù)據(jù)操縱語言DML主要有三種形式:
- 插入:INSERT
- 更新:UPDATE
- 刪除:DELETE
DQL (Data Query Language)數(shù)據(jù)庫查詢語言
數(shù)據(jù)查詢語言DQL基本結(jié)構(gòu)是由SELECT子句,F(xiàn)ROM子句俯抖,WHERE
子句組成的查詢塊:
SELECT <字段名表>
FROM <表或視圖名>
WHERE <查詢條件>DCL (Data Control Language)數(shù)據(jù)庫控制語言
數(shù)據(jù)控制語言DCL用來授予或回收訪問數(shù)據(jù)庫的某種特權(quán),并控制
數(shù)據(jù)庫操縱事務(wù)發(fā)生的時間及效果,對數(shù)據(jù)庫實(shí)行監(jiān)視等艾猜。如:
- GRANT:授權(quán)宙橱。
- ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點(diǎn)。
回滾---ROLLBACK
回滾命令使數(shù)據(jù)庫狀態(tài)回到上次最后提交的狀態(tài)柬祠。其格式為:
SQL>ROLLBACK; - COMMIT [WORK]:提交北戏。
SQL語句
創(chuàng)建表
CREATE TABLE IF NOT EXISTS table_Name(ID PRIMARY KEY,);
sqlite3
SQLite是一個嵌入式的數(shù)據(jù)庫引擎,專門適用于資源有限的設(shè)備(手機(jī),pda等)適量數(shù)據(jù)存儲.即輕量級的數(shù)據(jù)庫,沒有服務(wù)器進(jìn)程.其使用的是原生的C函數(shù)庫.
特點(diǎn)
1.所有數(shù)據(jù)在表單中進(jìn)行管理,數(shù)據(jù)沒有順序
2.SQL語句不區(qū)分大小寫,字段,表單區(qū)分大小寫
3.表單必須有主鍵,主鍵唯一,主鍵不會歸零,只增不減
4.SQLite內(nèi)部只支持NULL,INTEGER,REAL(浮點(diǎn)數(shù)),TEXT(文本),BLOB(大二進(jìn)制對象),這5種類型,但實(shí)際上也完全可以接受VARCHAR(N),CHAR(N),DECIMAL(P,S)等數(shù)據(jù)類型,只不過SQLite會在運(yùn)算或保存時將他們轉(zhuǎn)換為上面5種數(shù)據(jù)類型中相應(yīng)的類型.
5.SQLite允許把各種類型的數(shù)據(jù)保存到任何類型字段只能中,開發(fā)者可以不用關(guān)心聲明該字段所使用的數(shù)據(jù)類型.例如:可以把字符串類型的值存入INTEGER類型的字段中,也可以把數(shù)值型的值存入布爾類型的字段中.但是定義為”INTEGER PRIMARY KEY”即主鍵,只能存儲64位整數(shù),存儲除整數(shù)以外的其它數(shù)據(jù)類型時,SQLite會產(chǎn)生錯誤.
sqlite3工具
Mac OS X ++自帶sqlite3工具,可以通過終端來執(zhí)行命令來檢查,管理數(shù)據(jù)庫.
得到數(shù)據(jù)庫路徑,在終端執(zhí)行 sqlite3 路徑來啟動SQLite數(shù)據(jù)庫
常用命令:
- .database:查看當(dāng)前數(shù)據(jù)庫
- .tables:查看當(dāng)前數(shù)據(jù)庫里的數(shù)據(jù)庫表
- .help查看sqlite3支持的命令
我們編寫代碼時可以用來測試SQL語句.
sqlite3API
sqlite3使用
添加library---libsqlite3.tbd,導(dǎo)入頭文件#import "sqlite3.h"
sqlite3的創(chuàng)建
步驟如下:
- 根據(jù)路徑,調(diào)用函數(shù)sqlite3_open()打開數(shù)據(jù)庫
- 使用sqlite3_exec函數(shù)執(zhí)行Create Table語句
- 使用sqlite3_close函數(shù)釋放資源
聲明一個sqlite3 *db變量,獲取沙盒創(chuàng)建資源路徑,一般放在沙盒路徑下的Documents文件夾下.橋接成C語言的字符串,調(diào)用sqlite3_open()打開數(shù)據(jù)庫
@interface SQLManage : NSObject{
sqlite3 *db;
}
//獲取路徑
static const char *sqliteResoursePath(){
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [[paths firstObject]stringByAppendingPathComponent:@"xxxx.sqlite"];
return documentDirectory.UTF8String;
}
//打開數(shù)據(jù)庫
//參數(shù)一:數(shù)據(jù)庫文件所在的完整路徑, const char *
//參數(shù)二:數(shù)據(jù)庫句柄 地址 &&sqlite3
int status = sqlite3_open(sqliteResoursePath()?:”:memory:", &db);
if (status != SQLITE_OK) {
//SQLITE_OK 代表打開成功
sqlite3_close(db);
NSAssert(NO, @"數(shù)據(jù)庫打開失敗~");
}
建表
CREATE TABLE [IF NOT EXISTS] 表名(字段名稱 字段類型 [完整性約束條件],完整性約束條件], .....)ENGINE=存儲引擎 CHARSET=編碼方式;
char *sql = "create table if not exists Student(id integer primary key autoincrement,name varchar(10),age integer,score float default 0.0,sex text,desc text)”;
關(guān)于完整性約束條件
約束條件 | 含義 |
---|---|
UNSIGNED | 無符號,沒有負(fù)數(shù),從0開始 |
ZEROFILL | 零填充,當(dāng)數(shù)據(jù)的顯示長度不夠的時候,可以使用前補(bǔ)0的效果填充至指定長度,字段會自動添加UNSIGNED |
NOT NULL | 非空約束,也就是插入值的時候,這個字段必須要給值,值不能為空 |
DEFAULT | 默認(rèn)值.如果插入記錄的時候沒有給字段賦值,則使用默認(rèn)值 |
PRIMARY KEY | 主鍵,標(biāo)識記錄的唯一性,值不能重復(fù),一個表只能有一個主鍵,自動禁止為空 |
AUTO_INCREMENT | 自動增長,只能用于數(shù)值列,而且配合索引使用,默認(rèn)起始值從1開始,每次增長1 |
UNIQUE KEY | 唯一性,一個表中可以有多個字段是唯一索引,同樣的值不能重復(fù),但是NULL值除外 |
FOREIGN KEY | 外鍵約束 |
char *error;
//數(shù)據(jù)庫語句
char *sql = "create table if not exists user(id integer primary key autoincrement,name text,desc text)";
//執(zhí)行SQL語句
//參數(shù)一: 數(shù)據(jù)庫對象
//參數(shù)二: 數(shù)據(jù)庫語句
//參數(shù)三: 回調(diào)函數(shù)
//參數(shù)四: 回調(diào)函數(shù)的引用(傳遞參數(shù))
//參數(shù)五: 錯誤信息
int execStatus = sqlite3_exec(db, sql, NULL, NULL, &error);
if (execStatus != SQLITE_OK) {
NSLog(@"execSql failed:%s",error);
NSAssert(NO, @"create table falied”);
}else{
NSLog(@"exec sql success!");
}
//關(guān)閉數(shù)據(jù)庫
sqlite3_close(db);
添加數(shù)據(jù)
- sqlite3_open()打開數(shù)據(jù)庫
- 使用sqlite3_prepare_v2函數(shù)預(yù)處理SQL語句
- 使用sqlite3_bind_text|int..(類型)函數(shù)綁定參數(shù)
- 使用sqlite3_step函數(shù)執(zhí)行SQL語句,遍歷結(jié)果集合.
- (void)insert:(NSString *)name desc:(NSString *)desc{
char *insertSQL = "insert into user values(null,?,?)";
sqlite3_stmt *stmt;
int result = sqlite3_prepare_v2(db, insertSQL, -1, &stmt, NULL);
//預(yù)編譯成功
if (result == SQLITE_OK) {
//為第一個?綁定參數(shù)
sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);
//為第二個?綁定參數(shù)
sqlite3_bind_text(stmt, 2, desc.UTF8String, -1, NULL);
//執(zhí)行SQL語句
result = sqlite3_step(stmt);
if (result == SQLITE_DONE) {
NSLog(@"插入成功~");
}
sqlite3_finalize(stmt);
}
//關(guān)閉數(shù)據(jù)庫
sqlite3_close(db);
}
刪除表
drop table 表名
- (void)dropTable{
char *drop = "drop table user";
char *error;
int result = sqlite3_exec(db, drop, NULL, NULL, &error);
if (result != SQLITE_OK) {
if (error) {
NSLog(@"drop table failed,error:%s",error);
}
}else{
NSLog(@"drop table success!");
}
}
刪除記錄
delete from 表名 where ID = 2;
delete from 表名; ——表單內(nèi)容全部刪除(表單還在)
模糊刪除
delete from 表名 where name like '%楓%';
delete from 表名 where name = ‘小明’;
delete from 表名 where name = ‘小明’ and age = ’20’;
delete from 表名 where name = ‘小明’ and ID > 5;
更新記錄
update 表名 set name = ‘小明’ where ID = 1;
update 表名 set name = ‘小明’, age = ’20’ where ID = 1;
使用sqlite進(jìn)行數(shù)據(jù)查找操作
select:
select * from 表名; 查詢所有數(shù)據(jù)
select name from 表名;
select name, age from 表名;
where:
select * from 表名 where name like '%舒%';
select * from 表名 where name like '%舒%' and ID == 1;
select * from 表名 where name like '%舒%' and ID < 2;
select:
select count(*) from 表名
select sum(ID) from 表名
select avg(ID) from 表名
運(yùn)算符
= 或 == 或 like 等于
大于
< 小于
= 大于等于
<= 小于等于
<> 不等于
!> 不大于
!< 不小于
%小明% 包含子字符串”小明” 只用于like
- sqlite3_open()打開數(shù)據(jù)庫
- 使用sqlite3_prepare_v2函數(shù)預(yù)處理SQL語句
- 使用sqlite3_bind_text|int..(類型)函數(shù)綁定參數(shù)
- 使用sqlite3_step函數(shù)執(zhí)行SQL語句,遍歷結(jié)果集合.
- 使用sqlite3_column_text|int..(類型)等函數(shù)提取字段數(shù)據(jù)
//查詢
- (void)queryKey:(NSString *)key{
//sqlite3_exec()一般執(zhí)行無須返回值的語句 DDL DML
//如果需要執(zhí)行查詢語句,則先調(diào)用sqlite3_prepare_v2預(yù)處理查詢語句,然后循環(huán)調(diào)用sqlite3_step()取出查詢結(jié)果集.
char *querySQL = "SELECT * FROM user where name like ?";
sqlite3_stmt *statement;
//v2代表新版本
//預(yù)編譯SQL語句,sqlite3_stmt保存了預(yù)編譯結(jié)果的引用
int result = sqlite3_prepare_v2(db, querySQL, -1, &statement, nil);
//預(yù)編譯成功
if (result == SQLITE_OK) {
//%代表通配符
NSString *keys = [NSString stringWithFormat:@"%%%@%%",key];
sqlite3_bind_text(statement, 1, keys.UTF8String, -1, NULL);
while (sqlite3_step(statement) == SQLITE_ROW) {
int idKey = sqlite3_column_int(statement, 0);
const unsigned char *name = sqlite3_column_text(statement, 1);
const unsigned char *desc = sqlite3_column_text(statement, 2);
NSLog(@"%d,%s,%s",idKey,name,desc);
}
}
}
FMDB的使用
單例類
#import "DBManage.h"
#import "FMDatabase.h"
#import "FMResultSet.h"
@implementation DBManage{
FMDatabase *_dataBase;
}
+ (id)defaultDBManager{
static DBManage *manager = nil;
if (manager == nil) {
manager = [[DBManage alloc]init];
}
return manager;
}
/*
對于Model而言,重寫init方法目的在于瓶盛,創(chuàng)建容器最欠,創(chuàng)建對應(yīng)的對象,調(diào)用成員方法之前的準(zhǔn)備的工作
對于View而言惩猫,重寫init方法目的在于 添加控件芝硬,達(dá)到自定制頁面的目的
*/
- (id)init{
if (self = [super init]) {
[self createDB];
}
return self;
}
建表
- (void)createDB{
NSString *dbPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/DB"];
NSLog(@"%@",dbPath);
if (_dataBase == nil) {
_dataBase = [FMDatabase databaseWithPath:dbPath];
}
//操作數(shù)據(jù)庫之前,一定要打開數(shù)據(jù)庫轧房,要不然所有的操作都無法執(zhí)行
[_dataBase open];
[self createTable];
}
- (void)createTable{
NSString *sql = @"create table if not exists Contact(ID integer primary key autoincrement,name varchar(128),remark text,tel text,email varchar(200),head text);";
[_dataBase executeUpdate:sql];
}
添加數(shù)據(jù)
- (void)addUser:(ContactModel *)user{
NSString *sql = @"insert into Contact(name,head,email,tel,remark) values(?,?,?,?,?);";
[_dataBase executeUpdate:sql,user.name,user.head,user.email,user.tel,user.remark];
}
刪除數(shù)據(jù)
- (void)deleteUser:(ContactModel *)user{
//根據(jù)電話號碼刪除記錄
NSString *sql =@"delete from Contact where tel=?;";
[_dataBase executeUpdate:sql,user.tel];
}
更新數(shù)據(jù)
- (void)updateUser:(ContactModel *)user toUser:(ContactModel *)newUser{
//1.找到對應(yīng)的用戶拌阴;
NSString *sql = @"select ID from Contact where tel = ?;";
FMResultSet *resultSet = [_dataBase executeQuery:sql,user.tel];
NSString *ID = nil;
if (resultSet.next) {
ID =[resultSet stringForColumn:@"ID"];
}
//2.修改
if (ID) {
NSString *sql =@"update Contact set tel=?,name=?,email=?,head=?,remark=? where ID = ?;";
[_dataBase executeUpdate:sql,newUser.tel,newUser.name,newUser.email,newUser.head,newUser.remark,ID];
}
}
獲取所有數(shù)據(jù)
- (NSArray *)searchAllUsers{
NSMutableArray *array = [NSMutableArray array];
NSString *sql = @"select * from Contact;";
FMResultSet *set = [_dataBase executeQuery:sql];
while (set.next) {
ContactModel *user = [[ContactModel alloc]init];
user.name = [set stringForColumn:@"name"];
user.tel = [set stringForColumn:@"tel"];
user.email = [set stringForColumn:@"email"];
user.head = [set stringForColumn:@"head"];
user.remark = [set stringForColumn:@"remark"];
[array addObject:user];
}
return array;
}