IOS使用项目中的本地数据库简单操作
IOS使用项目中的本地数据库简单操作
之前在安卓中做过项目通过本地的SQLITE数据库的项目,现在有了iphone,于是也想把它转到ios上
主要是对项目中的sqlite数据库文件的使用,其中对数据库中的操作用的是FMDBQueue,还有就是对网络图片的浏览,对网络图片的浏览用的是SDWebImage框架。
经过一天的学习与操作,终于完成了。主要步骤如下:
1.加入第三方库
1.1.加入FMDBQueue
FMDBQueue库的加入:先去网上搜一下FMDBQueue的下载地址,先把它下载下来,然后将代码放到项目中就要以了。
由于其FMDBQueue依赖于系统自带的libsqlite3.dylib,所以也得要把libsqlite3.dylib添加到项目中来,不然会出问题的。
1.2.加入SDWebImage
SDWebImage的加入方式和FMDBQueue差不多,也是先到网上去搜一个下载地址,把它下载下来后,将代码复制到项目中就可以了。
2.数据库操作
2.1将数据库从资源文件拷贝到项目中
由于数据库用的是本地的sqlite数据库,所以得先把数据库复制到项目中。移动方法很简单,找到准备好的数据库,将它添加到项目中就可以了。
2.2数据库操作代码
数据库和相关的jar包都弄进来了,就开始开干了吧。
首先在项目获取到数据库,面向对象嘛,谁获取到了对象,谁就可以操作对象嘛。
主要代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// // 0.获得沙盒中的数据库文件名
NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"stu.db"];
NSError *error;
NSBundle *bundle = [NSBundle mainBundle];
NSString *filenameAgo = [bundle pathForResource:@"stu" ofType:@"db"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager copyItemAtPath:filenameAgo toPath:filename error:&error];
NSLog(@"filenameAgo>>>>%@",filenameAgo);
NSLog(@"filename%@",filename);
// 1.创建数据库队列
self.queue = [FMDatabaseQueue databaseQueueWithPath:filename];
// 2.创表
[self.queue inDatabase:^(FMDatabase *db) {
BOOL result = [db executeUpdate:@"create table if not exists person (id integer primary key autoincrement, name text, age integer);"];
if (result) {
NSLog(@"创表成功");
} else {
NSLog(@"创表失败");
}
}];
}
上面还写了建表语句,其实它是用不到的。
上面的代码主要就是将项目中的数据库文件拷贝到应用的沙盒目录中,因为代码没到直接操作资源文件,只能当它成为应用中的沙盒文件才可以操作。所以不得不拷贝下啦,这点和安卓下的很相似,安卓下的数据库只能放到assets文件夹中。
通过以上的操作,就得到了一个数据库的db对象啦。ok!感觉已经成功了一大半了。
2.3数据库表的查询
在数据库查询之前,先建立一条纪录相对应的模型(model)出来,也就是Java中的javaBean。
由于我知道数据库里有什么记录,所以就直接新建一个文件,开写啦。
#import <Foundation/Foundation.h>
@interface IWStudent : NSObject
@property (nonatomic,copy) NSString *stunum;
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *tel;
@property (nonatomic,copy) NSString *classname;
@property (nonatomic,copy) NSString *qq;
@property (nonatomic,copy) NSString *address;
@property (nonatomic,copy) NSString *photo;
@end
模型建立完成了,就再写一个与模型对应的工具,用来专门对刚刚建立的模型进行操作。让后续的操作少写点代码
#import <Foundation/Foundation.h>
@class IWStudent;
@interface IWStudentTool : NSObject
/**
* 添加学生
*
* @param student 需要添加的学生
*/
+ (BOOL)addStudent:(IWStudent *)student;
/**
* 获得所有的学生
*
* @return 数组中装着都是IWStudent模型
*/
+ (NSArray *)students;
/**
* 根据搜索条件获得对应的学生
*
* @param condition 搜索条件
*/
+ (NSArray *)studentsWithCondition:(NSString *)condition;
@end
之后再在storyboard中在主界面中添加一个按钮,再加上对应的点击事件方法,我这里取名为query了
其主要代码如下:
- (IBAction)query
{
self.myStudents = [NSMutableArray array];
[self.queue inDatabase:^(FMDatabase *db) {
NSString *inputText = [self.inputTf text];
NSLog(@"query %@",inputText);
NSMutableArray *students = [NSMutableArray array];
// 1.查询数据
FMResultSet *rs = [db executeQuery:@"select * from person where name=?;",@"王磊"];
// 2.遍历结果集
while (rs.next) {
IWStudent *student = [[IWStudent alloc] init];
student.name = [rs stringForColumn:@"name"];
student.photo = [rs stringForColumn:@"photourl"];
student.classname = [rs stringForColumn:@"classname"];
student.qq = [rs stringForColumn:@"qq"];
student.tel = [rs stringForColumn:@"tel"];
student.stunum = [rs stringForColumn:@"stunum"];
student.address = [rs stringForColumn:@"address"];
NSString *name = [rs stringForColumn:@"name"];
NSLog(@" %@ ", student.tel);
[self goImage:student.photo];
[students addObject: student];
self.myStudents = students;
}
}];
[self performSegueWithIdentifier:@"second" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSString *msg = self.inputTf.text;
UIViewController *send = segue.destinationViewController;
if([send respondsToSelector:@selector(setData:)]){
[send setValue:msg forKey:@"data"];
[send setValue:self.myStudents forKey:@"myStudents"];
}
}
上面这样写,是因为,我想点一下按钮后就进入一个新的界面,并将查询的结果展示在第二个界面中。
在跳转界面前,先拖线给了另一个界面,并将并segue的identifier设为了second,这样,我就可以往第二个界面中传名为myStudents的数据了。
3.TableViewController界面展示
3.1TableViewController界面初始化
#import <UIKit/UIKit.h>
#import "IWStudent.h"
@class IWStudent;
@interface IWSecondViewController : UITableViewController
@property NSString *data;
@property NSMutableArray *myStudents;
@end
注意:变量名称必须得为上一个界面传过来的名称额。即data和myStudents
3.2UITableViewCell设置
数据接收到了,下面就是cell的展示了。
在storyboard中将TableView的content设为dynamic prototypes
然后再在cells中拖放几个label,用来展示上一个界面传过来的数据
再给cell设置一个identifier,这里名为student,并将class设为IWStudentCell
同时,在代码中新建一个继承自UITableViewCell的类
#import <UIKit/UIKit.h>
@class IWStudent;
@interface IWStudentCell : UITableViewCell
@property(nonatomic,strong) IWStudent *student;
@end
下面就是数据的展示了
通过storyboard对IWStudentCell连线后,分别取个名字,然后再给每个label设置相应的值
#import "IWStudentCell.h"
#import "IWStudent.h"
@interface IWStudentCell()
@property (weak, nonatomic) IBOutlet UILabel *nameLb;
@property (weak, nonatomic) IBOutlet UILabel *qqLb;
@property (weak, nonatomic) IBOutlet UILabel *classNameLb;
@property (weak, nonatomic) IBOutlet UILabel *telLb;
@property (weak, nonatomic) IBOutlet UILabel *stuNumLb;
@property (weak, nonatomic) IBOutlet UILabel *addressLb;
@end
@implementation IWStudentCell
-(void)setStudent:(IWStudent *)student
{
_student = student;
self.nameLb.text = [NSString stringWithFormat:@"姓名:%@",student.name];
self.qqLb.text = [NSString stringWithFormat:@"QQ:%@",student.qq];
self.classNameLb.text =[NSString stringWithFormat:@"班级:%@",student.classname];
self.telLb.text = [NSString stringWithFormat:@"电话:%@",student.tel];
self.stuNumLb.text = [NSString stringWithFormat:@"学号:%@",student.stunum];
self.addressLb.text = [NSString stringWithFormat:@"地址:%@",student.address];
}
@end
这样,就把第个cell的值就设好了
3.3将UITableViewCell设在UITableView中
下面的就很简单了,将cell设到这个UITableViewCell中就可以了
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.myStudents.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
IWStudentCell *cell = [tableView dequeueReusableCellWithIdentifier:@"student"];
cell.student = self.myStudents[indexPath.row];
return cell;
}
两个方法搞定了,不知道效率如何。
其次,我想达到的效果是,点击一个条目,就跳转到另一个界面,将这个学生的照片给显示出来。所以有了下面的方法:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
IWStudent *stu = [IWStudent alloc];
stu = self.myStudents[self.tableView.indexPathForSelectedRow.row];
NSString *photoUrl = stu.photo;
NSString *url;
url = @"http://xxx.xxx.xxx.xxx";
url = [url stringByAppendingString:[NSString stringWithFormat:@"%@",photoUrl]];
NSLog(url);
NSURL *urlPath = [NSURL URLWithString:url];<pre name="code" class="objc">#import "IWViewController.h"
@interface IWThirdViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIImageView *photoIv;
@property NSURL *photoUrl;
@property NSString *photoUrlPath;
@property (weak, nonatomic) IBOutlet UILabel *testLb;
@end
NSLog(@“send”); UIViewController *send = segue.destinationViewController; [send setValue:urlPath forKey:@“photoUrl”]; [send setValue:url forKey:@“photoUrlPath”];}重写prepareForSegue就好。但在重写前,还是记得要在storyboard中给cell拖线额。
4.图片展示界面完成
4.1接收数据
在此界面中展示一个网络图片前得获取到从上一个界面传过来的photoUrlPath,获取方法和第二个界面获取方法一样。
#import "IWViewController.h"
@interface IWThirdViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIImageView *photoIv;
@property NSURL *photoUrl;
@property NSString *photoUrlPath;
@property (weak, nonatomic) IBOutlet UILabel *testLb;
@end
在.h文件中,定义出photoUrl和photoUrlPath就好了。
在该调用的地方调用就好
4.2网络地址图片展示
网络网片的展示由于有了SDImageView就好办多了。一行代码都能搞定的事
由于之前我直接拖出了一个imageview,并给UIImageView设为了名为photoIv的变量,那么我就可以直接用它了
网络图片展示代码如下:
#import "IWThirdViewController.h"
#import "UIImageView+WebCache.h"
@implementation IWThirdViewController
@synthesize photoUrl;
@synthesize photoUrlPath;
-(void)viewDidLoad
{
[super viewDidLoad];
//self.testLb.text = photoUrlPath;
[self.photoIv sd_setImageWithURL:photoUrl];
}
@end
就这么简单就搞定了。嘻嘻。
我的第一个ios小程序完成啦。。。
程序地址: