轉: http://www.cnblogs.com/xiaobaizhu/archive/2012/12/07/2808170.html
研究了幾天的數據庫,終於把它給搞出來了。Sqlite是ios上最常用的數據庫之一,大家還是有必要了解一下的。這是仿照網上的一個例子做的,有些部分寫的不好,我稍作了修改,以講解爲主,主要讓大家能夠明白如何修改,明白原理,達到舉一反三的目的。
先來看看效果圖
先來看看數據庫方法類,將各個操作都封裝在一個類裏面,達到代碼重用的目的,這是程序員都應該努力去實現的目標,這樣在下一次用到同樣的方法和類的時候,就可以直接使用封裝好的類,可以節約大量的時間。
先來看看.h文件
複製代碼
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#define kFilename @"testdb.db"
@class sqlTestList;
@interface sqlService : NSObject {
sqlite3 *_database;
}
@property (nonatomic) sqlite3 *_database;
-(BOOL) createTestList:(sqlite3 *)db;//創建數據庫
-(BOOL) insertTestList:(sqlTestList *)insertList;//插入數據
-(BOOL) updateTestList:(sqlTestList *)updateList;//更新數據
-(NSMutableArray*)getTestList;//獲取全部數據
- (BOOL) deleteTestList:(sqlTestList *)deletList;//刪除數據:
- (NSMutableArray*)searchTestList:(NSString*)searchString;//查詢數據庫,searchID爲要查詢數據的ID,返回數據爲查詢到的數據
@end
@interface sqlTestList : NSObject//重新定義了一個類,專門用於存儲數據
{
int sqlID;
NSString *sqlText;
NSString *sqlname;
}
@property (nonatomic) int sqlID;
@property (nonatomic, retain) NSString *sqlText;
@property (nonatomic, retain) NSString *sqlname;
@end
複製代碼
再來看看.m文件
複製代碼
//
// sqlService.m
// SQLite3Test
//
// Created by fengxiao on 11-11-28.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "sqlService.h"
@implementation sqlService
@synthesize _database;
- (id)init
{
return self;
}
- (void)dealloc
{
[super dealloc];
}
//獲取document目錄並返回數據庫目錄
- (NSString *)dataFilePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(@"=======%@",documentsDirectory);
return [documentsDirectory stringByAppendingPathComponent:@"data.db"];//這裏很神奇,可以定義成任何類型的文件,也可以不定義成.db文件,任何格式都行,定義成.sb文件都行,達到了很好的數據隱祕性
}
//創建,打開數據庫
- (BOOL)openDB {
//獲取數據庫路徑
NSString *path = [self dataFilePath];
//文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//判斷數據庫是否存在
BOOL find = [fileManager fileExistsAtPath:path];
//如果數據庫存在,則用sqlite3_open直接打開(不要擔心,如果數據庫不存在sqlite3_open會自動創建)
if (find) {
NSLog(@"Database file have already existed.");
//打開數據庫,這裏的[path UTF8String]是將NSString轉換爲C字符串,因爲SQLite3是採用可移植的C(而不是
//Objective-C)編寫的,它不知道什麼是NSString.
if(sqlite3_open([path UTF8String], &_database) != SQLITE_OK) {
//如果打開數據庫失敗則關閉數據庫
sqlite3_close(self._database);
NSLog(@"Error: open database file.");
return NO;
}
//創建一個新表
[self createTestList:self._database];
return YES;
}
//如果發現數據庫不存在則利用sqlite3_open創建數據庫(上面已經提到過),與上面相同,路徑要轉換爲C字符串
if(sqlite3_open([path UTF8String], &_database) == SQLITE_OK) {
//創建一個新表
[self createTestList:self._database];
return YES;
} else {
//如果創建並打開數據庫失敗則關閉數據庫
sqlite3_close(self._database);
NSLog(@"Error: open database file.");
return NO;
}
return NO;
}
//創建表
- (BOOL) createTestList:(sqlite3*)db {
//這句是大家熟悉的SQL語句
char *sql = "create table if not exists testTable(ID INTEGER PRIMARY KEY AUTOINCREMENT, testID int,testValue text,testName text)";// testID是列名,int 是數據類型,testValue是列名,text是數據類型,是字符串類型
sqlite3_stmt *statement;
//sqlite3_prepare_v2 接口把一條SQL語句解析到statement結構裏去. 使用該接口訪問數據庫是當前比較好的的一種方法
NSInteger sqlReturn = sqlite3_prepare_v2(_database, sql, -1, &statement, nil);
//第一個參數跟前面一樣,是個sqlite3 * 類型變量,
//第二個參數是一個 sql 語句。
//第三個參數我寫的是-1,這個參數含義是前面 sql 語句的長度。如果小於0,sqlite會自動計算它的長度(把sql語句當成以\0結尾的字符串)。
//第四個參數是sqlite3_stmt 的指針的指針。解析以後的sql語句就放在這個結構裏。
//第五個參數是錯誤信息提示,一般不用,爲nil就可以了。
//如果這個函數執行成功(返回值是 SQLITE_OK 且 statement 不爲NULL ),那麼下面就可以開始插入二進制數據。
//如果SQL語句解析出錯的話程序返回
if(sqlReturn != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement:create test table");
return NO;
}
//執行SQL語句
int success = sqlite3_step(statement);
//釋放sqlite3_stmt
sqlite3_finalize(statement);
//執行SQL語句失敗
if ( success != SQLITE_DONE) {
NSLog(@"Error: failed to dehydrate:create table test");
return NO;
}
NSLog(@"Create table 'testTable' successed.");
return YES;
}
//插入數據
-(BOOL) insertTestList:(sqlTestList *)insertList {
//先判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement;
//這個 sql 語句特別之處在於 values 裏面有個? 號。在sqlite3_prepare函數裏,?號表示一個未定的值,它的值等下才插入。
static char *sql = "INSERT INTO testTable(testID, testValue,testName) VALUES(?, ?, ?)";
int success2 = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success2 != SQLITE_OK) {
NSLog(@"Error: failed to insert:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表上面的第幾個問號,這裏將三個值綁定到三個綁定變量
sqlite3_bind_int(statement, 1, insertList.sqlID);
sqlite3_bind_text(statement, 2, [insertList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [insertList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
//執行插入語句
success2 = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果插入失敗
if (success2 == SQLITE_ERROR) {
NSLog(@"Error: failed to insert into the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//獲取數據
- (NSMutableArray*)getTestList{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10];
//判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement = nil;
//sql語句
char *sql = "SELECT testID, testValue ,testName FROM testTable";//從testTable這個表中獲取 testID, testValue ,testName,若獲取全部的話可以用*代替testID, testValue ,testName。
if (sqlite3_prepare_v2(_database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement with message:get testValue.");
return NO;
}
else {
//查詢結果集中一條一條的遍歷所有的記錄,這裏的數字對應的是列值,注意這裏的列值,跟上面sqlite3_bind_text綁定的列值不一樣!一定要分開,不然會crash,只有這一處的列號不同,注意!
while (sqlite3_step(statement) == SQLITE_ROW) {
sqlTestList* sqlList = [[sqlTestList alloc] init] ;
sqlList.sqlID = sqlite3_column_int(statement,0);
char* strText = (char*)sqlite3_column_text(statement, 1);
sqlList.sqlText = [NSString stringWithUTF8String:strText];
char *strName = (char*)sqlite3_column_text(statement, 2);
sqlList.sqlname = [NSString stringWithUTF8String:strName];
[array addObject:sqlList];
[sqlList release];
}
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
return [array retain];//定義了自動釋放的NSArray,這樣不是個好辦法,會造成內存泄露,建議大家定義局部的數組,再賦給屬性變量。
}
//更新數據
-(BOOL) updateTestList:(sqlTestList *)updateList{
if ([self openDB]) {
sqlite3_stmt *statement;//這相當一個容器,放轉化OK的sql語句
//組織SQL語句
char *sql = "update testTable set testValue = ? and testName = ? WHERE testID = ?";
//將SQL語句放入sqlite3_stmt中
int success = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success != SQLITE_OK) {
NSLog(@"Error: failed to update:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表第幾個問號。這裏只有1個問號,這是一個相對比較簡單的數據庫操作,真正的項目中會遠遠比這個複雜
//綁定text類型的數據庫數據
sqlite3_bind_text(statement, 3, [updateList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [updateList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(statement, 1, updateList.sqlID);
//執行SQL語句。這裏是更新數據庫
success = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果執行失敗
if (success == SQLITE_ERROR) {
NSLog(@"Error: failed to update the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//執行成功後依然要關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//刪除數據
- (BOOL) deleteTestList:(sqlTestList *)deletList{
if ([self openDB]) {
sqlite3_stmt *statement;
//組織SQL語句
static char *sql = "delete from testTable where testID = ? and testValue = ? and testName = ?";
//將SQL語句放入sqlite3_stmt中
int success = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success != SQLITE_OK) {
NSLog(@"Error: failed to delete:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表第幾個問號。這裏只有1個問號,這是一個相對比較簡單的數據庫操作,真正的項目中會遠遠比這個複雜
sqlite3_bind_int(statement, 1, deletList.sqlID);
sqlite3_bind_text(statement, 2, [deletList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [deletList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
//執行SQL語句。這裏是更新數據庫
success = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果執行失敗
if (success == SQLITE_ERROR) {
NSLog(@"Error: failed to delete the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//執行成功後依然要關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//查詢數據
- (NSMutableArray*)searchTestList:(NSString*)searchString{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10];
//判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement = nil;
//sql語句
NSString *querySQL = [NSString stringWithFormat:@"SELECT * from testTable where testName like \"%@\"",searchString];
const char *sql = [querySQL UTF8String];
// char *sql = "SELECT * FROM testTable WHERE testName like ?";//這裏用like代替=可以執行模糊查找,原來是"SELECT * FROM testTable WHERE testName = ?"
if (sqlite3_prepare_v2(_database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement with message:search testValue.");
return NO;
} else {
sqlTestList *searchList = [[sqlTestList alloc]init];
// sqlite3_bind_int(statement, 1, searchID);
sqlite3_bind_text(statement, 3, [searchString UTF8String], -1, SQLITE_TRANSIENT);
//查詢結果集中一條一條的遍歷所有的記錄,這裏的數字對應的是列值。
while (sqlite3_step(statement) == SQLITE_ROW) {
sqlTestList* sqlList = [[sqlTestList alloc] init] ;
sqlList.sqlID = sqlite3_column_int(statement,1);
char* strText = (char*)sqlite3_column_text(statement, 2);
sqlList.sqlText = [NSString stringWithUTF8String:strText];
char *strName = (char*)sqlite3_column_text(statement, 3);
sqlList.sqlname = [NSString stringWithUTF8String:strName];
[array addObject:sqlList];
[sqlList release];
}
[searchList release];
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
return [array retain];
}
@end
@implementation sqlTestList//剛纔.h文件裏定義的類在這實現
@synthesize sqlID;
@synthesize sqlText;
@synthesize sqlname;
-(id) init
{
sqlID = 0;
sqlText = @"";
sqlname = @"";
return self;
};
-(void) dealloc
{
if ((sqlText != nil) && (sqlname != nil)) {
[sqlText release];
[sqlname release];
}
[super dealloc];
}
@end
複製代碼
這就是封裝好的類,可以重用哦!
下面是添加數據頁面
這也是一個類,來看.h文件
複製代碼
#import <UIKit/UIKit.h>
#import "sqlService.h"
@interface operateSqlViewController : UIViewController {
UITextField *idValue;
UITextField *textValue;
UITextField *textName;
int oprateType;//區分數據插入與更新
sqlTestList *sqlValue;
}
@property (nonatomic, retain) IBOutlet UITextField *idValue;
@property (nonatomic, retain) IBOutlet UITextField *textValue;
@property (nonatomic, retain) IBOutlet UITextField *textName;
@property (nonatomic, retain) sqlTestList *sqlValue;
@property (nonatomic) int oprateType;
@end
複製代碼
再來看看.m文件
複製代碼
#import "operateSqlViewController.h"
@implementation operateSqlViewController
@synthesize idValue;
@synthesize textValue;
@synthesize oprateType;
@synthesize sqlValue;
@synthesize textName;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidLoad{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:@"返回"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(dismiss:)];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithTitle:@"保存"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(saveValue:)];
[[self navigationItem] setLeftBarButtonItem:backButton];
[[self navigationItem] setRightBarButtonItem:saveButton];
[backButton release];
[saveButton release];
if (oprateType == 0) {
[self.navigationItem setTitle:@"數據插入"];
}
else if(oprateType == 1){
[self.navigationItem setTitle:@"數據更新"];
idValue.text = [NSString stringWithFormat:@"%d", sqlValue.sqlID];
textValue.text = sqlValue.sqlText;
textName.text = sqlValue.sqlname;
}
}
- (void)viewDidUnload {
idValue = nil;
textValue = nil;
textName = nil;
sqlValue = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[idValue release];
[textValue release];
[sqlValue release];
[textName release];
[super dealloc];
}
- (void)dismiss:(id)sender{
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
- (void)saveValue:(id)sender{
if (idValue.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入ID"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
if (textValue.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入電話"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
if (textName.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入姓名"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
//初始化數據庫
sqlService *sqlSer = [[sqlService alloc] init];
//數據庫插入
if (oprateType == 0) {
sqlTestList *sqlInsert = [[sqlTestList alloc]init];
sqlInsert.sqlID = [idValue.text intValue];
sqlInsert.sqlText = textValue.text;
sqlInsert.sqlname = textName.text;
//調用封裝好的數據庫插入函數
if ([sqlSer insertTestList:sqlInsert]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"插入數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"插入數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[sqlInsert release];
}
//數據庫更新
if(oprateType == 1){
sqlTestList *newValue = [[sqlTestList alloc]init];
newValue.sqlID = [idValue.text intValue];
newValue.sqlText = textValue.text;
newValue.sqlname = textName.text;
//調用封裝好的更新數據庫函數
if ([sqlSer updateTestList:newValue]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"更新數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"更新數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[newValue release];
}
}
@end
複製代碼
代碼寫的有些囉嗦,不過不難容易看懂,不多解釋了,要在xib文件中添加3個UITextField和ULabel,要記得連線。
在主界面的.h文件
複製代碼
#import <UIKit/UIKit.h>
#import "sqlService.h"
@interface SQLite3TestViewController : UIViewController<UITableViewDelegate,UITableViewDataSource> {
UITableView *utableView;
NSArray *listData;
UISearchBar *searchBar;//搜索欄
}
@property (nonatomic, retain) IBOutlet UITableView *utableView;
@property (nonatomic, retain) IBOutlet UISearchBar *searchBar;
@property (nonatomic, retain) NSArray *listData;
- (IBAction)insertValue;
- (IBAction)updateValue;
- (IBAction)getAllValue;
- (IBAction)deleteValue;
- (IBAction)searchValue;
@end
複製代碼
.m文件
複製代碼
//
// SQLite3TestViewController.m
// SQLite3Test
//
// Created by fengxiao on 11-11-28.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "SQLite3TestViewController.h"
#import "operateSqlViewController.h"
@implementation SQLite3TestViewController
@synthesize utableView;
@synthesize listData;
@synthesize searchBar;
- (void)viewDidLoad{
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];//先初始化那個專門用於存數據的類,才調用類獲取數據的方法
}
- (void)viewDidAppear:(BOOL)animated{//在這裏寫是爲了等待時間縮短一點,數據如果很多的,在這裏寫可以讓數據提前加載
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];
[sqlSer release];
[utableView reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
utableView = nil;
listData = nil;
searchBar = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[utableView release];
[listData release];
[searchBar release];
[super dealloc];
}
- (IBAction)insertValue{
[searchBar resignFirstResponder];//觸發這個insertValue方法時隱藏鍵盤
operateSqlViewController *operateController = [[operateSqlViewController alloc] init ];
UINavigationController *theNavController = [[UINavigationController alloc]
initWithRootViewController:operateController];//這裏如果不初始化一個UINavigationController類的對象來存放operateSqlViewController類的UIViewController,就不會有最上面的導航欄了。
operateController.oprateType = 0;//optrateType爲0時爲數據插入
[operateController release];
theNavController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:theNavController animated:YES];
[theNavController release];
}
- (IBAction)updateValue{
[searchBar resignFirstResponder];
NSIndexPath *indexPath = [utableView indexPathForSelectedRow];
if (indexPath == nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請選擇要更新的項"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc]init];
sqlList = [listData objectAtIndex:(row - 1)];//在這裏面獲取點擊的行,因爲table的第一行沒顯示數據,所以這裏要減1。
operateSqlViewController *operateController = [[operateSqlViewController alloc] init ];
UINavigationController *theNavController = [[UINavigationController alloc]
initWithRootViewController:operateController];
operateController.oprateType = 1;//optrateType爲1時爲數據更新
operateController.sqlValue = sqlList;
theNavController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:theNavController animated:YES];
[sqlList release];
[operateController release];
[theNavController release];
}
- (IBAction)getAllValue{
[searchBar resignFirstResponder];
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];
[utableView reloadData];
[sqlSer release];
}
- (IBAction)deleteValue{
[searchBar resignFirstResponder];
NSIndexPath *indexPath = [utableView indexPathForSelectedRow];
if (indexPath == nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請選擇要刪除的項"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc]init];
sqlList = [listData objectAtIndex:(row - 1)];
sqlService *sqlSer = [[sqlService alloc] init];
if ([sqlSer deleteTestList:sqlList]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"刪除數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
//刪除成功後重新獲取數據更新列表
listData = [sqlSer getTestList];
[utableView reloadData];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"刪除數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
[sqlList release];
[sqlSer release];
}
- (IBAction)searchValue{
if ([searchBar.text isEqualToString:@""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入要查詢數據的ID"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
else {
// int idNum = [searchBar.text intValue];
NSString *str = searchBar.text;
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer searchTestList:str];
if ([listData count] == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"sorry,未查詢到數據,請查看name是否有誤"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
[searchBar resignFirstResponder];
[utableView reloadData];
[sqlSer release];
}
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [listData count] + 1;//從第二行開始,第一行不顯示數據
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CustomIdentifier = [NSString stringWithFormat:@"cell%d",indexPath.row];
//cell不重用
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomIdentifier];
if (indexPath.row == 0)
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ( cell == nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CustomIdentifier] autorelease];
cell.backgroundColor = [UIColor clearColor];
}
if (indexPath.row > 0)
{
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc] init] ;
if (listData != nil)
sqlList = [listData objectAtIndex: (row - 1)];//讀取數據的時候也要減一行,從第二行開始
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0+40, 10, 70, 30)];
UILabel *IDLabel = [[UILabel alloc]initWithFrame:CGRectMake(90+40, 10, 70, 30)];
UILabel *valueLabel = [[UILabel alloc]initWithFrame:CGRectMake(180+40, 10, 70, 30)];
nameLabel.text = sqlList.sqlname;
IDLabel.text = sqlList.sqlText;
valueLabel.text = [NSString stringWithFormat:@"%d",sqlList.sqlID];
[cell.contentView addSubview:nameLabel];
[cell.contentView addSubview:IDLabel];
[cell.contentView addSubview:valueLabel];
[nameLabel release];
[IDLabel release];
[valueLabel release];
}
else
{
for (int i = 0; i < 3; i ++) {
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(90 * i + 40, 10, 70 , 30)];
NSArray *array = [NSArray arrayWithObjects:@"姓名",@"ID",@"電話", nil];
label.text = [array objectAtIndex:i];
label.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:label];
[label release];
}
}
return cell;
}
- (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[searchBar resignFirstResponder];
if (indexPath.row == 0) {
return nil;//讓第一行不能點擊
}
else
return indexPath;
}
@end
研究了幾天的數據庫,終於把它給搞出來了。Sqlite是ios上最常用的數據庫之一,大家還是有必要了解一下的。這是仿照網上的一個例子做的,有些部分寫的不好,我稍作了修改,以講解爲主,主要讓大家能夠明白如何修改,明白原理,達到舉一反三的目的。
先來看看效果圖
先來看看數據庫方法類,將各個操作都封裝在一個類裏面,達到代碼重用的目的,這是程序員都應該努力去實現的目標,這樣在下一次用到同樣的方法和類的時候,就可以直接使用封裝好的類,可以節約大量的時間。
先來看看.h文件
複製代碼
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#define kFilename @"testdb.db"
@class sqlTestList;
@interface sqlService : NSObject {
sqlite3 *_database;
}
@property (nonatomic) sqlite3 *_database;
-(BOOL) createTestList:(sqlite3 *)db;//創建數據庫
-(BOOL) insertTestList:(sqlTestList *)insertList;//插入數據
-(BOOL) updateTestList:(sqlTestList *)updateList;//更新數據
-(NSMutableArray*)getTestList;//獲取全部數據
- (BOOL) deleteTestList:(sqlTestList *)deletList;//刪除數據:
- (NSMutableArray*)searchTestList:(NSString*)searchString;//查詢數據庫,searchID爲要查詢數據的ID,返回數據爲查詢到的數據
@end
@interface sqlTestList : NSObject//重新定義了一個類,專門用於存儲數據
{
int sqlID;
NSString *sqlText;
NSString *sqlname;
}
@property (nonatomic) int sqlID;
@property (nonatomic, retain) NSString *sqlText;
@property (nonatomic, retain) NSString *sqlname;
@end
複製代碼
再來看看.m文件
複製代碼
//
// sqlService.m
// SQLite3Test
//
// Created by fengxiao on 11-11-28.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "sqlService.h"
@implementation sqlService
@synthesize _database;
- (id)init
{
return self;
}
- (void)dealloc
{
[super dealloc];
}
//獲取document目錄並返回數據庫目錄
- (NSString *)dataFilePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(@"=======%@",documentsDirectory);
return [documentsDirectory stringByAppendingPathComponent:@"data.db"];//這裏很神奇,可以定義成任何類型的文件,也可以不定義成.db文件,任何格式都行,定義成.sb文件都行,達到了很好的數據隱祕性
}
//創建,打開數據庫
- (BOOL)openDB {
//獲取數據庫路徑
NSString *path = [self dataFilePath];
//文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//判斷數據庫是否存在
BOOL find = [fileManager fileExistsAtPath:path];
//如果數據庫存在,則用sqlite3_open直接打開(不要擔心,如果數據庫不存在sqlite3_open會自動創建)
if (find) {
NSLog(@"Database file have already existed.");
//打開數據庫,這裏的[path UTF8String]是將NSString轉換爲C字符串,因爲SQLite3是採用可移植的C(而不是
//Objective-C)編寫的,它不知道什麼是NSString.
if(sqlite3_open([path UTF8String], &_database) != SQLITE_OK) {
//如果打開數據庫失敗則關閉數據庫
sqlite3_close(self._database);
NSLog(@"Error: open database file.");
return NO;
}
//創建一個新表
[self createTestList:self._database];
return YES;
}
//如果發現數據庫不存在則利用sqlite3_open創建數據庫(上面已經提到過),與上面相同,路徑要轉換爲C字符串
if(sqlite3_open([path UTF8String], &_database) == SQLITE_OK) {
//創建一個新表
[self createTestList:self._database];
return YES;
} else {
//如果創建並打開數據庫失敗則關閉數據庫
sqlite3_close(self._database);
NSLog(@"Error: open database file.");
return NO;
}
return NO;
}
//創建表
- (BOOL) createTestList:(sqlite3*)db {
//這句是大家熟悉的SQL語句
char *sql = "create table if not exists testTable(ID INTEGER PRIMARY KEY AUTOINCREMENT, testID int,testValue text,testName text)";// testID是列名,int 是數據類型,testValue是列名,text是數據類型,是字符串類型
sqlite3_stmt *statement;
//sqlite3_prepare_v2 接口把一條SQL語句解析到statement結構裏去. 使用該接口訪問數據庫是當前比較好的的一種方法
NSInteger sqlReturn = sqlite3_prepare_v2(_database, sql, -1, &statement, nil);
//第一個參數跟前面一樣,是個sqlite3 * 類型變量,
//第二個參數是一個 sql 語句。
//第三個參數我寫的是-1,這個參數含義是前面 sql 語句的長度。如果小於0,sqlite會自動計算它的長度(把sql語句當成以\0結尾的字符串)。
//第四個參數是sqlite3_stmt 的指針的指針。解析以後的sql語句就放在這個結構裏。
//第五個參數是錯誤信息提示,一般不用,爲nil就可以了。
//如果這個函數執行成功(返回值是 SQLITE_OK 且 statement 不爲NULL ),那麼下面就可以開始插入二進制數據。
//如果SQL語句解析出錯的話程序返回
if(sqlReturn != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement:create test table");
return NO;
}
//執行SQL語句
int success = sqlite3_step(statement);
//釋放sqlite3_stmt
sqlite3_finalize(statement);
//執行SQL語句失敗
if ( success != SQLITE_DONE) {
NSLog(@"Error: failed to dehydrate:create table test");
return NO;
}
NSLog(@"Create table 'testTable' successed.");
return YES;
}
//插入數據
-(BOOL) insertTestList:(sqlTestList *)insertList {
//先判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement;
//這個 sql 語句特別之處在於 values 裏面有個? 號。在sqlite3_prepare函數裏,?號表示一個未定的值,它的值等下才插入。
static char *sql = "INSERT INTO testTable(testID, testValue,testName) VALUES(?, ?, ?)";
int success2 = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success2 != SQLITE_OK) {
NSLog(@"Error: failed to insert:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表上面的第幾個問號,這裏將三個值綁定到三個綁定變量
sqlite3_bind_int(statement, 1, insertList.sqlID);
sqlite3_bind_text(statement, 2, [insertList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [insertList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
//執行插入語句
success2 = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果插入失敗
if (success2 == SQLITE_ERROR) {
NSLog(@"Error: failed to insert into the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//獲取數據
- (NSMutableArray*)getTestList{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10];
//判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement = nil;
//sql語句
char *sql = "SELECT testID, testValue ,testName FROM testTable";//從testTable這個表中獲取 testID, testValue ,testName,若獲取全部的話可以用*代替testID, testValue ,testName。
if (sqlite3_prepare_v2(_database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement with message:get testValue.");
return NO;
}
else {
//查詢結果集中一條一條的遍歷所有的記錄,這裏的數字對應的是列值,注意這裏的列值,跟上面sqlite3_bind_text綁定的列值不一樣!一定要分開,不然會crash,只有這一處的列號不同,注意!
while (sqlite3_step(statement) == SQLITE_ROW) {
sqlTestList* sqlList = [[sqlTestList alloc] init] ;
sqlList.sqlID = sqlite3_column_int(statement,0);
char* strText = (char*)sqlite3_column_text(statement, 1);
sqlList.sqlText = [NSString stringWithUTF8String:strText];
char *strName = (char*)sqlite3_column_text(statement, 2);
sqlList.sqlname = [NSString stringWithUTF8String:strName];
[array addObject:sqlList];
[sqlList release];
}
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
return [array retain];//定義了自動釋放的NSArray,這樣不是個好辦法,會造成內存泄露,建議大家定義局部的數組,再賦給屬性變量。
}
//更新數據
-(BOOL) updateTestList:(sqlTestList *)updateList{
if ([self openDB]) {
sqlite3_stmt *statement;//這相當一個容器,放轉化OK的sql語句
//組織SQL語句
char *sql = "update testTable set testValue = ? and testName = ? WHERE testID = ?";
//將SQL語句放入sqlite3_stmt中
int success = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success != SQLITE_OK) {
NSLog(@"Error: failed to update:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表第幾個問號。這裏只有1個問號,這是一個相對比較簡單的數據庫操作,真正的項目中會遠遠比這個複雜
//綁定text類型的數據庫數據
sqlite3_bind_text(statement, 3, [updateList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [updateList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(statement, 1, updateList.sqlID);
//執行SQL語句。這裏是更新數據庫
success = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果執行失敗
if (success == SQLITE_ERROR) {
NSLog(@"Error: failed to update the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//執行成功後依然要關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//刪除數據
- (BOOL) deleteTestList:(sqlTestList *)deletList{
if ([self openDB]) {
sqlite3_stmt *statement;
//組織SQL語句
static char *sql = "delete from testTable where testID = ? and testValue = ? and testName = ?";
//將SQL語句放入sqlite3_stmt中
int success = sqlite3_prepare_v2(_database, sql, -1, &statement, NULL);
if (success != SQLITE_OK) {
NSLog(@"Error: failed to delete:testTable");
sqlite3_close(_database);
return NO;
}
//這裏的數字1,2,3代表第幾個問號。這裏只有1個問號,這是一個相對比較簡單的數據庫操作,真正的項目中會遠遠比這個複雜
sqlite3_bind_int(statement, 1, deletList.sqlID);
sqlite3_bind_text(statement, 2, [deletList.sqlText UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [deletList.sqlname UTF8String], -1, SQLITE_TRANSIENT);
//執行SQL語句。這裏是更新數據庫
success = sqlite3_step(statement);
//釋放statement
sqlite3_finalize(statement);
//如果執行失敗
if (success == SQLITE_ERROR) {
NSLog(@"Error: failed to delete the database with message.");
//關閉數據庫
sqlite3_close(_database);
return NO;
}
//執行成功後依然要關閉數據庫
sqlite3_close(_database);
return YES;
}
return NO;
}
//查詢數據
- (NSMutableArray*)searchTestList:(NSString*)searchString{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10];
//判斷數據庫是否打開
if ([self openDB]) {
sqlite3_stmt *statement = nil;
//sql語句
NSString *querySQL = [NSString stringWithFormat:@"SELECT * from testTable where testName like \"%@\"",searchString];
const char *sql = [querySQL UTF8String];
// char *sql = "SELECT * FROM testTable WHERE testName like ?";//這裏用like代替=可以執行模糊查找,原來是"SELECT * FROM testTable WHERE testName = ?"
if (sqlite3_prepare_v2(_database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"Error: failed to prepare statement with message:search testValue.");
return NO;
} else {
sqlTestList *searchList = [[sqlTestList alloc]init];
// sqlite3_bind_int(statement, 1, searchID);
sqlite3_bind_text(statement, 3, [searchString UTF8String], -1, SQLITE_TRANSIENT);
//查詢結果集中一條一條的遍歷所有的記錄,這裏的數字對應的是列值。
while (sqlite3_step(statement) == SQLITE_ROW) {
sqlTestList* sqlList = [[sqlTestList alloc] init] ;
sqlList.sqlID = sqlite3_column_int(statement,1);
char* strText = (char*)sqlite3_column_text(statement, 2);
sqlList.sqlText = [NSString stringWithUTF8String:strText];
char *strName = (char*)sqlite3_column_text(statement, 3);
sqlList.sqlname = [NSString stringWithUTF8String:strName];
[array addObject:sqlList];
[sqlList release];
}
[searchList release];
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
return [array retain];
}
@end
@implementation sqlTestList//剛纔.h文件裏定義的類在這實現
@synthesize sqlID;
@synthesize sqlText;
@synthesize sqlname;
-(id) init
{
sqlID = 0;
sqlText = @"";
sqlname = @"";
return self;
};
-(void) dealloc
{
if ((sqlText != nil) && (sqlname != nil)) {
[sqlText release];
[sqlname release];
}
[super dealloc];
}
@end
複製代碼
這就是封裝好的類,可以重用哦!
下面是添加數據頁面
這也是一個類,來看.h文件
複製代碼
#import <UIKit/UIKit.h>
#import "sqlService.h"
@interface operateSqlViewController : UIViewController {
UITextField *idValue;
UITextField *textValue;
UITextField *textName;
int oprateType;//區分數據插入與更新
sqlTestList *sqlValue;
}
@property (nonatomic, retain) IBOutlet UITextField *idValue;
@property (nonatomic, retain) IBOutlet UITextField *textValue;
@property (nonatomic, retain) IBOutlet UITextField *textName;
@property (nonatomic, retain) sqlTestList *sqlValue;
@property (nonatomic) int oprateType;
@end
複製代碼
再來看看.m文件
複製代碼
#import "operateSqlViewController.h"
@implementation operateSqlViewController
@synthesize idValue;
@synthesize textValue;
@synthesize oprateType;
@synthesize sqlValue;
@synthesize textName;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidLoad{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:@"返回"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(dismiss:)];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithTitle:@"保存"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(saveValue:)];
[[self navigationItem] setLeftBarButtonItem:backButton];
[[self navigationItem] setRightBarButtonItem:saveButton];
[backButton release];
[saveButton release];
if (oprateType == 0) {
[self.navigationItem setTitle:@"數據插入"];
}
else if(oprateType == 1){
[self.navigationItem setTitle:@"數據更新"];
idValue.text = [NSString stringWithFormat:@"%d", sqlValue.sqlID];
textValue.text = sqlValue.sqlText;
textName.text = sqlValue.sqlname;
}
}
- (void)viewDidUnload {
idValue = nil;
textValue = nil;
textName = nil;
sqlValue = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[idValue release];
[textValue release];
[sqlValue release];
[textName release];
[super dealloc];
}
- (void)dismiss:(id)sender{
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
- (void)saveValue:(id)sender{
if (idValue.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入ID"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
if (textValue.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入電話"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
if (textName.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入姓名"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
//初始化數據庫
sqlService *sqlSer = [[sqlService alloc] init];
//數據庫插入
if (oprateType == 0) {
sqlTestList *sqlInsert = [[sqlTestList alloc]init];
sqlInsert.sqlID = [idValue.text intValue];
sqlInsert.sqlText = textValue.text;
sqlInsert.sqlname = textName.text;
//調用封裝好的數據庫插入函數
if ([sqlSer insertTestList:sqlInsert]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"插入數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"插入數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[sqlInsert release];
}
//數據庫更新
if(oprateType == 1){
sqlTestList *newValue = [[sqlTestList alloc]init];
newValue.sqlID = [idValue.text intValue];
newValue.sqlText = textValue.text;
newValue.sqlname = textName.text;
//調用封裝好的更新數據庫函數
if ([sqlSer updateTestList:newValue]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"更新數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"更新數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[newValue release];
}
}
@end
複製代碼
代碼寫的有些囉嗦,不過不難容易看懂,不多解釋了,要在xib文件中添加3個UITextField和ULabel,要記得連線。
在主界面的.h文件
複製代碼
#import <UIKit/UIKit.h>
#import "sqlService.h"
@interface SQLite3TestViewController : UIViewController<UITableViewDelegate,UITableViewDataSource> {
UITableView *utableView;
NSArray *listData;
UISearchBar *searchBar;//搜索欄
}
@property (nonatomic, retain) IBOutlet UITableView *utableView;
@property (nonatomic, retain) IBOutlet UISearchBar *searchBar;
@property (nonatomic, retain) NSArray *listData;
- (IBAction)insertValue;
- (IBAction)updateValue;
- (IBAction)getAllValue;
- (IBAction)deleteValue;
- (IBAction)searchValue;
@end
複製代碼
.m文件
複製代碼
//
// SQLite3TestViewController.m
// SQLite3Test
//
// Created by fengxiao on 11-11-28.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "SQLite3TestViewController.h"
#import "operateSqlViewController.h"
@implementation SQLite3TestViewController
@synthesize utableView;
@synthesize listData;
@synthesize searchBar;
- (void)viewDidLoad{
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];//先初始化那個專門用於存數據的類,才調用類獲取數據的方法
}
- (void)viewDidAppear:(BOOL)animated{//在這裏寫是爲了等待時間縮短一點,數據如果很多的,在這裏寫可以讓數據提前加載
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];
[sqlSer release];
[utableView reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
utableView = nil;
listData = nil;
searchBar = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[utableView release];
[listData release];
[searchBar release];
[super dealloc];
}
- (IBAction)insertValue{
[searchBar resignFirstResponder];//觸發這個insertValue方法時隱藏鍵盤
operateSqlViewController *operateController = [[operateSqlViewController alloc] init ];
UINavigationController *theNavController = [[UINavigationController alloc]
initWithRootViewController:operateController];//這裏如果不初始化一個UINavigationController類的對象來存放operateSqlViewController類的UIViewController,就不會有最上面的導航欄了。
operateController.oprateType = 0;//optrateType爲0時爲數據插入
[operateController release];
theNavController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:theNavController animated:YES];
[theNavController release];
}
- (IBAction)updateValue{
[searchBar resignFirstResponder];
NSIndexPath *indexPath = [utableView indexPathForSelectedRow];
if (indexPath == nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請選擇要更新的項"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc]init];
sqlList = [listData objectAtIndex:(row - 1)];//在這裏面獲取點擊的行,因爲table的第一行沒顯示數據,所以這裏要減1。
operateSqlViewController *operateController = [[operateSqlViewController alloc] init ];
UINavigationController *theNavController = [[UINavigationController alloc]
initWithRootViewController:operateController];
operateController.oprateType = 1;//optrateType爲1時爲數據更新
operateController.sqlValue = sqlList;
theNavController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:theNavController animated:YES];
[sqlList release];
[operateController release];
[theNavController release];
}
- (IBAction)getAllValue{
[searchBar resignFirstResponder];
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer getTestList];
[utableView reloadData];
[sqlSer release];
}
- (IBAction)deleteValue{
[searchBar resignFirstResponder];
NSIndexPath *indexPath = [utableView indexPathForSelectedRow];
if (indexPath == nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請選擇要刪除的項"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc]init];
sqlList = [listData objectAtIndex:(row - 1)];
sqlService *sqlSer = [[sqlService alloc] init];
if ([sqlSer deleteTestList:sqlList]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"刪除數據成功"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
//刪除成功後重新獲取數據更新列表
listData = [sqlSer getTestList];
[utableView reloadData];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"刪除數據失敗"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
[sqlList release];
[sqlSer release];
}
- (IBAction)searchValue{
if ([searchBar.text isEqualToString:@""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"請輸入要查詢數據的ID"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
else {
// int idNum = [searchBar.text intValue];
NSString *str = searchBar.text;
sqlService *sqlSer = [[sqlService alloc] init];
listData = [sqlSer searchTestList:str];
if ([listData count] == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"sorry,未查詢到數據,請查看name是否有誤"
delegate:self
cancelButtonTitle:@"好"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
[searchBar resignFirstResponder];
[utableView reloadData];
[sqlSer release];
}
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [listData count] + 1;//從第二行開始,第一行不顯示數據
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CustomIdentifier = [NSString stringWithFormat:@"cell%d",indexPath.row];
//cell不重用
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomIdentifier];
if (indexPath.row == 0)
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ( cell == nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CustomIdentifier] autorelease];
cell.backgroundColor = [UIColor clearColor];
}
if (indexPath.row > 0)
{
NSUInteger row = [indexPath row];
sqlTestList *sqlList = [[sqlTestList alloc] init] ;
if (listData != nil)
sqlList = [listData objectAtIndex: (row - 1)];//讀取數據的時候也要減一行,從第二行開始
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0+40, 10, 70, 30)];
UILabel *IDLabel = [[UILabel alloc]initWithFrame:CGRectMake(90+40, 10, 70, 30)];
UILabel *valueLabel = [[UILabel alloc]initWithFrame:CGRectMake(180+40, 10, 70, 30)];
nameLabel.text = sqlList.sqlname;
IDLabel.text = sqlList.sqlText;
valueLabel.text = [NSString stringWithFormat:@"%d",sqlList.sqlID];
[cell.contentView addSubview:nameLabel];
[cell.contentView addSubview:IDLabel];
[cell.contentView addSubview:valueLabel];
[nameLabel release];
[IDLabel release];
[valueLabel release];
}
else
{
for (int i = 0; i < 3; i ++) {
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(90 * i + 40, 10, 70 , 30)];
NSArray *array = [NSArray arrayWithObjects:@"姓名",@"ID",@"電話", nil];
label.text = [array objectAtIndex:i];
label.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:label];
[label release];
}
}
return cell;
}
- (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[searchBar resignFirstResponder];
if (indexPath.row == 0) {
return nil;//讓第一行不能點擊
}
else
return indexPath;
}
@end