iOS Sqlite数据库 iOS 多媒体 iOS CoreData 编程 iOS Sqlite数据库 本章内容概述 Sqlite 简介 在命令行使用Sqlite 使用Sqlite实现表的增、删、查、改 Sqlite和UITableView结合使用 22.1 Sqlite 简介 sqlite是一个开源的嵌入式数据库引擎,广泛应用在嵌入式设备操作系统中,例如,早期的Symbian、android、ios等系统中。 Sqlite的官方站点是:http://sqlite.org/index.html ,更多详细用法可以从该站点找到。标准的sql语言在sqlite数据库中都支持。这里我们需要了解的是sqlite中的数据类型。 表22.1 sqlite数据类型 名称 描述 NULL 空值 INTEGER 带符号的整型,具体取决有存入数字的范围大小 REAL 浮点数字,存储为8-byte IEEE浮点数 TEXT 字符串文本 BLOB 二进制对象 22.2 在命令行使用Sqlite Mac提供了对sqlite的支持,可以通过命令行的方法来创建数据库和表。可以在命令行通过sql语句来操作数据库和表。 在Mac系统中打开Terminal终端,使用sqlite3命令来打开或创建数据库。例如,在终端输入sqlite3 test.db 就可以在当前目录下创建一个test.db数据库。我们通过下面步骤来创建一个数据库test.db 并在该库中创建一个UserTbl数据表,并对该并进行增、删、查、改等操作。 打开终端输入如下命令,可以创建一个数据库。 sqlite3 test.db 如上图所示,当前的提示符变成了sqlite,这里我们可以输入.help需求帮助。 这些命令很多,常用的有查看当前目录下的数据库.databases,查看当前库下面的表.tables以及查看表结构.schema tablename等命令。 下面我们来在test.db数据库中创建一个UserTbl表。 create table UserTbl(uid integer primary key autoincrement,username text,pwd text); 这里uid是主键并且是自动增加的。 下面通过insert into sql语言插入几条记录。 insert into UserTbl(username,pwd)values(`tom`,`123`); insert into UserTbl(username,pwd)values(`kite`,`456`); 使用下面sql语言可以查询到uid=1的用户。 select username,pwd from UserTbl where uid=1; 下面是删除uid为1的用户。 delete from UserTbl where uid=1; 下面是修改uid为2的用户名称。 update UserTbl set username=`big kite`; where uid=2; 以上是sqlite命令行操作的常用sql语言,这些语句在实际的项目测试和项目开发中都能应用得到。 22.3 使用Sqlite实现表的增、删、查、改 在上一节我们讲述了如何在命令行进行数据库和表的操作,实际开发当中我们更多的是通过程序api接口来实现表的增、删、查、改等操作。本节我们将通过程序的方式实现sqlite的增、删、查、改。 在程序中使用sqlite数据库需要导入sqlite数据库的动态库libsqlite3.dylib。选择项目名称,在右边的"TARGET"中的"Build Phases"中选择"Link Binary With Libraries"中选择"+"添加。如下图所示。 并且在程序中需要导入#import "/usr/include/sqlite3.h"头文件。 Sqlite数据库编程中,使用了一组以sqlite3打头的函数,来实现数据库和表的操作。通过下面表格我们先来认识一下这些函数。 表22.2 sqlite数据库函数 名称 描述 sqlite3 表示数据库对象 sqlite3_open 打开数据库 sqlite3_close 关闭数据库 sqlite3_exec 执行sql语句,例如,创建表 sqlite3_prepare_v2 预定义语句 sqlite3_bind_xxx 绑定数据 sqlite3_step 执行预定义语句 sqlite3_column_text 获得某列数据 sqlite数据库编程的基本步骤是: 创建或者打开库。 创建表 增、删、查、改操作。 关闭库。 下面通过一个案例来演示如何使用sqlite数据库,实现步骤如下所示: 创建一个项目,添加libsqlite3.dylib库。 在xib文件中添加5个按钮,分别实现创建库、创建表、插入、删除、更新和查询操作。 创建一个类Person和数据库中的Person表映射。 #import <Foundation/Foundation.h> @interface Person : NSObject // id @property(nonatomic)int pid; // 姓名 @property(nonatomic,retain)NSString *name; // 密码 @property(nonatomic,retain)NSString *pwd; @end 创建一个数据库工具类DbUtil.h 在该类中实现增、删、查、改操作。 #import <Foundation/Foundation.h> // 导入头文件 #import "/usr/include/sqlite3.h" #import "Person.h" // 定义数据库名称 #define kDbName @"test.db" @interface DbUtil : NSObject // 获得数据库文件路径方法 -(NSString*)getPath; // 打开库 -(sqlite3*)open; // 关闭库 -(void)close:(sqlite3*)db; // 创建表 -(void)createTable:(sqlite3*)db; // 插入 -(void)insert:(Person*)per; // 删除 -(void)del:(int)pid; // 更新 -(void)update:(Person*)per; // 查询 -(NSMutableArray*)query; // 根据id查询 -(Person*)findPerson:(int)pid; @end 获得数据库保存路径,获得程序文档路径,并附加数据库名称即可。 // 获得数据库保存路径 -(NSString*)getPath{ // 获得文件路径 NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *path = [docPaths objectAtIndex:0]; // 创建数据库路径 path = [path stringByAppendingPathComponent:kDbName]; return path; } 打开数据库,声明sqlite3数据库对象,调用sqlite3_open函数,传递数据库文件路径和sqlite3二级指针打开库。 // 打开数据库 -(sqlite3*)open{ // 声明数据库 sqlite3 *database; // 获得数据库路径 NSString *path = [self getPath]; NSLog(@"%@",path); // 打开库 NSInteger result = sqlite3\_open([path UTF8String], &database); if (result==SQLITE\_OK) { // 返回数据库 return database; } return nil; } 关闭库,调用sqlite3_close函数,传递sqlite3对象关闭数据库。 // 关闭库 -(void)close:(sqlite3 *)db{ if(db!=nil) sqlite3\_close(db); } 创建表方法,准备创建表的sql语句,调用sqlite3_exec方法来执行。 // 创建表 -(void)createTable:(sqlite3 *)db{ // 创建表sql语句 char *sql = "create table PerTbl (pid integer primary key autoincrement, name text,pwd text) "; // 执行sql语句创建表 int result = sqlite3\_exec(db, sql, 0, nil, nil); // 判断是否创建成功 if (result==SQLITE\_OK) { NSLog(@"%@",@"create ok."); }else{ NSLog(@"%@",@"create fail."); } } 插入数据,插入数据需要打开数据库,准备sql语句,并准备预定义语句,绑定数据,并执行sql语句。 // 插入数据 -(void)insert:(Person *)per{ // 打开数据库 sqlite3 *db = [self open]; // 插入sql语句 char *sql = "insert into PerTbl(name,pwd)values(?,?) "; // 预定义语句 sqlite3\_stmt *stmt; //准备预定义语句 if(sqlite3\_prepare\_v2(db, sql , -1, &stmt, nil)==SQLITE\_OK){ // 绑定数据 sqlite3\_bind\_text(stmt, 1, "tom", -1, nil); sqlite3\_bind\_text(stmt, 2, "123", -1, nil); } // 执行sql if(sqlite3\_step(stmt)==SQLITE\_DONE){ NSLog(@"%@",@"insert ok."); }else{ NSLog(@"%@",@"insert fail."); } // 释放语句 sqlite3\_finalize(stmt); // 关闭数据库 [self close:db]; } 删除数据的流程和插入数据的流程类似,这里不多赘述。 // 删除数据 -(void)del:(int)pid{ // 打开数据库 sqlite3 *db = [self open]; // 准备sql char *sql = "delete from PerTbl where pid=? "; // 定义预定义语句 sqlite3\_stmt *stmt; // 准备预定义语句 if(sqlite3\_prepare\_v2(db, sql , -1, &stmt, nil)==SQLITE\_OK){ // 绑定数据 sqlite3\_bind\_int(stmt, 1, pid); } // 执行语句 if(sqlite3\_step(stmt)==SQLITE\_DONE){ NSLog(@"%@",@"del ok."); }else{ NSLog(@"%@",@"del fail."); } // 是否资源 sqlite3\_finalize(stmt); // 关闭数据库 [self close:db]; } 更新数据。 // 更新 -(void)update:(Person *)per{ // 打开库 sqlite3 *db = [self open]; // sql char *sql = "update PerTbl set name =?,pwd=? where pid=?"; // 声明预定义语句 sqlite3\_stmt *stmt; // 准备预定义 if(sqlite3\_prepare\_v2(db, sql , -1, &stmt, nil)==SQLITE\_OK){ // 绑定数据 sqlite3\_bind\_text(stmt, 1, [[per name] UTF8String], -1, nil); sqlite3\_bind\_text(stmt, 2, [[per pwd]UTF8String], -1, nil); sqlite3\_bind\_int(stmt, 3, [per pid]); } // 执行预定义语句 if(sqlite3\_step(stmt)==SQLITE\_DONE){ NSLog(@"%@",@"update ok."); }else{ NSLog(@"%@",@"update fail."); } // 释放资源 sqlite3\_finalize(stmt); // 关闭数据库 [self close:db]; } 查询数据,查询流程和插入、删除类似,不同的地方是循环调用sqlite3_step方法获得数据,并使用sqlite3_column_xxx方法获得列数据。 // 查询 -(NSMutableArray*)query{ // 打开数据库 sqlite3 *db = [self open]; // 查询sql char *sql = " select pid,name,pwd from PerTbl "; // 预定义语句 sqlite3\_stmt *stmt; // 可变数组 NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; // 准备预定义语句 if(sqlite3\_prepare\_v2(db, sql , -1, &stmt, nil)==SQLITE\_OK){ // 循环获得数据 while (sqlite3\_step(stmt)==SQLITE\_ROW) { // 获得第一列数据 int pid = sqlite3\_column\_int(stmt, 0); // 第二列 const char *name = (char*)sqlite3\_column\_text(stmt, 1); // 第三列 char *pwd = (char*)sqlite3\_column\_text(stmt, 2); // 实例化Person Person *per = [[Person alloc]init]; // 赋值 [per setPid:pid]; [per setPwd:[NSString stringWithUTF8String:pwd]]; [per setName:[NSString stringWithUTF8String:name]]; // 添加到数组 [array addObject:per]; } } // 是否资源 sqlite3\_finalize(stmt); // 关闭数据库 [self close:db]; return array; } 以上是数据的处理方法,下面在界面按钮的事件方法中调用上述方法实现数据库的维护。 // 创建表 - (IBAction)create:(id)sender { sqlite3 *db; db = [util open]; [util createTable:db]; [util close:db]; } // 插入数据 - (IBAction)insert:(id)sender { Person *per = [[Person alloc]init]; [per setPid:1]; [per setName:@"tom"]; [per setPwd:@"123"]; [util insert:per]; } // 删除数据 - (IBAction)delete2:(id)sender{ [util del:1]; } // 更新数据 - (IBAction)update:(id)sender { Person *per = [[Person alloc]init]; [per setPid:3]; [per setName:@"tom3"]; [per setPwd:@"333"]; [util update:per]; } // 查询数据 - (IBAction)query:(id)sender { [util query]; } 程序运行结果如下所示。 22.4 Sqlite和UITableView结合使用 在上一节我们只是孤立、枯燥的来演示了sqlite数据库的用法,实现项目当中数据库中的数据需要漂亮的界面加以维护的,本节将sqlite数据库和UITableView结合在一起来讲述它们的组合应用。 本节我们将在上一节的基础上创建如下图所示的程序。导航栏中有添加和删除按钮,点击添加按钮弹出对话框实现添加,点击删除按钮删除数据,表格视图显示当前数据库中的数据。 该程序的实现步骤如下: 创建一个项目,在界面上添加UITableView。 在.h控制器头文件中实现表视图数据源协议和代理协议,以及警告视图代理协议,表格视图属性、数据源属性、数据库工具类属性和导航按钮属性。 #import <UIKit/UIKit.h> #import "DbUtil.h" // 实现表视图数据源协议和代理协议,以及警告视图代理协议 @interface AmakerViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate> // 表格视图属性 @property (strong, nonatomic) IBOutlet UITableView *tableView; // 数据源属性 @property(nonatomic,strong)NSMutableArray *dataSource; // 数据库工具类属性 @property(nonatomic,strong)DbUtil *util; // 导航按钮属性 @property(nonatomic,strong)UIBarButtonItem *addItem,*delItem; @end 在控制器.m的实现文件中的viewDidLoad方法中,实例化数据库工具类,创建表,查询数据库数据并赋值给数据源,实例化导航按钮并绑定插入和删除方法。 - (void)viewDidLoad { [super viewDidLoad]; // 实例化数据库工具类 self.util = [[DbUtil alloc]init]; // 创建表 [self.util createTable]; // 查询数据 self.dataSource = [self.util query]; // 添加按钮 self.addItem = [[UIBarButtonItem alloc]initWithTitle:@"Add" style:UIBarButtonItemStylePlain target:self action:@selector(add)]; self.navigationItem.rightBarButtonItem = self.addItem; // 删除按钮 self.delItem = [[UIBarButtonItem alloc]initWithTitle:@"Del" style:UIBarButtonItemStylePlain target:self action:@selector(del)]; self.navigationItem.leftBarButtonItem = self.delItem; } 点击导航栏的添加按钮显示添加对话框。 // 使用对话框添加 -(void)add{ UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Add" message:nil delegate:self cancelButtonTitle:@"Add" otherButtonTitles:@"Cancel", nil]; alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput; [alert show]; } 点击删除按钮更改表格视图的编辑模式。 // 删除方法,更改表格的编辑状态 -(void)del{ BOOL result = [self.tableView isEditing]; if (result) { [self.tableView setEditing:NO]; self.delItem.title=@"Del"; }else{ [self.tableView setEditing:YES]; self.delItem.title = @"Done"; } } 在对话框的代理方法中实现添加数据。获得输入框的数据,根据该数据创建Person对象,调用数据库工具类添加数据,并重新加载表。 // 添加数据 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ UITextField *nameTf = [alertView textFieldAtIndex:0]; UITextField *pwdTf = [alertView textFieldAtIndex:1]; NSString *name = nameTf.text; NSString *pwd = pwdTf.text; Person *p = [[Person alloc]init]; p.name = name; p.pwd = pwd; nameTf.text=@""; pwdTf.text=@""; [self.util insert:p]; [self.tableView reloadData]; } 实现表格视图的代理方法,查询数据库作为表格行返回值。 // 表格行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ self.dataSource = [self.util query]; return [self.dataSource count]; } 实现表格视图代理的获得表单元方法,将数据库数据显示在表格中。 // 表格单元 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *cid = @"cid"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cid]; if (cell==nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cid]; } Person *p = [self.dataSource objectAtIndex:[indexPath row]]; cell.textLabel.text = p.name; cell.detailTextLabel.text = p.pwd; return cell; } iOS 多媒体 iOS CoreData 编程