在學習SQLite之前,首先了解下數據持久化的幾種方式:
定義:數據持久化是通過文件將數據存儲在磁盤上
IOS下主要有四種數據持久化的方式:
1.屬性列表Plist(通過將數組和字典寫入一個文件進行存儲,自定義的對象不能使用屬性列表寫入文件)
2.偏好設置Preference(NSUserDefaults,也是只能存數組和字典等簡單數據)
2.對象歸檔(將自定義的對象寫入文件)
3.SQLite數據庫(純C語言,輕量級)
4.CoreData(基于SQLite,OC版本,重量級)
持久化方式的對比:
1.屬性列表,對象歸檔適合小數據量存儲和查詢操作(如果數據比較大,缺點:消耗內存,查詢性能不好)
2.SQLite,CoreData適合大數據量存儲和查詢操作
數據庫介紹
數據庫(Database)是按照數據結構來組織,存儲和管理數據的倉庫
數據庫管理系統是一種操縱和管理數據庫的大型軟件,用于建立,使用和維護數據庫,常見的關系數據庫管理系統有:
Oracl(甲骨文,一些大的企業級的軟件都用Orcal開發數據)
MSSQLServer(微軟的系統,用.Net開發的一個系統)
DB2(IBM開發的數據管理系統)
MySQL(一般是跟php組合使用,已被甲骨文收購)
數據庫可以分為兩大類:
1.關系型數據庫(主流)
2.對象型數據庫
SQLite介紹
SQLite是一種輕型的數據庫,是一種關系型數據庫管理系統,它的設計目的是嵌入式設備中使用(手機中)
SQLite占用資源很低,可能只需要哦幾百K的內存就夠了
SQLite的處理速度比Mysql,PostgreSQL這兩款著名的數據庫都快
SQLite占用資源非常低,非常適合移動設備中使用,而且是開源免費的
SQLite第一個版本誕生于2000年5月,現在已經更新到SQLite3版本
SQLite數據庫是通過建表來存儲數據的,表和表之間可以建立關系,所以叫關系型數據庫
基礎的SQL語句
SQL語句用于對數據進行存儲,查詢,更新等管理操作
1.創建表
CREATE TABLE Class99 (Stu_ID INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, gender TEXT NOT NULL DEFAULT M, age INTEGER NOT NULL)
2.插入一條數據
INSERT INTO Class99(Stu_ID,name,gender,age) VALUES(?,?,?,?)
3.更新一條數據
UPDATE Class99 SET gender = ? WHERE Stu_ID = ?
4.刪除一條數據
DELETE FROM Class99 WHERE Stu_ID = ?
5.查詢一條數據
SELECT * FROM Class99 WHERE Stu_ID = ?
數據庫操作流程
SQLite最新版本是3.0,使用前需要導入libsqlite3.0dylib
操作流程:
1.打開數據庫
2.編譯SQL語句
3.執行SQL語句,讀取數據
4.語句完結
5.關閉數據庫
SQL常用參數
1.sqlite3_open() //打開數據庫
2.sqlite3_close() //關閉數據庫
3.sqlite3_exec() //執行sql語句,例如創建表
4.sqlite3_prepare_v2() //編譯SQL語句
5.sqlite3_step() //執行sql語句
6.sqlite3_finaliza() //結束sql語句
7.sqlite3_bind_text() //綁定參數
8.sqlite3_column_text() //查詢字段上的數據
下面新建一個工程,使用以上SQLite的函數以及操作流程:
1.首先,給工程里面導入libsqlite3.tbd:
2.然后,使用storyboard,分別添加一下Button,關聯到ViewController里面:
3. 新建一個類,聲明這個類的屬性,這個相當于建表
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property(nonatomic,strong)NSString *name;
@property(nonatomic,strong)NSString *gender;
@property(nonatomic,assign)int age;
@property(nonatomic,assign)int Stu_ID;
-(instancetype)initWithName:(NSString *)name andAge:(int)age andGender:(NSString *)gender andStuID:(int)stu_ID;
@end
@implementation Student
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
-(NSString *)description{
return [NSString stringWithFormat:@"%@",_name];
}
//自定義初始化方法
-(instancetype)initWithName:(NSString *)name andAge:(int)age andGender:(NSString *)gender andStuID:(int)stu_ID{
if (self = [super init]) {
_name = name;
_age = age;
_gender = gender;
_Stu_ID = stu_ID;
}
return self;
}
@end
4.這里我們通過用單例來聲明方法,然后在控制器里調用這些方法
這里結合SQLite的基礎語句來聲明這些方法:
#import <Foundation/Foundation.h>
@class Student;
@interface DataBase : NSObject
//創建單例
+(instancetype)shareDatabase;
//打開數據庫
-(void)openDB;
//關閉數據庫
-(void)closeDB;
//添加
-(void)insertStudent:(Student *)stu;
//刪除
-(void)deleteStudent:(int)stu_ID;
//修改
-(void)updateStudentgender:(NSString *)gender andStuID:(int)stu_id;
//查詢所有
-(NSArray *)selectAllStudents;
//查詢單個
-(Student *)selectStudengWithID:(int)stu_id;
@end
****在.m里實現這些方法:***
首先在.m里導入數據庫,并且創建單例:
#import "DataBase.h"
#import <sqlite3.h>
#import "Student.h"
@implementation DataBase
static DataBase *dataBase = nil;
+(instancetype)shareDatabase{
//加鎖
@synchronized(self) {
if (nil == dataBase) {
dataBase = [[DataBase alloc] init];
//打開數據庫
[dataBase openDB];
}
}
return dataBase;
}
//創建數據庫對象
static sqlite3 *db = nil;
***打開數據庫和關閉數據庫:****
//打開數據庫
-(void)openDB{
//如果數據庫已經打開,則不需要執行后面的操作
if (db != nil) {
return;
}
//創建保存數據庫的路徑
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
documentPath = [documentPath stringByAppendingString:@"/LOClass.sqlite"];
NSLog(@"%@",documentPath);
//打開數據庫 (如果該數據庫存在,則直接打開,否則自動創建一個再打開)
int result = sqlite3_open([documentPath UTF8String], &db);
if (result == SQLITE_OK) {
NSLog(@"成功打開");
//建表
//準備sql語句
NSString *sql = @"CREATE TABLE Class43 (Stu_ID INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, gender TEXT NOT NULL DEFAULT M, age INTEGER NOT NULL);";
//執行sql語句
sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
}else{
NSLog(@"%d",result);
}
}
//關閉數據庫
-(void)closeDB{
int result = sqlite3_close(db);
if (result == SQLITE_OK) {
NSLog(@"關閉成功");
//關閉數據庫的時候,將db置為空,是因為打開數據庫的時候,我們需要使用nil來判斷
db = nil;
}else{
NSLog(@"關閉失敗:%d",result);
}
}
實現添加
//添加
-(void)insertStudent:(Student *)stu{
//1.打開數據庫
[self openDB];
//2.創建跟隨指針
sqlite3_stmt *stmt = nil;
//3.準備sqlite語句
NSString *sql = @"INSERT INTO CLASS43(Stu_ID,name,gender,age) VALUES(?,?,?,?)";
//4.驗證sql語句的正確性
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
//5. 執行
if (result == SQLITE_OK) {
NSLog(@"數據庫添加成功");
//一旦sql語句沒有問題,就要開始綁定數據,替換?
//(1)跟隨指針 (2)問號的順序(從1開始) (3)要綁定的值
sqlite3_bind_int(stmt, 1, stu.Stu_ID);
sqlite3_bind_text(stmt, 2, [stu.name UTF8String], -1, nil);
sqlite3_bind_text(stmt, 3, [stu.gender UTF8String], -1, nil);
sqlite3_bind_int(stmt, 4, stu.age);
//6單步執行q
sqlite3_step(stmt);
}else{
NSLog(@"數據庫添加失敗:%d",result);
}
//7 釋放跟隨指針占用的內存
sqlite3_finalize(stmt);
}
我們可以 通過打開數據庫里的方法中的路徑,去查詢數據:
在finder中前往文件夾,會找到后綴.sqlite的文檔,通過SQLiteManager(一種管理數據的工具)打開,可以看到代碼中的數據成功添加了:
刪除
//刪除
-(void)deleteStudent:(int)stu_ID{
//1.打開數據庫
[self openDB];
//2.創建跟隨指針
sqlite3_stmt *stmt = nil;
//3.準備sql語句
NSString *sql = @"DELETE FROM Class43 WHERE Stu_ID=?";
//4.驗證sql正確性
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
//5.
if (result == SQLITE_OK) {
NSLog(@"刪除成功");
//開始綁定
sqlite3_bind_int(stmt, 1, stu_ID);
//執行
sqlite3_step(stmt);
}else{
NSLog(@"刪除失敗%d",result);
}
//7.釋放內存
sqlite3_finalize(stmt);
}
修改
//修改
-(void)updateStudentgender:(NSString *)gender andStuID:(int)stu_id{
[self openDB];
sqlite3_stmt *stmt = nil;
NSString *sql = @"UPDATE Class43 SET gender = ? WHERE Stu_ID = ?";
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
NSLog(@"修改成功");
//綁定 (綁定的是問號) (1和2 代表問號)
sqlite3_bind_text(stmt, 1, [gender UTF8String], -1, NULL);
sqlite3_bind_int(stmt, 2, stu_id);
sqlite3_step(stmt);
}else{
NSLog(@"修改失敗");
}
sqlite3_finalize(stmt);
}
查找
-(NSArray *)selectAllStudents{
//1.打開數據庫
[self openDB];
//2.跟隨指針
sqlite3_stmt *stmt = nil;
//3.
NSString *sql = @"SELECT * FROM Class43";
//4.驗證
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
//創建可變數組,用來存放查詢到的學生
NSMutableArray *array = [NSMutableArray array];
while (sqlite3_step(stmt) == SQLITE_ROW) {
//根據sql語句,將搜索到的符合條件的值取出來
//0代表數據庫表的第一列
int stu_id = sqlite3_column_int(stmt, 0);
NSString *name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
NSString *gender = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 2)];
int age = sqlite3_column_int(stmt, 3);
//將取出來的信息賦值給學生模型
Student *stu = [[Student alloc] initWithName:name andAge:age andGender:gender andStuID:stu_id];
//將學生添加到可變數組里面
[array addObject:stu];
}
sqlite3_finalize(stmt);
return array;
}else{
NSLog(@"查詢失敗:%d",result);
}
sqlite3_finalize(stmt);
return nil;
}
-(Student *)selectStudengWithID:(int)stu_id{
//1.
[self openDB];
//2.
sqlite3_stmt *stmt = nil;
//3.
NSString *sql = @"SELECT * FROM Class43 WHERE Stu_ID= ?";
//4.
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
//5
if (result == SQLITE_OK) {
//綁定
sqlite3_bind_int(stmt, 1, stu_id);
//執行
Student *stu = [Student new];
while (sqlite3_step(stmt) == SQLITE_ROW) {
int stu_id = sqlite3_column_int(stmt, 0);
NSString *name = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 1)];
NSString *gender = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 2)];
int age = sqlite3_column_int(stmt, 3);
stu.Stu_ID = stu_id;
stu.name = name;
stu.age = age;
stu.gender = gender;
}
sqlite3_finalize(stmt);
return stu;
}else{
NSLog(@"查詢失敗%d",result);
}
sqlite3_finalize(stmt);
return nil;
}
5.在關聯的控制器里調用這些方法
- (void)viewDidLoad {
[super viewDidLoad];
DataBase *db = [DataBase shareDatabase];
// [db closeDB];
}
- (IBAction)inserBtn:(UIButton *)sender {
NSLog(@"添加");
Student *stu = [Student new];
stu.Stu_ID = 1;
stu.name = @"影魔";
stu.gender = @"sf";
stu.age = 100;
Student *stu1 = [[Student alloc] initWithName:@"大隊長" andAge:25 andGender:@"女" andStuID:2];
Student *stu2 = [[Student alloc] initWithName:@"愛君" andAge:18 andGender:@"女" andStuID:3];
Student *stu3 = [[Student alloc] initWithName:@"屠夫" andAge:99 andGender:@"男" andStuID:4];
DataBase *db = [DataBase shareDatabase];
[db insertStudent:stu];
[db insertStudent:stu1];
[db insertStudent:stu2];
[db insertStudent:stu3];
}
- (IBAction)deleteBtn:(UIButton *)sender {
NSLog(@"刪除");
DataBase *db = [DataBase shareDatabase];
[db deleteStudent:4];
}
- (IBAction)searchBtn:(UIButton *)sender {
NSLog(@"查詢所有");
DataBase *da = [DataBase shareDatabase];
NSArray *array = [da selectAllStudents];
NSLog(@"%@",array);
}
- (IBAction)oneSearchBtn:(UIButton *)sender {
NSLog(@"查詢單個");
DataBase *db = [DataBase shareDatabase];
Student *stu = [db selectStudengWithID:1];
NSLog(@"%@",stu);
}
- (IBAction)changeBtn:(UIButton *)sender {
NSLog(@"修改");
DataBase *db = [DataBase shareDatabase];
[db updateStudentgender:@"nv" andStuID:4];
}