数据库基础用法
libsqlite3
//重写init方法,完成必要的初始化操作
- (id)init
{
self = [super init];
if (self) {
//指定数据库的路径 user.db
_lock = [[NSLock alloc] init];
NSString *dbPath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/user.db"];
//创建一个FMDataBase(操作sqlite3)的对象,并将数据库的路径传递给对象
_dataBase = [[FMDatabase alloc] initWithPath:dbPath];
//open有两层含义:如果指定路径下没有user.db则创建一个user.db数据库文件,并打开,如果已经存在user.db则直接打开,返回值反映操作是否成功
BOOL isOpen = [_dataBase open];
if (isOpen) {
//create table if not exists固定写法
//userInfo表名,()里面是表单的字段
//primary key主键,autoincrement主键自动增长
//创建一个表单,如果表单已经存在,这个sql语句就不会产生反应
NSString *createSql = @"create table if not exists userInfo(id integer primary key autoincrement,name varchar(256),age integer default 0,image blob)";
//需要执行创建表的语句
//创建表以及增、删、改的sql语句,执行的话全用executeUpdate方法,返回值为执行的结果
BOOL isCreate =[_dataBase executeUpdate:createSql];
if (!isCreate) {
//执行语句失败
//lastErrorMessage 会获取到执行sql语句失败的信息
NSLog(@"create error:%@",_dataBase.lastErrorMessage);
}
}
}
return self;
}
+(DBManager *)shareManager
{
static DBManager *manager = nil;
//@synchronized 同一时刻,只能有一个线程来执行{}中的代码
//为了防止,多个线程同时来调用shareManager而造成实例化多个对象
@synchronized(self){
if (manager == nil) {
manager = [[DBManager alloc] init];
}
}
return manager;
}
//将数据模型中的数据插入到表中
- (void)insertDataWithModel:(UserModel *)model{
[_lock lock];
UIImage *image = model.headImage;
//将image转化为NSData,UIImagePNGRepresentation将png格式的图片转化成NSData
NSData *imageData = UIImagePNGRepresentation(image);
//insert的sql语句,sql语句中,用?来作为占位符,不管字段是何种类型
NSString *insertSql = @"insert into userInfo(name,age,image) values(?,?,?)";
//executeUpdate:后面跟的参数类型必须是对象类型
//FMDataBase对象会将传过来的参数,转化成与数据库字段相匹配的类型,再进行后续处理
BOOL isInsert = [_dataBase executeUpdate:insertSql,mm.nameStr,mm.ageStr,imageDate];
if (!isInsert) {
NSLog(@"insert error = %@",_fmdb.lastErrorMessage);
}
[_lock unlock];
}
//根据主键id删除某条数据
- (void)deleteDataWithUserId:(NSInteger)userId
{
[_lock lock];
NSString *deleteSql = @"delete from userInfo where id =?";
//参数必须是对象类型,再作为executeUpdate:方法的参数
BOOL isDelete = [_dataBase executeUpdate:deleteSql,[NSNumber numberWithInteger:userId]];
if (isDelete == NO) {
NSLog(@"delete error:%@",_dataBase.lastErrorMessage);
}
[_lock unlock];
}
//根据主键id来更改某条数据
- (void)updateDataWithModel:(UserModel *)model userId:(NSInteger)userId
{
[_lock lock];
NSData *imageData = UIImagePNGRepresentation(model.headImage);
NSString *updateSql = @"update userInfo set name=?,age=?,image=? where id=?";
BOOL isUpdate =[_dataBase executeUpdate:updateSql,model.userName,model.age,imageData,[NSNumber numberWithInteger:userId]];
if (isUpdate == NO) {
NSLog(@"updateError:%@",_dataBase.lastErrorMessage);
}
[_lock unlock];
}
//获取所有的数据
- (NSArray *)getAllStudentsae
{
//取到userInfo表中所有的数据
[_lock lock];
//用来存放UserModel
NSMutableArray *array = [NSMutableArray array];
NSString *selectSql = @"select * from userInfo";
//FMResultSet 查询结果
FMResultSet *set =[_dataBase executeQuery:selectSql];
//类似于数组的快速遍历,set会依次代表所有的查询结果
while ([set next]) {
//每次取出一整条数据
//根据字段名称,取出字段的值
NSString *name=[set stringForColumn:@"name"];
NSString *age = [set stringForColumn:@"age"];
NSData *imageData =[set dataForColumn:@"image"];
UserModel *model = [[UserModel alloc] init];
model.userName = name;
model.age = age;
model.headImage = [UIImage imageWithData:imageData];
[array addObject:model];
[model release];
}
[_lock unlock];
return array;
}
【图片选择器进阶】
UIImagePickerController *ipc = [[UIImagePickerController alloc]init];//照片选择器
//打开编辑模式(为了裁剪图片)
picker.allowsEditing = YES;
ipc.delegate = self;//<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
[self presentViewController:ipc animated:YES completion:nil];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
//判断点击的是否是图片资源
//#import <MobileCoreServices/MobileCoreServices.h>才能用kUTTypeImage
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
//裁剪后的图片,只有打开编辑模式info里才有这个键值对
UIImage *image1 = [info objectForKey:UIImagePickerControllerEditedImage];
//原图
UIImage *image2 = [info objectForKey:UIImagePickerControllerOriginalImage];
//将图片转化为二进制数据
NSData* headData = UIImagePNGRepresentation(image2);
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
#import "ListViewController.h"
#import "DetailViewController.h"
#import "PersonModel.h"
@interface ListViewController () <UITableViewDataSource, UITableViewDelegate, dvcDelegate>
{
NSMutableArray *_dataArr;
UITableView *_myTableView;
}
@end
@implementation ListViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_dataArr = [[NSMutableArray alloc] init];
_dataArr.array = [[DataBaseManager sharedManager] selectAllModel];
_myTableView = [[UITableView alloc] initWithFrame:self.view.frame];
_myTableView.delegate = self;
_myTableView.dataSource = self;
[self.view addSubview:_myTableView];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addClick)];
}
- (void)addClick
{
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.delegate = self;
[self.navigationController pushViewController:dvc animated:YES];
}
- (void)saveClick:(DetailViewController *)dvc
{
if (!dvc.indexP) {
[_dataArr addObject:dvc.pm];
}
[_myTableView reloadData];
}
#pragma mark - tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_dataArr count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
PersonModel *pm = [_dataArr objectAtIndex:indexPath.row];
cell.textLabel.text = pm.name;
cell.detailTextLabel.text = pm.age;
cell.imageView.image = [UIImage imageWithData:pm.iconData];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.delegate = self;
dvc.pm = [_dataArr objectAtIndex:indexPath.row];
dvc.indexP = indexPath;
[self.navigationController pushViewController:dvc animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
#import <Foundation/Foundation.h>
#import "PersonModel.h"
@interface DataBaseManager : NSObject
//获得数据库管理的单例对象
+ (DataBaseManager *)sharedManager;
//插入一条数据
- (void)insertWithModel:(PersonModel *)pm;
//修改某一条数据
- (void)updateModel:(PersonModel *)pm forId:(NSInteger)identifier;
//查询所有的数据
- (NSArray *)selectAllModel;
@end
#import "DataBaseManager.h"
#import "FMDatabase.h"
@interface DataBaseManager ()
{
//管理数据库的三方类
FMDatabase *_fmdb;
}
@end
@implementation DataBaseManager
- (id)init
{
if (self = [super init]) {
//将要绑定的数据库的文件路径
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/user.db"];
//让fmdb和一个数据库关联起来
_fmdb = [[FMDatabase alloc] initWithPath:path];
//打开数据库(如果不存在就先创建,再打开)
BOOL isOpen = [_fmdb open];
//判断打开状态
if (isOpen) {
//sql语句,操作数据库的专用语言
//create table if not exists固定的,如果表不存在就创建。如果存在,这一行sql就略过
//userInfo表名,primary key代表主键(不能重复)autoincrement自增
NSString *createSql = @"create table if not exists userInfo(id integer primary key autoincrement,name varchar(256),age integer default 0,image blob)";
//执行sql语句
BOOL isCreate = [_fmdb executeUpdate:createSql];
//如果执行失败,打印错误信息
if (!isCreate) {
NSLog(@"create = %@",_fmdb.lastErrorMessage);
}
}
}
return self;
}
+ (DataBaseManager *)sharedManager
{//获取单例对象
static DataBaseManager *dbm = nil;
@synchronized(self) {
if (!dbm) {
dbm = [[DataBaseManager alloc] init];
}
}
return dbm;
}
- (void)insertWithModel:(PersonModel *)pm
{
//插入数据的sql语句
NSString *insertSql = @"insert into userInfo(name,age,image) values(?,?,?)";
//executeUpdate增删改都用这个方法,参数不能是基础数据类型
BOOL isInsert = [_fmdb executeUpdate:insertSql,pm.name,pm.age,pm.iconData];
if (!isInsert) {
NSLog(@"insert = %@",_fmdb.lastErrorMessage);
}
}
- (NSArray *)selectAllModel
{
//用一个数组来接收查询结果
NSMutableArray *dataArr = [NSMutableArray array];
//从userInfo里查询所有的记录
NSString *selectSql = @"select * from userInfo";
//执行查询的sql
FMResultSet *set = [_fmdb executeQuery:selectSql];
//在while循环中,set会依次代表查询结果里所有的数据
while ([set next]) {
PersonModel *pm = [[PersonModel alloc] init];
pm.name = [set stringForColumn:@"name"];
pm.age = [set stringForColumn:@"age"];
pm.iconData = [set dataForColumn:@"image"];
[dataArr addObject:pm];
}
return dataArr;
}
- (void)updateModel:(PersonModel *)pm forId:(NSInteger)identifier
{
NSString *updateSql = @"update userInfo set name=?,age=?,image=? where id=?";
//修改
BOOL isUpdate = [_fmdb executeUpdate:updateSql,pm.name,pm.age,pm.iconData,[NSNumber numberWithInteger:identifier]];
if (!isUpdate) {
NSLog(@"update = %@",_fmdb.lastErrorMessage);
}
}
@end
#import <Foundation/Foundation.h>
@interface PersonModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, retain) NSData *iconData;
@end
#import "PersonModel.h"
@implementation PersonModel
@end
#import <UIKit/UIKit.h>
#import "PersonModel.h"
#import "DataBaseManager.h"
@class DetailViewController;
@protocol dvcDelegate <NSObject>
- (void)saveClick:(DetailViewController *)dvc;
@end
@interface DetailViewController : UIViewController
@property (nonatomic, assign) id <dvcDelegate> delegate;
@property (nonatomic, retain) PersonModel *pm;
@property (nonatomic, retain) NSIndexPath *indexP;
@end
#import "DetailViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
@interface DetailViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
UIImagePickerController *_ipc;
}
@property (weak, nonatomic) IBOutlet UITextField *nameTF;
@property (weak, nonatomic) IBOutlet UITextField *ageTF;
@property (weak, nonatomic) IBOutlet UIButton *iconBtn;
@end
@implementation DetailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if (self.pm) {
_nameTF.text = _pm.name;
_ageTF.text = _pm.age;
[_iconBtn setBackgroundImage:[UIImage imageWithData:_pm.iconData] forState:UIControlStateNormal];
}
}
- (IBAction)iconClick:(UIButton *)sender
{
_ipc = [[UIImagePickerController alloc] init];
_ipc.delegate = self;
//允许编辑
_ipc.allowsEditing = YES;
[self presentViewController:_ipc animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *typeStr = [info objectForKey:UIImagePickerControllerMediaType];
//判断类型是不是图片
if ([typeStr isEqualToString:(NSString *)kUTTypeImage]) {
[_iconBtn setBackgroundImage:[info objectForKey:UIImagePickerControllerEditedImage] forState:UIControlStateNormal];
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)saveClick:(UIButton *)sender
{
if (!self.pm) {
_pm = [[PersonModel alloc] init];
}
_pm.name = _nameTF.text;
_pm.age = _ageTF.text;
_pm.iconData = UIImagePNGRepresentation(_iconBtn.currentBackgroundImage);
if (self.indexP) {
[[DataBaseManager sharedManager] updateModel:_pm forId:_indexP.row + 1];
} else {
//插入一条数据
[[DataBaseManager sharedManager] insertWithModel:_pm];
}
[self.delegate saveClick:self];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end