iPhone開發之SQLite

如今網站開發和軟件開發,數據庫的支持是少不了的;在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

SQLite函數知識準備

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

TestSQLite TestSQLite xcodeproj

輸出結果:函數

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來顯示數據,支持數據的輸入、刪除。工具

  • ♥ 1.建立Student模型類
  • ♥ 2.建立StudentDB類
  • ♥ 3.建立TableViewController用來顯示數據
  • ♥ 4.建立添加數據界面和代碼的實現
  • ♥ 5.刪除代碼的實現

接下來就按照這個步驟,一步步實現這些功能。

建立Student模型類

// 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類

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 

建立TableViewController用來顯示數據

經過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 

數據顯示效果圖:
iphone studentlistviewcontroller

建立添加數據界面和代碼的實現

經過點擊導航右邊的的「+」號按鈕來顯示,錄入學生資料界面,界面經過純代碼建立,點擊導航欄右邊的」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];}

iphone addstudentviewcontroller

刪除代碼的實現

- (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     }   }

完整代碼

下載

相關文章
相關標籤/搜索