- 為啥用數(shù)據庫
1:一款輕量級的嵌入式數(shù)據庫(用于移動端)
2:處理數(shù)據庫的速度比MySql還要快
3:SQLite不需要進行配置,這就意味著不需要安裝和管理
4:它是一個不需要單獨服務器進行操作的系統(tǒng)
5:SQLite是非常小的完全配置時小于400k,當省略一些可選文件時,小于250k
6:SQLite自給自足的,也就意味著不需要任何的外部依賴
- SQLite是如何存儲的
和excel很像,是以表(table)為單位進行存儲
** 數(shù)據庫的兩大類:**
- 關系型數(shù)據庫(主流):關系型數(shù)據庫是以行和列的形式存儲數(shù)據,這種形式被稱為表(二維表格),組成數(shù)據庫.
- 1.1:關系:可以理解為一張二維表,每一個關系都有一個關系名,也就是表名
- 1.2:屬性:可以理解為二維表中的一列,在數(shù)據庫中稱為字段
- 1.3:元組:可以理解為二維表中的一行,在數(shù)據庫中稱為記錄
- 1.4:域:屬性的取值范圍,也就是數(shù)據庫中,某一列的取值范圍
- 1.5:關鍵字:一組可以唯一標識元組的屬性,數(shù)據庫中稱為主鍵.可以由一個或者多個列組成
- 2:對象型數(shù)據庫:把面向對象的方法和數(shù)據庫技術結合起來,使得數(shù)據庫系統(tǒng)的分析,設計盡可能最大程度的和人的思想,以及對世界的認識保持一致
數(shù)據庫的存儲步驟
1:新建一張表(table)
2:添加多個字段(列,屬性,column)
3:增加多條記錄(record,row:用于存放多個字段的對應值)
**什么叫SQL**
1:SQL(Structured Query Language)結構化查詢語言
2:是一種關系型數(shù)據庫,對數(shù)據進行定義和操作(增刪改查)的語言
---------------------------------------------------------------------------------
**什么是SQL語句**
1:用SQL語言編寫的句子,代碼
2:在運行程序的過程中,要操作(增刪改查:CRUD)數(shù)據庫中的數(shù)據,必須使用SQL語句
SQL語句特點:不區(qū)分大小寫(eg:在數(shù)據庫中user和UsEr是一樣的)
注意:每條語句必須用分號結束,不能用關鍵字來命名表和字段
數(shù)據庫中常用的關鍵字:select,inset,update,delete,where......
SQL語句的種類:
- 數(shù)據定義語句(DDL: Data Definition Language):用來定義表的結構,包括create table(建表),drop table(刪表)...
- 數(shù)據操作語句(DML:Data Manipulate Language):用來修改表內容,包括insert,delete,update......
- 數(shù)據查詢語句(DQL:Data Query Language):用來查詢表內數(shù)據,關鍵字是select(也是DQL中和所有SQL中用的最多的操作)
這里我用的是創(chuàng)建單例類去調用的方法去實現(xiàn)數(shù)據的存儲
+ (instancetype)shareDBHandle{
if (dataBase == nil ) {
dataBase = [[DBHandle alloc]init];
}
return dataBase;
}
- (NSString *)path{
if (_path == nil) {
NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
//創(chuàng)建數(shù)據庫文件
_path = [document stringByAppendingString:@"/text.sqlite"];
}
return _path;
}
//創(chuàng)建一個數(shù)據庫指針,好多地方都會使用到數(shù)據庫,所以初始化一個數(shù)據庫靜態(tài)變量
static sqlite3 *db= nil;
//打開數(shù)據庫
- (void)openDB{
NSLog(@"%@",self.path);
/*
用int接收打開結果,這里使用BOOL值
sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
參數(shù)1:文件名即數(shù)據庫存儲的路徑
參數(shù)2:兩級指針即數(shù)據庫的地址"&"
*/
BOOL result = sqlite3_open(self.path.UTF8String, &db);
if (result ==SQLITE_OK) {
NSLog(@"數(shù)據庫打開成功");
}else{
NSLog(@"數(shù)據庫打開失敗");
}
}
//關閉數(shù)據庫
- (void)closeDB{
BOOL result = sqlite3_close(db);
if (result == SQLITE_OK) {
NSLog(@"數(shù)據庫關閉成功");
}else{
NSLog(@"數(shù)據庫關閉失敗");
}
}
//建表
- (void)SetCreat{
//1:準備SQL語句,創(chuàng)建一個stu表
NSString *sqlString = @"create table if not exists stu(s_id integer primary key autoincrement not null, s_name text, s_age integer)";
//執(zhí)行SQL語句
/*
sqlite3_exec(<#sqlite3 *#>, <#const char *sql#>, <#int (*callback)(void *, int, char **, char **)#>, <#void *#>, <#char **errmsg#>)
參數(shù)1:數(shù)據庫
參數(shù)2:將準備好的sql語句放置在此(轉換成C語言格式)
參數(shù)3:結果回調一個函數(shù)
參數(shù)4:回調一個函數(shù)
參數(shù)5:錯誤信息
*/
int result = sqlite3_exec(db, sqlString.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"建表成功");
}else{
NSLog(@"建表失敗");
}
}
//增(姓名,年齡)
- (void)insertWithName:(NSString *)name age:(NSInteger)age{
//1:準備sql語句,當values的值不確定時用?來代替,之后會對其進行綁定
NSString *sqlString = @"insert into stu(s_name,s_age)values(?,?)";
//2:創(chuàng)建伴隨指針(用于綁定參數(shù),獲取數(shù)據)
sqlite3_stmt *stmt = NULL;
//3:預執(zhí)行
/*
sqlite3_prepare(<#sqlite3 *db#>, <#const char *zSql#>, <#int nByte#>, <#sqlite3_stmt **ppStmt#>, <#const char **pzTail#>)
參數(shù)1:數(shù)據庫
參數(shù)2:sql語句(轉格式)
參數(shù)3:有正負之分(正:代表只往后讀一個字節(jié).負:遇到特殊符號才會結束(\000,u000))
參數(shù)4:伴隨指針的地址
參數(shù)5:表示取值時取不全,剩下的值全部存于此,一般給NULL
*/
int result = sqlite3_prepare(db, sqlString.UTF8String, -1, &stmt, NULL);
if (result == SQLITE_OK) {
//4:綁定參數(shù)
/*
sqlite3_bind_text(<#sqlite3_stmt *#>, <#int#>, <#const char *#>, <#int#>, <#void (*)(void *)#>)
參數(shù)1:伴隨指針--綁定參數(shù),獲取數(shù)據
參數(shù)2:[?的位置,從1開始]
參數(shù)3:表示你要插入的值(轉換格式---UTF8String)
參數(shù)4:有正負之分(正:代表只往后讀一個字節(jié).負:遇到特殊符號才會結束(\000,u000))
參數(shù)5:回調函數(shù)
*/
sqlite3_bind_text(stmt, 1, name.UTF8String, -1, nil);
sqlite3_bind_int64(stmt, 2, age);
//5:sql語句執(zhí)行完畢后,執(zhí)行伴隨指針,根據伴隨指針的情況判斷是否插入成功[SQLITE_DONE表示伴隨指針執(zhí)行數(shù)據成功]
if (sqlite3_step(stmt) == SQLITE_DONE) {
NSLog(@"插入成功");
}else {
NSLog( @"插入失敗");
}
}
else{
NSLog(@"語句失敗");
}
sqlite3_finalize(stmt);
}
//刪(SID)
- (void)deleteWithID:(NSInteger)SID{
//1:準備sql語句
NSString *sqlstring = [NSString stringWithFormat:@"delete from stu where s_id = %ld",SID];
//執(zhí)行sql語句
int result = sqlite3_exec(db, sqlstring.UTF8String, NULL, NULL, NULL);
//結果
if (result == SQLITE_OK) {
NSLog(@"刪除數(shù)據成功,%ld",SID);
}else{
NSLog(@"刪除失敗");
}
}
//更新(age)
- (void)upDataWithAge:(NSInteger)age{
//1:準備sql語句
NSString *sqlString = @"update stu set s_age = ? where s_age = 18";
//2:創(chuàng)建伴隨指針
sqlite3_stmt *stmt = NULL;
int result = sqlite3_prepare(db, sqlString.UTF8String, -1, &stmt, NULL);
if (result == SQLITE_OK) {
//3:參數(shù)綁定
sqlite3_bind_int64(stmt, 1, age);
//4:執(zhí)行判斷伴隨指針是否綁定成功
if (sqlite3_step(stmt) == SQLITE_DONE) {
NSLog(@"更新成功");
}else{
NSLog(@"更新失敗");
}
}
else{
NSLog(@"語句錯誤");
}
//5:釋放伴隨指針
sqlite3_finalize(stmt);
}
//查找(name)
- (void)selectWithName:(NSString *)name{
//準備sql語句
NSString *sqlString = @"select s_id,s_name,s_age from stu where s_name = ?";
//伴隨指針創(chuàng)建
sqlite3_stmt *stmt = nil;
//預執(zhí)行
int result = sqlite3_prepare(db, sqlString.UTF8String, -1, &stmt, NULL);
if (result == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);
while (sqlite3_step(stmt) == SQLITE_ROW) {
//從伴隨指針獲取數(shù)據(第0列)
int s_id = sqlite3_column_int(stmt, 0);
NSLog(@"s_id=====%d",s_id);
//從伴隨指針獲取數(shù)據(第1列)
NSString *s_name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
NSLog(@"s_name=====%@",s_name);
//從伴隨指針獲取數(shù)據(第2列)
int s_age = sqlite3_column_int(stmt, 2);
NSLog(@"s_age======%d",s_age);
}
}else{
NSLog(@"語句錯誤");
}
sqlite3_finalize(stmt);
}
//清空數(shù)據
- (void)clear;{
//準備sql語句
NSString *sqlstring = @"delete from stu";
//執(zhí)行
sqlite3_exec(db, sqlstring.UTF8String, nil, NULL, NULL);
}
//清除表
- (void)clearTable{
NSString *sql = @"drop table if exists stu";
BOOL result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"成功");
}
}