線程類型:
1.單線程
設置方法:
經過在實例化sqlite3 *db時調用
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
不支持併發操做sql
2.多線程(默認)
設置方法:
經過在實例化sqlite3 *db時調用
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
不支持併發操做數據庫
3.串行(經常使用)
設置方法:
經過在實例化sqlite3 *db時調用
sqlite3_config(SQLITE_CONFIG_SERIALIZED);
支持併發操做,其實是系統給對應的地方加鎖,變相把並行變爲串行訪問多線程
sqlite3 *db
數據庫句柄,跟文件句柄FILE很相似併發
int sqlite3_open(const char *filename,sqlite3 **ppDb)
打開數據庫,沒有數據庫時建立。
filename:數據庫的文件路徑
ppDb:數據庫實例函數
sqlite3_stmt *stmt
這個至關於ODBC的Command對象,用於保存編譯好的SQL語句工具
int sqlite3_prepare_v2(sqlite3 *db,const char *zSql,int nBytes,sqlite3_stmt **ppStmt,const char **pzTail)
建立sqlite3_stmt對象
db:數據庫實例
zSql:須要檢查的SQL語句
nBytes:SQL語句的最大字節長度
ppStmt:sqlite3_stmt實例,用來得到數據庫數據
pzTail:線程
int sqlite3_exec(sqlite3 *db,const char *sql,int(*callback)(void *,int,char **,char **),void *,char **errmsg)
執行非查詢(創表,更新,插入,刪除,開啓事務,回滾事務,提交事務)的sql語句
db:一個打開的數據庫實例
sql:須要執行的SQL語句
callback:SQL語句執行完畢後的回調
void *:回調函數的第一個參數
errmsg:錯誤信息指針
sqlite3_bind_xxxx()
綁定sql語句須要用到的參數
第一個參數是sqlite3_stmt *類型
第二個int類型參數-表示參數的在SQL中的序號(從1開始)。
第三個參數爲要綁定參數的值。
對於blob和text數值的額外參數:
第四參數是第三個參數數據(Unicode 8or16)的長度,若是是字符串可傳入-1代替字符串長度。
第五個參數,類型爲void(*)(void*),表示SQLite處理結束後用於清理參數字符串的函數。
沒有進行綁定的未知參數將被認爲是NULL。code
int sqlite3_step(sqlite3_stmt *)
在調用sqlite3_prepare後,使用這個函數在記錄集中移動。
可能的返回值:
SQLITE_BUSY: 數據庫被鎖定,須要等待再次嘗試直到成功。
SQLITE_DONE: 成功執行過程(須要再次執行一遍以恢復數據庫狀態)
SQLITE_ROW: 返回一行結果(使用sqlite3_column_xxx(sqlite3_stmt*,, int iCol)獲得每一列的結果。再次調用將返回下一行的結果。
SQLITE_ERROR: 運行錯誤,過程沒法再次調用(錯誤內容參考sqlite3_errmsg函數返回值)
SQLITE_MISUSE: 錯誤的使用了本函數(通常是過程沒有正確的初始化)orm
sqlite3_finalize(sqlite3_stmt *pStmt)
清理sqlite3_stmt對象
sqlite3_close(sqlite3 *db)
關閉數據庫文件
還有一系列的函數,用於從記錄集字段中獲取數據,如
sqlite3_column_text()
取text類型的數據。
sqlite3_column_blob()
取blob類型的數據
sqlite3_column_int()
取int類型的數據
其餘工具函數
1. 獲得結果總共的行數,若是過程沒有返回值,如update,將返回0
int sqlite3_column_count(sqlite3_stmt *pStmt);
2. 獲得當前行中包含的數據個數,若是sqlite3_step返回SQLITE_ROW,能夠獲得列數,不然爲零。
int sqlite3_data_count(sqlite3_stmt *pStmt);
3. 獲得數據行中某個列的數據,在sqlite3_step返回SQLITE_ROW後,使用它獲得第iCol列的數據。
sqlite3_column_xxx(sqlite3_stmt*, int iCol);
其中的xxx表明:
blob:指向保存數據內存的指針
bytes, bytes16: 獲得該blob類型數據的大小,或者text轉換爲UTF8/UTF16的字符串長度。
double, int, int64: 數值
text,text16:字符串指針
type:該列的數據類型(SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL)
注意:若是對該列使用了不一樣與該列自己類型適合的數據讀取方法,獲得的數值將是轉換過的結果。
4. 獲得數據行中某個列的數據的類型
int sqlite3_column_type(sqlite3_stmt*, int iCol);
返回值:
SQLITE_INTEGER,
SQLITE_FLOAT,
SQLITE_TEXT,
SQLITE_BLOB,
SQLITE_NULL
使用的方法和sqlite3_column_xxx()函數相似。
經常使用sql語句:
建表
create table t_student (id integer, name text, age integer, score real) ;
刪表
drop table if exists 表名 ;
插入數據
insert into t_student (name, age) values ('mj', 10) ;//SQL語句中字符串用''單引號
更新數據
update t_student set name = 'jack', age = 20 ;
刪除數據
delete from t_student;
條件語句
where 字段 = 某個值 ; // 不能用兩個 =
where 字段 is 某個值 ; // is 至關於 =
where 字段 != 某個值 ;
where 字段 is not 某個值 ; // is not 至關於 !=
where 字段 > 某個值 ;
where 字段1 = 某個值 and 字段2 > 某個值 ; // and至關於C語言中的 &&
where 字段1 = 某個值 or 字段2 = 某個值 ; // or 至關於C語言中的 ||
查詢數據
select * from t_student where age > 10 ; // 條件查詢
模糊查詢
select id,name,age from t_person where name like '%%%@%%' order by age asc;"
計算記錄的數量
select count (age) from t_student ;
或
select count ( * ) from t_student where score >= 60;
排序
select * from t_student order by age desc ; //降序
或
select * from t_student order by age asc ; // 升序(默認)
或
select * from t_student order by age asc, height desc ;//先按照年齡排序(升序),年齡相等就按照身高排序(降序)
使用limit控制查詢結果數量
select * from t_student limit 7;//表示取最前面的7條記錄
或
select * from t_student limit 4, 8 ;//跳過最前面4條語句,而後取8條記錄
limit經常使用來作分頁查詢,好比每頁固定顯示5條數據,那麼應該這樣取數據
第1頁:limit 0, 5
第2頁:limit 5, 5
第3頁:limit 10, 5
…
第n頁:limit 5*(n-1), 5
簡單約束
not null:規定字段值不能爲null
unique:規定字段值必須惟一
default:指定字段默認值
create table t_student (id integer, name text not null unique, age integer not null default 1) ;//name字段不能爲null,而且惟一;age字段不能爲null,而且默認爲1
主鍵約束
用來惟一地標識某一條記錄
create table t_student (id integer primary key, name text, age integer) ;//integer類型的id做爲t_student表的主鍵
自增加且作主鍵
create table t_student (id integer primary key autoincrement, name text, age integer) ;
外鍵約束
create table t_student (id integer primary key autoincrement, name text, age integer, class_id integer, constraint fk_student_class foreign key (class_id) references t_class (id));
鏈接表查詢
select s.name,s.age from t_student s, t_class c where s.class_id = c.id and c.name = '0316iOS';
使用範例:
打開數據庫
sqlite3 *db=NULL;
int result=sqlite3_open([dbPaht UTF8String],&db);
關閉數據庫
sqlite3_close(db);
執行不返回數據的SQL語句
char *errorMsg=NULL;
char *sql="create table if not exists myTableName(id integer primary key autoincrement,name text,age integer);";
int result=sqlite3_exec(db,sql,NULL,NULL,&errorMsg);
帶佔位符插入數據
char *sql="insert into myTableName(name,age)values(?,?);";
sqlite3_stmt *stmt;
if(sqlite3_prepare_v2(db,sql,-1,&stmt,NULL)==SQLITE_OK){//說明SQL語句已經準備成功,沒有語法問題
sqlite3_bind_text(stmt,1,"母雞",-1,NULL);//綁定SQL語句參數
sqlite3_bind_int(stmt,2,28);
}
if(sqlite3_step(stmt)!=SQLITE_DONE){//執行SQL語句,返回SQLITE_DONE表明執行完畢
NSLog(@"插入數據錯誤");
}
sqlite3_finalize(stmt);//銷燬sqlite3_stmt *對象
查詢數據
char *sql="select id,name,age from myTableName;";
sqlite3_stmt *stmt;
if(sqlite3_prepare_v2(db,sql,-1,&stmt,NULL)==SQLITE_OK){
while(sqlite3_step(stmt)==SQLITE_ROW){//返回SQLITE_ROW表明遍歷到一條新記錄
int _id=sqlite3_column_int(stmt,0);//獲取每一個字段對應的值,第2個參數是字段的索引,從0開始
char *_name=(char *)sqlite3_column_text(stmt,1);
NSString *name=[NSString stringWithUTF8String:_name];
int _age=sqlite3_column_int(stmt,2);
}
}
sqlite3_finalize(stmt);
事務: @try{ if (sqlite3_exec(dbo, "BEGIN", NULL, NULL, NULL)==SQLITE_OK) { NSLog(@"啓動事務成功"); sqlite3_stmt *stmt; NSArray *objects=object.insertObject.tableObjects; for (int i=0; i<objects.count; i++) { NSString *tableName=[NSString stringWithUTF8String:object_getClassName(object)]; NSString *sqlOffields=@""; NSString *sqlOfValues=@""; NSArray *insertSqlObjects=[self arrayOfSqlParameterFieldsName:object]; for (int idx=0; idx<insertSqlObjects.count; idx++) { NSAssert([insertSqlObjects[idx] isKindOfClass:[OC_Sqlite3_SqlParameterClass class]], @"OC_Sqlite3_TableObjectInterface variable of insertObject must be OC_Sqlite3_TableInsertSqlObject"); OC_Sqlite3_SqlParameterClass *insertSqlObject=(OC_Sqlite3_SqlParameterClass *)insertSqlObjects[idx]; if (idx != insertSqlObjects.count-1) { sqlOffields=[sqlOffields stringByAppendingFormat:@"%@,",insertSqlObject.fieldName]; sqlOfValues=[sqlOfValues stringByAppendingString:@"?,"]; }else{ sqlOffields=[sqlOffields stringByAppendingFormat:@"%@",insertSqlObject.fieldName]; sqlOfValues=[sqlOfValues stringByAppendingString:@"?"]; } } NSString *sql=[NSString stringWithFormat:@"insert into %@ (%@) values (%@)",tableName,sqlOffields,sqlOfValues]; if (sqlite3_prepare_v2(dbo, [sql UTF8String], -1, &stmt, NULL)==SQLITE_OK) { [self bindSqlParameterInArrayOfSqlParametersClasses:insertSqlObjects stmt:stmt]; if (sqlite3_step(stmt)!=SQLITE_DONE) { sqlite3_finalize(stmt); } }else{ sqlite3_finalize(stmt); } } if (sqlite3_exec(dbo, "COMMIT", NULL, NULL, NULL)==SQLITE_OK) { NSLog(@"提交事務成功"); sqlite3_finalize(stmt); return YES; } } } @catch(NSException *e){ if (sqlite3_exec(dbo, "ROLLBACK", NULL, NULL, NULL)==SQLITE_OK) { NSLog(@"回滾事務成功"); } return NO; } @finally{}