管理工具:Navicat
數據類型
{
text 字段
integer 數字
real 浮點
bolb 二進制 能夠完整保存數據,例如照片
}
ddl(結構定義 CREATE ALTER DROP)
{
CREATE
CREATE TABLE 表的名字(每一個字段的定義 字段名 數據類型...)
CREATE TABLE t_cjb(xiaoming text NOT NULL,
yuwen integer NOT NULL)
}
dml(數據操做 INSERT DELETE UPDATE SELECT)
{
INSERT
INSERT INTO 表名(字段列表) values(值的列表)
INSERT INTO studnet(id,name) VALUES (3,'linf') integer 能夠不用''
UPDATE
UPDATE 表名 SET 字段名=值...WHERE 條件
UPDATE studnet SET telnum = '13100000000' WHERE name = 'xiaoming'
DELETE
DELETE FROM 表名 WHERE 條件
DELETE FROM studnet WHERE name = 'xiaoming'
SELECT
SELECT 字段列表 FROM 表名 WHERE 條件 ORDER BY 字段名
SELECT telnum (AS 電話號碼) FROM studnet WHERE name = 'xiaoming'
SELECT * FROM studnet WHERE name = 'xiaoming' //顯示全部列
SELECT * FROM studnet WHERE name LIKE '張%' //模糊查詢,like
SELECT * FROM studnet WHERE age>20 AND age<30 //顯示全部列,*
SELECT * FROM studnet WHERE age>20 ORDER BY age //排序,大於20的年齡從小到大排
SELECT * FROM studnet WHERE age>20 ORDER BY age DESC//排序,大於20的年齡從大到小排
統計函數(數據類型爲intege real)
SELECT count(*) FROM studnet WHERE age>20 AND age<30 //求個數
SELECT sum(age) FROM studnet //求總數
SELECT avg(age) FROM studnet //求平均數
SELECT *,yuwen+shuxue+yingyu AS sum FROM student //各個列總和mysql
在iOS中使用SQLite3,首先要添加庫文件libsqlite3.dylib和導入主頭文件git
// 打開數據庫(鏈接數據庫) NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"shops.sqlite"]; // 若是數據庫文件不存在, 系統會自動建立文件自動初始化數據庫 int status = sqlite3_open(filename.UTF8String, &_db); if (status == SQLITE_OK) { // 打開成功 NSLog(@"打開數據庫成功"); // 創表 const char *sql = "CREATE TABLE IF NOT EXISTS t_shop (id integer PRIMARY KEY, name text NOT NULL, price real);"; char *errmsg = NULL; sqlite3_exec(self.db, sql, NULL, NULL, &errmsg); if (errmsg) { NSLog(@"創表失敗--%s", errmsg); } } else { // 打開失敗 NSLog(@"打開數據庫失敗"); }
sqlite3_exec()能夠執行任何SQL語句,好比創表、更新、插入和刪除操做。可是通常不用它執行查詢語句,由於它不會返回查詢到的數據github
//插入數據 NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_shop(name, price) VALUES ('%@', %f);", self.nameField.text, self.priceField.text.doubleValue]; sqlite3_exec(self.db, sql.UTF8String, NULL, NULL, NULL); //帶佔位符插入數據 char *sql = "insert into t_person(name, age) values(?, ?);"; sqlite3_stmt *stmt = NULL; // stmt是用來取出查詢結果的 if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) { //-1是自動計算sql語句的長度 sqlite3_bind_text(stmt, 1, "母雞", -1, NULL); sqlite3_bind_int(stmt, 2, 27); } if (sqlite3_step(stmt) != SQLITE_DONE) { NSLog(@"插入數據錯誤"); } sqlite3_finalize(stmt); 代碼解析: sqlite3_prepare_v2()返回值等於SQLITE_OK,說明SQL語句已經準備成功,沒有語法問題 sqlite3_bind_text():大部分綁定函數都只有3個參數 第1個參數是sqlite3_stmt *類型 第2個參數指佔位符的位置,第一個佔位符的位置是1,不是0 第3個參數指佔位符要綁定的值 第4個參數指在第3個參數中所傳遞數據的長度,對於C字符串,能夠傳遞-1代替字符串的長度 第5個參數是一個可選的函數回調,通常用於在語句執行後完成內存清理工做
// sqlite3_step()返回SQLITE_ROW表明遍歷到一條新記錄 sqlite3_column_*()用於獲取每一個字段對應的值,第2個參數是字段的索引,從0開始 const char *sql = "SELECT name,price FROM t_shop;"; // stmt是用來取出查詢結果的 sqlite3_stmt *stmt = NULL; // 準備 int status = sqlite3_prepare_v2(self.db, sql, -1, &stmt, NULL); if (status == SQLITE_OK) { // 準備成功 -- SQL語句正確 while (sqlite3_step(stmt) == SQLITE_ROW) { // 成功取出一條數據 const char *name = (const char *)sqlite3_column_text(stmt, 0); const char *price = (const char *)sqlite3_column_text(stmt, 1); HMShop *shop = [[HMShop alloc] init]; shop.name = [NSString stringWithUTF8String:name]; shop.price = [NSString stringWithUTF8String:price]; [self.shops addObject:shop]; } }
#pragma mark - UISearchBarDelegate - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { [self.shops removeAllObjects]; NSString *sql = [NSString stringWithFormat:@"SELECT name,price FROM t_shop WHERE name LIKE '%%%@%%' OR price LIKE '%%%@%%' ;", searchText, searchText]; // stmt是用來取出查詢結果的 sqlite3_stmt *stmt = NULL; // 準備 int status = sqlite3_prepare_v2(self.db, sql.UTF8String, -1, &stmt, NULL); if (status == SQLITE_OK) { // 準備成功 -- SQL語句正確 while (sqlite3_step(stmt) == SQLITE_ROW) { // 成功取出一條數據 const char *name = (const char *)sqlite3_column_text(stmt, 0); const char *price = (const char *)sqlite3_column_text(stmt, 1); HMShop *shop = [[HMShop alloc] init]; shop.name = [NSString stringWithUTF8String:name]; shop.price = [NSString stringWithUTF8String:price]; [self.shops addObject:shop]; } } [self.tableView reloadData]; }
FMDB以OC的方式封裝了SQLite的C語言APIsql
FMDB的優勢
使用起來更加面向對象,省去了不少麻煩、冗餘的C語言代碼
對比蘋果自帶的Core Data框架,更加輕量級和靈活
提供了多線程安全的數據庫操做方法,有效地防止數據混亂
FMDB的github地址
https://github.com/ccgus/fmdb
數據庫
1)FMDatabase
一個FMDatabase對象就表明一個單獨的SQLite數據庫
用來執行SQL語句
2)FMResultSet
使用FMDatabase執行查詢後的結果集
3)FMDatabaseQueue
用於在多線程中執行多個查詢或更新,它是線程安全的
api
FMDatabase *db = [FMDatabase databaseWithPath:path]; if (![db open]) { NSLog(@"數據庫打開失敗!"); }
空字符串@"" 會在臨時目錄建立一個空的數據庫。當FMDatabase鏈接關閉時,數據庫文件也被刪除
nil會建立一個內存中臨時數據庫,當FMDatabase鏈接關閉時,數據庫會被銷燬
安全
在FMDB中,除查詢之外的全部操做,都稱爲「更新」
create、drop、insert、update、delete等
使用executeUpdate:方法執行更新
多線程
- (BOOL)executeUpdate:(NSString*)sql, ... - (BOOL)executeUpdateWithFormat:(NSString*)format, ... - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
示例 FMDB中SQL語句字符串不須要加''
框架
//插入數據 [db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" , @"hi'", // look! I put in a ', and I'm not escaping it! [NSString stringWithFormat:@"number %d", i], [NSNumber numberWithInt:i], [NSDate date], [NSNumber numberWithFloat:2.2f]]; } //更新數據 [db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]
查詢方法
異步
- (FMResultSet *)executeQuery:(NSString*)sql, ... - (FMResultSet *)executeQueryWithFormat:(NSString*)format, ... - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
示例.遍歷結果集
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"]; // 遍歷結果集 while ([rs next]) { NSString *name = [rs stringForColumn:@"name"]; int age = [rs intForColumn:@"age"]; double score = [rs doubleForColumn:@"score"]; }
模糊查詢
查詢語句中%%xxx%%表明包含xx字段,%x表明xx開頭字段,x%表明xx結尾字段 +(NSArray*)queryFuzzyContactInfo:(NSString *)item { FMDatabase *database = [FMDatabase databaseWithPath:SQLITEPATH1]; if (![database open]) { NSLog(@"數據庫打開失敗"); } NSMutableArray *array = [NSMutableArray arrayWithCapacity:0]; FMResultSet *resultSet = [database executeQuery:@"select * from mysql1 WHERE name like '%%%@%%'",item]; while ([resultSet next]) { NSString * name = [resultSet stringForColumn:@"name"]; } return array; }
FMDatabase這個類是線程不安全的,若是在多個線程中同時使用一個FMDatabase實例,會形成數據混亂等問題
爲了保證線程安全,FMDB提供方便快捷的FMDatabaseQueue類
1)FMDatabaseQueue的建立
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
2)簡單使用
[queue inDatabase:^(FMDatabase *db) { [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"]; [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"]; [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"]; FMResultSet *rs = [db executeQuery:@"select * from t_student"]; while ([rs next]) { // … } }];
3)使用事務
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"]; [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"]; [db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"]; FMResultSet *rs = [db executeQuery:@"select * from t_student"]; while ([rs next]) { // … } }]; 事務回滾 *rollback = YES;