一、SQLite 簡介
SQL 是指結(jié)構(gòu)化查詢語言。使我們有能力訪問數(shù)據(jù)庫,SQL的功能有:面向數(shù)據(jù)庫執(zhí)行查詢,取出數(shù)據(jù)庫中數(shù)據(jù),插入數(shù)據(jù),查詢數(shù)據(jù),更新數(shù)據(jù),刪除數(shù)據(jù),創(chuàng)建新數(shù)據(jù)庫,創(chuàng)建新表等。
二、SQLite 使用
0、準(zhǔn)備
如果你要使用SQLite數(shù)據(jù)庫,必須導(dǎo)入系統(tǒng)的libsqlite3.0.tbd文件
1、創(chuàng)建數(shù)據(jù)庫
在使用數(shù)據(jù)庫之前你必須在本地有一個數(shù)據(jù)庫,可以通過NSSearchPathForDirectoriesInDomains()函數(shù)來創(chuàng)建一個文件,為了方便查看數(shù)據(jù)庫中的數(shù)據(jù)一般以.sqlite為文件后綴。
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"Student.sqlite"];
2、打開數(shù)據(jù)庫
首先在自定義類中創(chuàng)建一個sqlite3類型的變量。然后調(diào)用sqlite3_open()函數(shù)就可以打開數(shù)據(jù)庫了。
- (void)openDB {
// 如果數(shù)據(jù)庫已經(jīng)打開,沒有必要再打開一次.
if (db) {
NSLog(@"數(shù)據(jù)庫已經(jīng)打開");
return;
}
// 創(chuàng)建數(shù)據(jù)庫文件的路徑
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"Student.sqlite"];
NSLog(@"%@",filePath);
// 參數(shù)1是C字符串,參數(shù)2是**,所傳入的參數(shù)是地址
int result = sqlite3_open(filePath.UTF8String, &db);
// 根據(jù)函數(shù)返回值,判斷執(zhí)行是否正確
if (result == SQLITE_OK) {
NSLog(@"數(shù)據(jù)庫打開成功!");
} else {
NSLog(@"數(shù)據(jù)庫打開失敗,錯誤碼:%d", result);
}
}
3、創(chuàng)建表格
在對數(shù)據(jù)進(jìn)行增刪改查之前,你要有一個表格來存放數(shù)據(jù),就如同書架對書進(jìn)行分類、整理一樣,數(shù)據(jù)在數(shù)據(jù)庫中也不能隨意放置,表格可以使數(shù)據(jù)更加的有序。
注意:對數(shù)據(jù)進(jìn)行增刪改查操作,一般會用到兩個函數(shù):sqlite3_exec()和sqlite3_prepare_v2()。
(1) sqlite3_exec()函數(shù)一般用于你對數(shù)據(jù)庫進(jìn)行操作,而數(shù)據(jù)庫只向你回饋你的操作是否成功,不返回?cái)?shù)據(jù)庫中的數(shù)據(jù)信息時。表格的創(chuàng)建就是如此,因?yàn)槲覀冎魂P(guān)心表格是否創(chuàng)建成功,而不需要知道表格中到底有什么。
(2) sqlite3_prepare_v2()函數(shù)用于你需要數(shù)據(jù)庫對你反饋數(shù)據(jù)時,如查詢數(shù)據(jù),因?yàn)槲覀儽仨毜玫綌?shù)據(jù)查詢的結(jié)果,而不只是它是否成功的查詢。
創(chuàng)建表格的sql語句:CREATE TABLE IF NOT EXISTS xxxTABLE (ID_S INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, sex TEXT, age INTEGER).
a. CREATE TABLE 是創(chuàng)建表格的關(guān)鍵詞,
b. IF NOT EXISTS 是告訴系統(tǒng)當(dāng)這個表格不存在是創(chuàng)建,這個詞可以不寫。
c. xxxTABLE 是你給創(chuàng)建的表起的名字。
d. 括號內(nèi)是你表格內(nèi)的每一個元素,用逗號鏈接。
- (void)createTable {
NSString *sql = @"CREATE TABLE IF NOT EXISTS dls160101 (ID_S INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, sex TEXT, age INTEGER)";
int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
if (result == SQLITE_OK) {
NSLog(@"插入表格成功!");
} else {
NSLog(@"插入表格失敗,錯誤碼:%d", result);
}
}
4、插入數(shù)據(jù)
有了表格后,就可以在表格中添加數(shù)據(jù)了,添加數(shù)據(jù)和創(chuàng)建表格除了sql語句不同外,其它都一樣,我們只關(guān)心數(shù)據(jù)是否添加進(jìn)去。
- (void)insertModel:(ModelOfStudent *)stu
{
// 插入數(shù)據(jù)的SQL語句
NSString *sql = [NSString stringWithFormat:@"INSERT INTO dls160101 (name, sex, age) VALUES ('%@', '%@', '%ld')", stu.name, stu.sex, stu.age];
int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
if (result == SQLITE_OK) {
NSLog(@"插入數(shù)據(jù)成功");
} else {
NSLog(@"插入數(shù)據(jù)失敗,錯誤碼:%d", result);
}
}
5、更新數(shù)據(jù)
更新數(shù)據(jù)是在原有數(shù)據(jù)基礎(chǔ)上對數(shù)據(jù)改動,其結(jié)果是在原來的位置上修改了原來的數(shù)據(jù),因此代碼與之前沒什么不同
- (void)updateModel:(ModelOfStudent *)stu id:(NSInteger)ID
{
// 更新數(shù)據(jù) SQL語句
NSString *sql = [NSString stringWithFormat:@"UPDATE dls160101 SET name = '%@', sex = '%@', age = '%ld' WHERE ID_S = '%ld'", stu.name, stu.sex, stu.age, ID];
int reslut = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
if (reslut == SQLITE_OK) {
NSLog(@"更新數(shù)據(jù)成功");
} else {
NSLog(@"更新數(shù)據(jù)失敗,錯誤碼:%d", reslut);
}
}
6、刪除數(shù)據(jù)
刪除數(shù)據(jù)我們也只關(guān)心數(shù)據(jù)是否刪除成功,與之前也沒什么不同
- (void)deleteModelWithId:(NSInteger)ID
{
// 刪除數(shù)據(jù)
NSString *sql = [NSString stringWithFormat:@"DELETE FROM dls160101 WHERE ID_S = '%ld'", ID];
int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
if (result == SQLITE_OK) {
NSLog(@"刪除數(shù)據(jù)成功");
} else {
NSLog(@"刪除數(shù)據(jù)失敗,錯誤碼:%d", result);
}
}
7、檢索數(shù)據(jù)
/** 檢索數(shù)據(jù) API: sqlite3_stmt */
- (NSArray<ModelOfStudent *> *)selectWithSex:(NSString *)sex {
NSMutableArray *arr = [NSMutableArray array];
// 查找SQL語句
NSString *sql = [NSString stringWithFormat:@"SELECT * FROM dls160101 WHERE sex = '%@'", sex];
// 創(chuàng)建一個準(zhǔn)備好的語句對象
sqlite3_stmt *stmt = nil;
// 為準(zhǔn)備好的語句對象賦值(SQL語句內(nèi)容)。
int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);
if (result == SQLITE_OK) {
NSLog(@"查詢中...");
// 當(dāng)有下一行數(shù)據(jù)時,繼續(xù)執(zhí)行檢索。
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 查詢條件匹配 使用函數(shù)簇將需要的列值取出來
const unsigned char *name = sqlite3_column_text(stmt, 1);
const unsigned char *sex = sqlite3_column_text(stmt, 2);
int age = sqlite3_column_int(stmt, 3);
// 創(chuàng)建model賦值
ModelOfStudent *stu = [[ModelOfStudent alloc]init];
stu.name = [NSString stringWithUTF8String:(const char *)name];
stu.sex = [NSString stringWithUTF8String:(const char *)sex];
stu.age = age;
// 添加到數(shù)組
[arr addObject:stu];
}
NSLog(@"查詢結(jié)果,有%ld條記錄匹配", arr.count);
sqlite3_step(stmt);
} else {
NSLog(@"未能啟動查詢過程,錯誤碼:%d", result);
}
// 銷毀stmt對象(內(nèi)存管理)
sqlite3_finalize(stmt);
return arr;
}