剛開(kāi)始接觸sqlite數(shù)據(jù)的程序猿們,可能對(duì)數(shù)據(jù)的具體操作還是模模糊糊的,接下來(lái),就具體的步驟,我在這簡(jiǎn)單的寫(xiě)一下,希望能幫助到大家!
1.創(chuàng)建一個(gè)單例類(lèi)
第一步:
在.h文件中寫(xiě)入一下代碼
#import <Foundation/Foundation.h>
@interface DataBaseHandle:NSObject
//聲明一個(gè)單例類(lèi)方法(命名方法:share + 類(lèi)名)
+(DataBaseHandle *) shareDataBaseHandle;
//下面寫(xiě)的這些方法就是數(shù)據(jù)庫(kù)有關(guān)的方法
//打開(kāi)數(shù)據(jù)庫(kù)
- (void)openDB;
//創(chuàng)建表
- (void)createTabel;
//插入信息
- (void)insertName:(NSString *)name gender:(NSString*)gender age:(NSInteger)age;
//通過(guò)UID(索引)更新一個(gè)數(shù)據(jù)
- (void)updateWithUID:(NSInteger) uid;
//通過(guò)UID刪除一個(gè)數(shù)據(jù)
- (void)deleteWithUID:(NSInteger) uid;
//搜索全部
- (void)searchAll;
//根據(jù)name查詢一條數(shù)據(jù)
- (void)searchWithName:(NSString *)name;
//關(guān)閉數(shù)據(jù)庫(kù)
- (void)closeDB;
@end
第二步:
在.m文件中,實(shí)現(xiàn)相關(guān)的方法
//sqlite頭文件(如上面圖片是引入數(shù)據(jù)庫(kù)的步驟:)
#import "DataBaseHandle.h"
#import <sqlite3.h>
@interface DataBaseHandle ()
//創(chuàng)建一個(gè)documents文件夾下的一個(gè)叫做person.sqlite的文件
@property(nonatomic, strong) NSString *dbPath;
@end
//聲明一個(gè)靜態(tài)的實(shí)例變量
static DataBaseHandle *dataBaseHandle = nil;
@implementation DataBaseHandle
//實(shí)現(xiàn)單例方法
+ (DataBaseHandle *) shareDataBaseHandle
{
if(dataBaseHandle == nil)
{
dataBaseHandle = [[DataBaseHandle alloc] init];
}
return dataBaseHandle;
}
//懶加載(注意,懶加載方法里面不能用self.dbPath,因?yàn)閼屑虞d方法是get方法,這樣會(huì)造成程序崩潰).懶加載——也稱為延遲加載倘零,即在需要的時(shí)候才加載(效率低,占用內(nèi)存小)。
//這兒引用大神的一句話,進(jìn)行更深的講解,方便大家更好的理解,在懶加載中的判斷語(yǔ)句中和return中為什么不能用self.(類(lèi)名)了.請(qǐng)看下面的講解:
- (NSString*)dbPath這個(gè)方法就是self.dbPath的get方法,也就是說(shuō)每次你調(diào)用self.dbPath的時(shí)候都會(huì)進(jìn)入這個(gè)方法,那么問(wèn)題來(lái)了
如果你在這個(gè)方法里用了下面這個(gè)語(yǔ)句
if (self.dbPath == nil );邏輯上就行不通,因?yàn)槟阍谶@里調(diào)用self.cover他會(huì)再一次進(jìn)入這個(gè)方法,理論上就會(huì)死循環(huán)
而_dbPath是直接值訪問(wèn)的,他不會(huì)調(diào)用get/set方法,所以就不會(huì)有這個(gè)問(wèn)題.
//注意:如果是懶加載的話則一定要注意先判斷是否已經(jīng)有了,如果沒(méi)有那么再去進(jìn)行實(shí)例化
- (NSString *)dbPath
{
if(_dbPath == nil){
//在documents文件中創(chuàng)建person.sqlite文件
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
_dbPath = [documentsPath stringByAppendingPathComponent:@"person.sqlite"];
//打印出來(lái)_dbPath,是為了打開(kāi)看到數(shù)據(jù)庫(kù)中具體的可視化的東西
NSLog(@"_dbPath === %@",_dbPath);
}
return _dbPath;
}
//實(shí)現(xiàn)數(shù)據(jù)庫(kù)的相關(guān)方法
//初始化一個(gè)數(shù)據(jù)庫(kù)
static sqlite3 *db = nil;
//打開(kāi)數(shù)據(jù)庫(kù)
- (void)openDB
{
//打開(kāi)數(shù)據(jù)庫(kù)里面的函數(shù)(注意,要用self.dbPath,調(diào)用get方法,我們初始化得東西都在get方法里面,不能用_dbPath,因?yàn)檫@樣是直接調(diào)用屬性,里面什么東西都沒(méi)有)
//在數(shù)據(jù)庫(kù)里面,所有的字符串都要變成utf - 8編碼格式
int result = sqlite3_open(self.dbPath.UTF8String,&db);
if(result == SQLITE_OK)
{
NSLog(@"打開(kāi)數(shù)據(jù)庫(kù)成功");
}
else
{
NSLog(@"打開(kāi)數(shù)據(jù)庫(kù)失敗");
}
}
//下圖是數(shù)據(jù)庫(kù)的增刪查改等步驟的具體實(shí)現(xiàn)方法:
//對(duì)了,在寫(xiě)具體的實(shí)現(xiàn)方法之前,我在順便提一下數(shù)據(jù)庫(kù)的字段約束;
1.NOT NULL--非空
2.UNIQUE -- 唯一
3.PRIMARY KEY -- 主鍵
4.FOREING KEY --外鍵
5.AUTOINCREATEMENT --自增型變量
//1創(chuàng)建表:
//(建表命令 (create table)) 步驟:create table if not exists 表名(字段1 約束1 約束2,字段2 約束2 ......);1)create table建表關(guān)鍵字 2)if not exists如果創(chuàng)建的表存在就不在創(chuàng)建 3)創(chuàng)建表的名字 4)字段名字 5)對(duì)字段的約束(可以有多個(gè)約束)
- (void)createTable
{
NSString *createSqlString = @"create table if not exists person(uid integer premary key autoincrement not null,name text,gender text,age integer)";
//參數(shù):1.數(shù)據(jù)庫(kù);2.sql語(yǔ)句,要用utf- 8編碼格式;3結(jié)果的回調(diào)函數(shù);4回調(diào)函數(shù)參數(shù);5錯(cuò)誤信息.(一般情況下,我們就寫(xiě)前兩個(gè)參數(shù))
int result = sqlite3_exec(db,createSqlString.UTF8String,NULL,NULL,NULL);
if(result == SQLITE_OK){
NSLog(@"創(chuàng)建表成功");
}else{
NSLog(@"創(chuàng)建表失敗");
}
}
//2.插入數(shù)據(jù):
//(插入數(shù)據(jù)的sql語(yǔ)句,數(shù)據(jù)不確定,所以在values里面使用?代替,之后向里面綁定) 步驟:insert into 表名(字段1,字段2,......)values(字段1值,字段2值......) 1)inser into插入語(yǔ)句關(guān)鍵字 2)要插入數(shù)據(jù)的表名 3)要向那些字段插入數(shù)據(jù) 4)values值關(guān)鍵字 5)要插入的數(shù)據(jù)(注:要和字段順序相同)
- (void)insertName:(NSString *)name gender:(NSString *)gender age:(NSInteger:)age
{
//初始化一個(gè)伴隨指針
sqlite3_stmt *stmt = nil;
NSString *dataSqlString = @"insert into person (name,gender,age) values (?,?,?)";
//參數(shù):1.數(shù)據(jù)庫(kù);2.sql語(yǔ)句;3如果為正,例如:1,表示取參數(shù)的時(shí)候只取一個(gè)字節(jié).所以使用負(fù)數(shù)表示取值取到碰到結(jié)束符號(hào)('\000','u000');4伴隨指針,會(huì)伴隨著數(shù)據(jù)庫(kù)的操作,獲取值或綁定值;5取值的時(shí)候如果取不全,那么剩下的都存在這里.
int result = sqlite3_prepare(db,[dataSqlString UTF8String],-1,&stmt,NULL);
//如果預(yù)執(zhí)行成功的話,那么就可以往里面放數(shù)據(jù)了
if(result == SQLITE_OK){
//向預(yù)執(zhí)行的sql語(yǔ)句里面插入?yún)?shù)(取代'?'的位置)
//參數(shù):1.伴隨指針;2.'?'的位置;3.插入的數(shù)據(jù);4和上面的-1一樣;5.回調(diào)函數(shù)
sqlite3_bind_text(stmt,1,name.UTF8String,-1,NULL);
sqlite3_bind_text(stmt,2,gender.UIT8String,-1,NULL);
sqlite3_bind_int64(stmt,3,age);
//sql語(yǔ)句已經(jīng)全了,把參數(shù)都已經(jīng)放進(jìn)去了
//執(zhí)行伴隨指針,如果為SQLITE_DONE 代表執(zhí)行成功,并且成功的插入數(shù)據(jù)
if(sqlite3_step(stmt) == SQLITE_DONE){
NSLog(@"插入數(shù)據(jù)成功");
}else{
NSLog(@"插入數(shù)據(jù)失敗");
}
}
else{
//如果這兒輸出的result == 1的話,說(shuō)明前面縮寫(xiě)的sql語(yǔ)句有誤,請(qǐng)認(rèn)真查找
NSLog(@"result == %d",result);
}
//這里一定要記得釋放掉伴隨指針
sqlite3_finalize(stmt);
}
3.通過(guò)UID更新數(shù)據(jù)
//update 表名 set 字段1 = 修改值,字段2 = 修改值,...... where 條件 1)update set更新數(shù)據(jù)關(guān)鍵字 2)更新數(shù)據(jù)的表名 3)需要修改數(shù)據(jù)的字段,和修改后的值 4)where條件關(guān)鍵字 5)條件可以有一個(gè)或多個(gè).(注:多個(gè)條件使用and(與),or(或)連接)
- (void)updateWithUID:(NSInteger:)uid
{
NSString *updateSqlString = @"update person set name = '黃軍',gender = '男' where uid = ? ";
//伴隨指針
static sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare(db,[updateSqlString UTF8String],&stmt,NULL);
if(result == SQLITE_OK){
sqlite3_bind_int64(stmt,1,uid);
if(sqlite3_step(stmt) == SQLITE_DONE){
NSLog(@"修改成功");
}
}
sqlite_finalize(stmt);
}
4.通過(guò)UID刪除一個(gè)數(shù)據(jù)
步驟:delete from 表名 where 條件;1)delete from刪除關(guān)鍵字 2)要?jiǎng)h除數(shù)據(jù)的表名 3)where條件關(guān)鍵字 4)刪除條件
- (void)deleteWithUID:(NSInteger)uid
{
NSString *deleteString = [NSString stringWithFormat:@"delete from person where uid = %ld",uid];
int result = sqlite3_exec(db,deleteString.UTF8String,NULL,NULL,NULL);
if(result == SQLITE_OK){
NSLog(@"刪除成功");
}
else{
NSLog(@"刪除失敗");
}
}
5.搜索全部數(shù)據(jù)
//步驟:select 要查找的字段 from 表名 where 條件 1)select查找關(guān)鍵字 2)要查找到字段(如果要查找所有的字段可以使用通配符*) 3)from關(guān)鍵字,要查找數(shù)據(jù)表名 4)where條件關(guān)鍵字 5)查找條件
- (void)searchAll
{
NSString *searchSql = @"select * from person";
static sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare(db,searchSql.UTF8String,-1,&stmt,NULL);
if(result == SQLITE_OK){
//當(dāng)sqlite3_step(stmt) == SQLITE_ROW的時(shí)候,代表還有下一條數(shù)據(jù)
if(sqlite3_step(stmt) == SQLITE_ROW){
int uid = 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);
NSLog(@"%d,%@,%@,%d",uid,name,gender,age);
NSLog(@"開(kāi)始查找");
}
}
sqlite3_finalize(stmt);
}
@end