**@常用接口(2個重要結構體和5個主要函數)**
sqlite3 ? ? ? ? ? ? ? *pdb, 數據庫句柄,跟文件句柄 FILE 很類似
sqlite3_stmt ? ? ?*stmt, 這個相當于 ODBC 的 Command 對象,用于保存編譯好的 SQL 語句
sqlite3_open(), ? 打開數據庫
sqlite3_exec(), ? 執行非查詢的 sql 語句
sqlite3_prepare(), 準備 sql 語句,執行 select 語句或者要使用 parameter bind 時(封裝了 sqlite3_exec ) .
Sqlite3_step(), 在調用 sqlite3_prepare 后,使用這個函數在記錄集中移動。
Sqlite3_close(), 關閉數據庫文件
還有一系列的函數,用于從記錄集字段中獲取數據,如
sqlite3_column_text(), 取 text 類型的數據。
sqlite3_column_blob (),取 blob 類型的數據
sqlite3_column_int(), 取 int 類型的數據
**@Sqlite3主要步驟如下:**
1 首先獲取iPhone上Sqlite 3的數據庫文件的地址
2 打開Sqlite 3的數據庫文件
3 定義SQL文
4 邦定執行SQL所需要的參數
5 執行SQL文,并獲取結果
6 釋放資源
7 關閉Sqlite 3數據庫。
**@導入庫**
? ? ? 在工程中的Frameworks中導入相應的libsqlite3.dylib文件,也許在相應的目錄下存在多個以libsqlite3開頭的文件,務必選擇libsqlite3.dylib,它始終指向最新版的SQLite3庫的別名。?
**@SQLite數據庫執行SQL語句的過程?**
1\. 調用sqlite3_prepare()將SQL語句編譯為sqlite內部一個結構體(sqlite3_stmt).該結構體中包含了將要執行的的SQL語句的信息.?
2\. 如果需要傳入參數,在SQL語句中用'?'作為占位符,再調用sqlite3_bind_XXX()函數將對應的參數傳入.
3\. 調用sqlite3_step(),這時候SQL語句才真正執行.注意該函數的返回值,SQLITE_DONE和SQLITE_ROW都是表示執行成功, 不同的是SQLITE_DONE表示沒有查詢結果,象UPDATE,INSERT這些SQL語句都是返回SQLITE_DONE,SELECT查詢語句在 查詢結果不為空的時候返回SQLITE_ROW,在查詢結果為空的時候返回SQLITE_DONE.?
4\. 每次調用sqlite3_step()的時候,只返回一行數據,使用sqlite3_column_XXX()函數來取出這些數據.要取出全部的數據需要 反復調用sqlite3_step(). (注意, 在bind參數的時候,參數列表的index從1開始,而取出數據的時候,列的index是從0開始).?
5\. 在SQL語句使用完了之后要調用sqlite3_finalize()來釋放stmt占用的內存.該內存是在sqlite3_prepare()時分配的.?
6\. 如果SQL語句要重復使用,可以調用sqlite3_reset()來清楚已經綁定的參數
~~~
#import "HMTSqlDBManager.h"
#import <sqlite3.h> //--------記得導入libsqlite3.0.dylib庫
@implementation HMTSqlDBManager
static HMTSqlDBManager * _dbManager = nil;
+ (HMTSqlDBManager *)shareInstance{
@synchronized(self){
if (!_dbManager) {
_dbManager = [[HMTSqlDBManager alloc]init];
}
}
return _dbManager;
}
#pragma mark - 獲取沙盒下Documents路徑
- (NSString *)documentsPath{
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
}
#pragma mark - 先聲明一個數據庫類型的變量
static sqlite3 * dbSqlite = nil;
#pragma mark - 打開數據庫操作
- (void)openDB{
// (3)如果數據庫存在并且已經打開,直接返回
if (dbSqlite) {
return;
}
// 拼接出數據庫全路徑
NSString * filePath = [[self documentsPath] stringByAppendingPathComponent:@"Lanou.sqlite"];
// 創建一個文件管理器
NSFileManager * fileManager = [NSFileManager defaultManager];
// (1)判斷是否存在數據庫文件
if (![fileManager fileExistsAtPath:filePath]) {
// 打開數據庫(這里已經會創建data.sqlite數據庫了,但是,里面為空)
int result = sqlite3_open([filePath UTF8String], &dbSqlite);
if (result == SQLITE_OK) {
// 設置創建表語句CREATE
NSString * sql = @"CREATE TABLE Student (number INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , name TEXT DEFAULT 18, age INTEGER NOT NULL DEFAULT 18,sex TEXT DEFAULT 不男不女,icon BLOB);";
// 執行
sqlite3_exec(dbSqlite, [sql UTF8String], NULL, NULL, NULL);
}
}
// (2)打開數據庫
sqlite3_open([filePath UTF8String], &dbSqlite);
}
#pragma mark - 關閉數據庫操作
- (void)closeDB{
int result = sqlite3_close(dbSqlite);
if (result == SQLITE_OK) {
dbSqlite = nil;
}
}
#pragma mark - **********增-----刪-----改-----查 數據,最好封裝成對象,直接對對象進行操作**********
#pragma mark - 插入數據操作
- (void)insertDataWithNumber:(int)number Name:(NSString *)name Sex:(NSString *)sex Age:(int)age Image:(UIImage *)image{
// 1.打開數據庫
[self openDB];
// 2.跟隨指針,記錄數據庫的每步操作
sqlite3_stmt * stmt = nil;
// 3.綁定數據,執行sql語句(插入列表,用"?"占位符表示)
NSString * sql = @"INSERT INTO Student(number,name,sex,age,icon) VALUES(?,?,?,?,?)";
// 4.編譯,驗證SQL語句是否正確
int result = sqlite3_prepare_v2(dbSqlite, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
// 5.綁定sql語句中得值(替換"?")----圖像存入數據庫,自斷類型為blob,將圖像轉為二進制數據NSData存入
sqlite3_bind_int(stmt, 1, number);
sqlite3_bind_text(stmt, 2, [name UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 3, [sex UTF8String], -1, NULL);
sqlite3_bind_int(stmt, 4, age);
sqlite3_bind_blob(stmt, 5, [UIImagePNGRepresentation(image) bytes], (int)[UIImagePNGRepresentation(image) length], NULL);
}
// 6.執行
sqlite3_step(stmt);
// 7.釋放
sqlite3_finalize(stmt);
// 8.關閉數據庫
[self closeDB];
}
#pragma mark - 修改數據操作
- (void)updateNumber:(int)number Name:(NSString *)name{
// 1.
[self openDB];
// 2.
sqlite3_stmt * stmt= nil;
// 3.
NSString * sql = @"UPDATE Student SET name = ? WHERE number = ?";
// 4.
int result = sqlite3_prepare_v2(dbSqlite, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
// 5.
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, NULL);
sqlite3_bind_int(stmt, 2, number);
// 6.
sqlite3_step(stmt);
}
// 7.
sqlite3_finalize(stmt);
// 8.
[self closeDB];
}
#pragma mark - 刪除數據操作
- (void)deleteNumber:(int)number{
// 1.
[self openDB];
// 2.stmt跟隨指針(數據庫句柄)
sqlite3_stmt * stmt= nil;
// 3.
NSString * sql = @"DELETE FROM Student WHERE number = ?";
// 4.
int result = sqlite3_prepare_v2(dbSqlite, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
// 5.
sqlite3_bind_int(stmt,1, number);
// 6.
sqlite3_step(stmt);
}
// 7.
sqlite3_finalize(stmt);
// 8.
[self closeDB];
}
#pragma mark - 查詢數據操作
- (NSArray *)selectAllData{
NSMutableArray * allDataArray = [NSMutableArray array];
// 1.
dbSqlite = [self openDB];
// 2.類似JAVA句柄?
sqlite3_stmt * stmt = nil;
// 3.設置查詢數據語句SELECT
NSString * sql = @"SELECT name FROM Student";
// 4.編譯
int result = sqlite3_prepare_v2(dbSqlite, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
// 5.查詢數據
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 6.查詢的索引下標從0開始(每一次循環后,下標+1)
const unsigned char * name = sqlite3_column_text(stmt, 0);
//NSString * nameString = [NSString stringWithUTF8String:(const char *)name];
NSString * nameString = [NSString stringWithCString:(const char *)name encoding:NSUTF8StringEncoding];
[allDataArray addObject:nameString];
}
// 8.關閉數據庫句柄
sqlite3_finalize(stmt);
// 9.
[self closeDB];
return allDataArray;
}
return nil;
}
- (NSMutableDictionary *)selectOneDataWithNumber:(int)number{
sqlite3 * _dbSqlite = [self openDB];
sqlite3_stmt * stmt = nil;
NSString * sql = @"SELECT * FROM Student WHERE number = ?";
int result = sqlite3_prepare_v2(_dbSqlite, [sql UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, number);
while (sqlite3_step(stmt) == SQLITE_ROW) {
int number = sqlite3_column_int(stmt, 0);
NSString * name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
int age = sqlite3_column_int(stmt, 2);
NSString * sex = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 3)];
UIImage * image = [UIImage imageWithData:[NSData dataWithBytes:sqlite3_column_blob(stmt, 4) length:sqlite3_column_bytes(stmt, 4)]];
NSMutableDictionary * dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:number],@"number",name,@"name",[NSNumber numberWithInt:age],@"age",sex,@"sex",image,@"image", nil];
// 關閉數據庫句柄
sqlite3_finalize(stmt);
return dic;
}
}
return nil;
}
@end
@SQLite支持哪些數據類型些?
NULL 值為NULL
INTEGER 值為帶符號的整型,根據類別用1,2,3,4,6,8字節存儲
REAL 值為浮點型,8字節存儲
TEXT 值為text字符串,使用數據庫編碼(UTF-8, UTF-16BE or UTF-16-LE)存儲
BLOB 值為二進制數據,具體看實際輸入
---------但實際上,sqlite3也接受如下的數據類型:
smallint 16 位元的整數
interger 32 位元的整數
decimal(p,s) p 精確值和 s 大小的十進位整數,精確值p是指全部有幾個數(digits)大小值 ,s是指小數點後有幾位數。如果沒有特別指定,則系統會設為 p=5; s=0 。
float 32位元的實數。
double 64位元的實數。
char(n) n 長度的字串,n不能超過 254。
varchar(n) 長度不固定且其最大長度為 n 的字串,n不能超過 4000。
graphic(n) 和 char(n) 一樣,不過其單位是兩個字元 double-bytes, n不能超過127。 這個形態是為了支援兩個字元長度的字體,例如中文字。
vargraphic(n) 可變長度且其最大長度為 n 的雙字元字串,n不能超過 2000。
date 包含了 年份、月份、日期。
time 包含了 小時、分鐘、秒。
timestamp 包含了 年、月、日、時、分、秒、千分之一秒。
@如果將某個字段設置為INTEGER PRIMARY KEY屬性,有什么特性?
如果將聲明表的一列設置為 INTEGER PRIMARY KEY,則具有:
1.每當你在該列上插入一NULL值時, NULL自動被轉換為一個比該列中最大值大1的一個整數;
2.如果表是空的, 將會是1;
---------注意該整數會比表中該列上的插入之前的最大值大1。 該鍵值在當前的表中是唯一的。但有可能與已從表中刪除的值重疊。要
想建立在整個表的生命周期中唯一的鍵值,需要在 INTEGER PRIMARY KEY 上增加AUTOINCREMENT聲明。那么,新的鍵值將會比該表中曾能存在過的最大值大1。
@字段聲明中有AUTOINCREMENT屬性,有什么與眾不同的含義?
要想建立在整個表的生命周期中唯一的鍵值,需要在 INTEGER PRIMARY KEY 上增加AUTOINCREMENT聲明。那么,新的鍵值將會比該表中曾能存在過的最大值大1。
@SQL常用命令使用方法:
(1) 數據記錄篩選:
sql="select * from 數據表 where 字段名=字段值 order by 字段名 [desc]"
sql="select * from 數據表 where 字段名 like %字段值% order by 字段名 [desc]"
sql="select top 10 * from 數據表 where 字段名 order by 字段名 [desc]"
sql="select * from 數據表 where 字段名 in (值1,值2,值3)"
sql="select * from 數據表 where 字段名 between 值1 and 值2"
(2) 更新數據記錄:
sql="update 數據表 set 字段名=字段值 where 條件表達式"
sql="update 數據表 set 字段1=值1,字段2=值2 …… 字段n=值n where 條件表達式"
(3) 刪除數據記錄:
sql="delete from 數據表 where 條件表達式"
sql="delete from 數據表" (將數據表所有記錄刪除)
(4) 添加數據記錄:
sql="insert into 數據表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)"
sql="insert into 目標數據表 select * from 源數據表" (把源數據表的記錄添加到目標數據表)
(5) 數據記錄統計函數:
AVG(字段名) 得出一個表格欄平均值
COUNT(*|字段名) 對數據行數的統計或對某一欄有值的數據行數統計
MAX(字段名) 取得一個表格欄最大的值
MIN(字段名) 取得一個表格欄最小的值
SUM(字段名) 把數據欄的值相加
引用以上函數的方法:
sql="select sum(字段名) as 別名 from 數據表 where 條件表達式"
set rs=conn.excute(sql)
用 rs("別名") 獲取統的計值,其它函數運用同上。
(6) 數據表的建立和刪除:
CREATE TABLE 數據表名稱(字段1 類型1(長度),字段2 類型2(長度) …… )
例:CREATE TABLE tab01(name varchar(50),datetime default now())
DROP TABLE 數據表名稱 (永久性刪除一個數據表)
@sqlite中用LIMIT返回前2行,語句如下:
select * from aa order by ids desc LIMIT 2
~~~
- 前言
- 沙盒機制與文件(一)
- 沙盒機制和文件(二)
- 沙盒機制和文件(三)
- NSBundle介紹以及讀取沙盒文件路徑問題
- 數據持久化(一)-----歸檔 讀寫 文件路徑
- 數據持久化(二)-----Sqlite
- 數據持久化(三)使用第三方類庫FMDB
- 數據持久化(四)之NSUserDefaults
- 數據持久化(五)之CoreData
- 數據持久化(六)之Using CoreData with MagicalRecord
- 數據解析(一)解析XML之系統自帶NSXMLParse類
- 數據解析(二)解析XML之GDataXMLNode
- 數據解析(三)解析JSON-----系統自帶NSJSONSerialization 與 第三方JSONKit
- iOS多線程編程(一)NSThread
- iOS多線程編程(二)NSOperationQueue
- iOS多線程編程(三)Grand Central Dispatch(GCD)詳解
- iOS網絡編程(一)NSURLConnection
- iOS網絡編程(二) 自定義請求網絡類----推薦用于需要請求過程片段數據
- iOS網絡編程(三) 異步加載及緩存圖片---->SDWebImage
- iOS網絡編程(四) 異步加載及緩存圖片-----自定義類
- iOS網絡編程(五) 異步加載及緩存圖片-----EGO
- iOS網絡編程(六) NSURLSession詳解
- iOS網絡編程(7) 第三方開源庫----->AFNetworking