sqlite3 的增删查找

前端之家收集整理的这篇文章主要介绍了sqlite3 的增删查找前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

 研究了几天的数据库,终于把它给搞出来了。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)  sqlID;
@property (nonatomic,retain) NSString *sqlText;
@property (nonatomic,0)">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.); NO; } 创建一个新表 [self createTestList:self._database]; YES; } 如果发现数据库不存在则利用sqlite3_open创建数据库(上面已经提到过),与上面相同,路径要转换为C字符串 sqlITE_OK) { [self createTestList:self._database]; YES; } else { 如果创建并打开数据库失败则关闭数据库 sqlite3_close(self._database); NSLog(); NO; } 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 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 NO; } NSLog(Create table 'testTable' successed.); YES; } 插入数据 -(BOOL) insertTestList:(sqlTestList *)insertList { 先判断数据库是否打开 ([self openDB]) { sqlite3_stmt *statement; 这个 sql 语句特别之处在于 values 里面有个? 号。在sqlite3_prepare函数里,?号表示一个未定的值,它的值等下才插入。 static INSERT INTO testTable(testID,testValue,testName) VALUES(?,?,?); int success2 = sqlite3_prepare_v2(_database,NULL); if (success2 != sqlITE_OK) { NSLog(Error: Failed to insert:testTable); sqlite3_close(_database); 这里的数字1,2,3代表上面的第几个问号,这里将三个值绑定到三个绑定变量 sqlite3_bind_int(statement,1sqlID); sqlite3_bind_text(statement,2,[insertList.sqlText UTF8String],sqlITE_TRANSIENT); sqlite3_bind_text(statement,128)">3,[insertList.sqlname UTF8String],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); NO; } sqlite3_close(_database); 获取数据 - (NSMutableArray*)getTestList{ NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; 判断数据库是否打开 ([self openDB]) { sqlite3_stmt *statement = nil; sql语句 SELECT testID,testName FROM testTable从testTable这个表中获取 testID,testName,若获取全部的话可以用*代替testID,testName。 if (sqlite3_prepare_v2(_database,&statement,NULL) !=Error: Failed to prepare statement with message:get testValue. { //查询结果集中一条一条的遍历所有的记录,这里的数字对应的是列值,注意这里的列值,跟上面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,0)">1); sqlList.sqlText = [NSString stringWithUTF8String:strText]; char *strName = (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{ ([self openDB]) { sqlite3_stmt *statement;这相当一个容器,放转化OK的sql语句 组织sql语句 update testTable set testValue = ? and testName = ? WHERE testID = ?sql语句放入sqlite3_stmt中 int success = sqlite3_prepare_v2(_database,255)">if (success !=Error: Failed to update:testTable这里的数字1,2,3代表第几个问号。这里只有1个问号,这是一个相对比较简单的数据库操作,真正的项目中会远远比这个复杂 绑定text类型的数据库数据 sqlite3_bind_text(statement,[updateList.sqlname UTF8String],[updateList.sqlText UTF8String],sqlITE_TRANSIENT); sqlite3_bind_int(statement,updateList.sqlID); 执行sql语句。这里是更新数据库 success =如果执行失败 if (success ==Error: Failed to update the database with message.执行成功后依然要关闭数据库 NO; } 删除数据 - (BOOL) deleteTestList:(sqlTestList *)deletList{ statement; delete from testTable where testID = ? and testValue = ? and testName = ?; Error: Failed to delete:testTable这里的数字1,2,3代表第几个问号。这里只有1个问号,这是一个相对比较简单的数据库操作,真正的项目中会远远比这个复杂 sqlite3_bind_int(statement,deletList.sqlID); sqlite3_bind_text(statement,[deletList.sqlText UTF8String],[deletList.sqlname UTF8String],sqlITE_TRANSIENT); Error: Failed to delete the database with message. NO; } 查询数据 - (NSMutableArray*)searchTestList:(NSString*)searchString{ NSMutableArray *array = [NSMutableArray arrayWithCapacity:sql语句 NSString *querysql = [NSString stringWithFormat:SELECT * from testTable where testName like \"%@\""const char *sql = [querysql UTF8String]; char *sql = "SELECT * FROM testTable WHERE testName like ?";这里用like代替=可以执行模糊查找,原来是"SELECT * FROM testTable WHERE testName = ?" Error: Failed to prepare statement with message:search testValue. NO; } { sqlTestList *searchList = [[sqlTestList alloc]init]; sqlite3_bind_int(statement,1,searchID); sqlite3_bind_text(statement,[searchString UTF8String],sqlITE_TRANSIENT); 查询结果集中一条一条的遍历所有的记录,这里的数字对应的是列值。 [[sqlTestList alloc] init] ; sqlList.sqlID = sqlite3_column_int(statement,128)">23 [NSString stringWithUTF8String:strName]; [array addObject:sqlList]; [sqlList release]; } [searchList release]; } sqlite3_finalize(statement); sqlite3_close(_database); } [array retain]; } @end @implementation sqlTestList刚才.h文件里定义的类在这实现 sqlID; sqlText; sqlname; -() init { sqlID = ; sqlText = @""; sqlname = ; self; }; -() dealloc { if ((sqlText != nil) && (sqlname != nil)) { [sqlText release]; [sqlname release]; } [super dealloc]; } 这就是封装好的类,可以重用哦!

下面是添加数据页面

这也是一个类,来看.h文件

#import <UIKit/UIKit.h> " operatesqlViewController : UIViewController { UITextField *idValue; UITextField *textValue; UITextField *textName; int oprateType;区分数据插入与更新 sqlTestList *sqlValue; } @property (nonatomic,retain) IBOutlet UITextField *idValue; @property (nonatomic,0)">textValue; @property (nonatomic,0)">textName; @property (nonatomic,retain) sqlTestList *sqlValue; @property (nonatomic) oprateType; operatesqlViewController.h operatesqlViewController idValue; textValue; oprateType; sqlValue; textName; - ()didReceiveMemoryWarning { Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; Release any cached data,images,etc. that aren't in use. } - ()viewDidLoad{ UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:返回 style:UIBarButtonItemStyleBordered target:self action:@selector(dismiss:)]; UIBarButtonItem *saveButton =保存 style:UIBarButtonItemStyleBordered target:self action:@selector(saveValue:)]; [[self navigationItem] setLeftBarButtonItem:backButton]; [[self navigationItem] setRightBarButtonItem:saveButton]; [backButton release]; [saveButton release]; if (oprateType == ) { [self.navigationItem setTitle:数据插入]; } else if(oprateType == ){ [self.navigationItem setTitle:数据更新]; idValue.text = [NSString stringWithFormat:%dsqlValue.sqlID]; textValue.text = sqlValue.sqlText; textName.text = sqlValue.sqlname; } } - ()viewDidUnload { idValue = nil; textValue = nil; textName = nil; sqlValue = nil; [super viewDidUnload]; Release any retained subviews of the main view. e.g. self.myOutlet = nil; } - ()dealloc { [idValue release]; [textValue release]; [sqlValue release]; [textName release]; [super dealloc]; } - (void)dismiss:()sender{ [[self parentViewController] dismissModalViewControllerAnimated:YES]; } - (void)saveValue:()sender{ if (idValue.text.length == ) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:提示 message:请输入ID" delegate:self cancelButtonTitle: otherButtonTitles:nil]; [alert show]; [alert release]; ; } if (textValue.text.length == ) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle: message:请输入电话" :self cancelButtonTitle: otherButtonTitles:nil]; [alert show]; [alert release]; if (textName.text.length == 请输入姓名; } 初始化数据库 sqlService *sqlSer = [[sqlService alloc] init]; 数据库插入 ) { sqlTestList *sqlInsert = [[sqlTestList alloc]init]; sqlInsert.sqlID = [idValue.text intValue]; sqlInsert.sqlText = textValue.text; sqlInsert.sqlname = textName.text; 调用封装好的数据库插入函数 ([sqlSer insertTestList:sqlInsert]) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:插入数据成功 otherButtonTitles:nil]; [alert show]; [alert release]; } { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:插入数据失败 otherButtonTitles:nil]; [alert show]; [alert release]; } [sqlInsert release]; } 数据库更新 ){ sqlTestList *newValue = [[sqlTestList alloc]init]; newValue.sqlID = [idValue.text intValue]; newValue.sqlText = textValue.text; newValue.sqlname =调用封装好的更新数据库函数 ([sqlSer updateTestList:newValue]) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:更新数据成功更新数据失败 otherButtonTitles:nil]; [alert show]; [alert release]; } [newValue release]; } } 代码写的有些啰嗦,不过不难容易看懂,不多解释了,要在xib文件添加3个UITextField和ULabel,要记得连线。

在主界面的.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; .m文件

  sqlite3TestViewController.m
sqlite3TestViewController.h sqlite3TestViewController
 utableView;
 listData;
 searchBar;


- ()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];
}

- ()viewDidUnload {
    utableView = nil;
    listData = nil;
    searchBar =)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:请选择要更新的项;
    }
    
    NSUInteger row = [indexPath row];
    sqlTestList *sqlList = [[sqlTestList alloc]init];
    sqlList = [listData objectAtIndex:(row - 1)];在这里面获取点击的行,因为table的第一行没显示数据,所以这里要减1。
        
    operatesqlViewController *operateController = [[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 = [sqlSer getTestList];
    [utableView reloadData];
    [sqlSer release];
    
}
- (IBAction)deleteValue{
    
    [searchBar resignFirstResponder];
    
    NSIndexPath *indexPath = [utableView  indexPathForSelectedRow];
    
    请选择要删除的项)];
    
    sqlService *sqlSer = [[sqlService alloc] init];
    
      ([sqlSer deleteTestList:sqlList]) {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle: 
                                                         message:删除数据成功" 
                                                        :self
                                               cancelButtonTitle: 
                                               otherButtonTitles:nil];
         [alert show];
         [alert release];
         
         删除成功后重新获取数据更新列表
         listData = [sqlSer getTestList];
         [utableView reloadData];

     }
     {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:删除数据失败;
    }
    
    [sqlList release];
    [sqlSer release];
}
- (IBAction)searchValue{
    
    if ([searchBar.text isEqualToString:]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:请输入要查询数据的ID {
        int idNum = [searchBar.text intValue];
        NSString *str = searchBar.text;
        sqlService *sqlSer = [[sqlService alloc] init];
        listData = [sqlSer searchTestList:str];

        if ([listData  count] == sorry,未查询到数据,请查看name是否有误 
                                                  otherButtonTitles:nil];
            [alert show];
            [alert release];
            ;
        }
        [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] + 从第二行开始,第一行不显示数据
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    NSString *CustomIdentifier =  [NSString stringWithFormat:cell%dcell不重用
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomIdentifier];
    if (indexPath.row == )
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    if ( cell == nil ) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 
                                         reuseIdentifier:CustomIdentifier] autorelease];
        cell.backgroundColor = [UIColor clearColor];
            }
    if (indexPath.row > )
    {
        NSUInteger row = [indexPath row];
        sqlTestList *sqlList = [[sqlTestList alloc] init] ;
        
        if (listData != nil)
        sqlList = [listData objectAtIndex: (row - 读取数据的时候也要减一行,从第二行开始
        
        UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0+40,128)">10,128)">70,128)">30)];
        UILabel *IDLabel = [[UILabel alloc]initWithFrame:CGRectMake(90+)];
        UILabel *valueLabel = [[UILabel alloc]initWithFrame:CGRectMake(180+)];
        nameLabel.text = sqlList.sqlname;
        IDLabel.text = sqlList.sqlText;
        valueLabel.text = [NSString stringWithFormat:sqlList.sqlID];
        [cell.contentView addSubview:nameLabel];
        [cell.contentView addSubview:IDLabel];
        [cell.contentView addSubview:valueLabel];
        [nameLabel release];
        [IDLabel release];
        [valueLabel release];
    }
     
        {
        for (int i = 0; i < 3; i ++) {
            UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(90 * i + )];
            NSArray *array = [NSArray arrayWithObjects:姓名",0)">ID电话 [array objectAtIndex:i];
            label.backgroundColor = [UIColor clearColor];
            [cell.contentView addSubview:label];
            [label release];
        }
    }
     cell;
}

- (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [searchBar resignFirstResponder];
    ) {
        return nil;让第一行不能点击
    }
    else
         indexPath;
}

@end
原文链接:https://www.f2er.com/sqlite/200605.html

猜你在找的Sqlite相关文章