如今網站開發和軟件開發,數據庫的支持是少不了的;在iPhone開發中,做爲數據持久化的解決方案中,SQLite是不錯的選擇,它既輕量佔用資源少,又能夠方便嵌入到程序中,在一些嵌入式設備中有着普遍使用。sql
SQLite提供了命令行工具sqlite3,建立建立庫。shell
cjdx@~/Desktop$ sqlite3 school.sqlite3 SQLite version 3.6.12 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>
建立student表數據庫
sqlite> create table student (key integer primary key, name text, age integer, birth date);
插入三條數據小程序
sqlite> insert into student (name, age, birth) values ('zhangsan', 18, '1980-01-09'); sqlite> insert into student (name, age, birth) values ('lisi', 20, '1980-10-05'); sqlite> insert into student (name, age, birth) values ('wangwu', 28, '1985-12-20');
查詢剛剛插入的數據數組
sqlite> select * from student;1|zhangsan|18|1980-01-092|lisi|20|1980-10-053|wangwu|28|1985-12-20
sqlite3_open 打開數據庫 sqlite3_close 關閉數據庫 sqlite3_prepare 預編譯SQL語句 sqlite3_step 執行預編譯後的SQL sqlite3_finalize 釋放資源
打開Xcode,建立iPhone項目,基於「Single View Application」,並命名爲TestSQLite,把剛纔建立的school.sqlite3添加項目「Supporting Files」目錄。xcode
先寫些測試代碼,看看sqlite能不能正常工做,在ViewController.m中添加以下代碼:app
// ViewController.m #import "ViewController.h" #import "/usr/include/sqlite3.h" @implementation ViewController ... #pragma mark - View lifecycle - (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. sqlite3 *db; char *szError = NULL; sqlite3_stmt *dbps; NSString *dbFile = [[NSBundle mainBundle] pathForResource:@"school" ofType:@"sqlite3"]; if (sqlite3_open([dbFile UTF8String], &db) != SQLITE_OK) { NSLog(@"failed to open db."); } NSString *sql_insert = @"insert into student (name, age, birth) values ('testdata', 16, '1987-09-18')"; if (sqlite3_exec(db, [sql_insert UTF8String], 0, 0, &szError) == SQLITE_OK) { NSLog(@"%d", sqlite3_changes(db)); } NSString *sql_select = @"SELECT * FROM student"; sqlite3_prepare_v2(db, [sql_select UTF8String], -1, &dbps, NULL); int nResult = sqlite3_step(dbps); for (int fld = 0; fld < sqlite3_column_count(dbps); fld++) { NSLog(@"%s", sqlite3_column_name(dbps, fld)); } while (nResult != SQLITE_DONE) { NSLog(@"%s|%s|%s|%s", sqlite3_column_text(dbps, 0), sqlite3_column_text(dbps, 1), sqlite3_column_text(dbps, 2), sqlite3_column_text(dbps, 3)); nResult = sqlite3_step(dbps); } sqlite3_close(db);} ...@end
把sqlite3鏈接庫添加到項目iphone
輸出結果:函數
2012-02-06 18:59:33.372 TestSQLite[4011:207] 1 2012-02-06 18:59:33.375 TestSQLite[4011:207] key 2012-02-06 18:59:33.377 TestSQLite[4011:207] name 2012-02-06 18:59:33.379 TestSQLite[4011:207] age 2012-02-06 18:59:33.380 TestSQLite[4011:207] birth 2012-02-06 18:59:33.384 TestSQLite[4011:207] 1|zhangsan|18|1980-01-09 2012-02-06 18:59:33.386 TestSQLite[4011:207] 2|lisi|20|1980-10-05 2012-02-06 18:59:33.387 TestSQLite[4011:207] 3|wangwu|28|1985-12-20 2012-02-06 18:59:33.405 TestSQLite[4011:207] 4|testdata|16|1987-09-18
在Objc中直接用SQLite的C API寫,若是每一個查詢都這樣,太繁瑣了,並且也不OO,因此仍是要封裝一下的,這樣就能夠把先前學過的知識串起來,寫個小程序,用TableView來顯示數據,支持數據的輸入、刪除。工具
接下來就按照這個步驟,一步步實現這些功能。
// Student.h #import <Foundation/Foundation.h> @interface Student : NSObject { int uniqueId; NSString *name; int age; NSDate *birth;} @property (nonatomic, assign) int uniqueId;@property (nonatomic, retain) NSString *name;@property (nonatomic, assign) int age;@property (nonatomic, retain) NSDate *birth; - (id)initWithUniqueId:(int)uniqueId name:(NSString *)name age:(int)age birth:(NSDate *)birth; @end
// Student.m #import "Student.h" @implementation Student @synthesize uniqueId, name, age, birth; - (id)initWithUniqueId:(int)uniqueId name:(NSString *)name age:(int)age birth:(NSDate *)birth{ self = [super init]; if (self) { self.uniqueId = uniqueId; self.name = name; self.age = age; self.birth = birth; } return self;} - (void)dealloc{ name = nil; birth = nil; [super dealloc];} @end
StudentDB類是sqlite的簡單封裝,獲取的數據被包裝到Student類中,有點ORM的感受,代碼長的就不貼代碼,只貼一些關鍵代碼。
// StudentDB.m #import "StudentDB.h" #import "Student.h" @implementation StudentDB @synthesize db; - (id)init{ self = [super init]; if (self) { NSString *dbFile = [[NSBundle mainBundle] pathForResource:@"school" ofType:@"sqlite3"]; if (sqlite3_open([dbFile UTF8String], &db) != SQLITE_OK) { NSLog(@"failed to open db."); } } return self;} -(int)getStudentsCount{ ...} - (NSMutableArray *)getAllStudent{ sqlite3_stmt *pStmt; NSMutableArray *studentArray = [[NSMutableArray alloc] init]; NSString *sql = @"SELECT * FROM student;"; sqlite3_prepare_v2(db, [sql UTF8String], -1, &pStmt, nil); while (SQLITE_ROW == sqlite3_step(pStmt)) { int uniqueId = sqlite3_column_int(pStmt, 0); NSString *name = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(pStmt, 1)]; int age = sqlite3_column_int(pStmt, 2); NSDateFormatter *formate = [[NSDateFormatter alloc] init]; [formate setDateFormat:@"yyyy-MM-dd"]; NSDate *birth= [formate dateFromString:[[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(pStmt, 3)]]; Student *student = [[Student alloc] initWithUniqueId:uniqueId name:name age:age birth:birth]; [studentArray addObject:student]; [formate release]; [name release]; [student release]; } sqlite3_finalize(pStmt); return studentArray;} - (void)removeStudent:(Student *)person{ ...} - (void)addStudent:(Student *)person{ ...} - (void)dealloc{ sqlite3_close(db); [super dealloc];} @end
經過StudentDB類的getAllStudent方法獲取全部學生的數組做爲數據源
// StudentListViewController.h #import <UIKit/UIKit.h> @class StudentDB; @interface StudentListViewController : UITableViewController{ StudentDB *db; NSMutableArray *students;} @end
#import "StudentListViewController.h" #import "StudentDB.h" #import "Student.h" #import "AddStudentViewController.h" @implementation StudentListViewController - (void)viewDidLoad{ // 初始化db db = [[StudentDB alloc] init]; [super viewDidLoad];} - (void)viewWillAppear:(BOOL)animated{ // 獲取全部學生數據保存到students數組中 students = [db getAllStudent]; [self.tableView reloadData]; [super viewWillAppear:animated];} - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1;} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ // 返回行數 return students.count;} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; } // Configure the cell... Student *student = [students objectAtIndex:indexPath.row]; cell.textLabel.text = student.name; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd"]; NSString *strBirth = [dateFormatter stringFromDate:student.birth]; NSString *strDescription = [[NSString alloc] initWithFormat:@"年齡:%d 生日:%s", student.age, [strBirth UTF8String]]; [cell.detailTextLabel setText:strDescription]; [dateFormatter release]; [strDescription release]; return cell;} - (void)dealloc{ [students release]; [db release]; [super dealloc];} @end
數據顯示效果圖:
經過點擊導航右邊的的「+」號按鈕來顯示,錄入學生資料界面,界面經過純代碼建立,點擊導航欄右邊的」Done」來完成錄入數據工做,而後返回學生列表界面執行reloadData操做,這樣新錄入的數據就能顯示出來了
// AddStudentViewController.m // 執行添加數據到數據庫中的操做,沒有驗證性操做 - (void)doneButtonPushed:(id)sender{ StudentDB *db = [[StudentDB alloc] init]; NSString *strName = txtName.text; int age = [txtAge.text intValue]; NSString *strBirth = txtBirth.text; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd"]; Student *student = [[Student alloc] initWithUniqueId:0 name:strName age:age birth:[dateFormatter dateFromString:strBirth]]; [db addStudent:student]; [student release]; [db release]; [dateFormatter release]; [self.navigationController popViewControllerAnimated:YES];}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source Student *student = [students objectAtIndex:indexPath.row]; //刪除數據庫中的數據 [db removeStudent:student]; //刪除數組中的數據 [students removeObjectAtIndex:indexPath.row]; //刪除TableView中的數據 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } }
完整代碼