Oc 数据库SQLite3

1.sqllite****好处1> 存储大批量数据,可以精确的读取数据。2> 批量读取数据,NSCoding这些都是一次把所有数据读取出来。
2.****数据库怎么存储1> 跟excel很像,以表为单位,每个表都是存储不同的数据。2> 存储学生数据步骤
• 先要创建表• 确定属性(字段)• 插入数据(记录)
3.****数据库专业术语:1> name,id这些叫字段
2> 一行叫做一个记录。4.利用Navcat工具演示数据库
1> 创建数据库,取数据库连接名,创建数据库文件,数据库是以文件存在的。2> 连接数据库,双击连接名,会自动创建一个名为main的数据库。
• table:数据库表
• view:视图2> 创建表格3> 添加字段,保存表格,表格名称以t_开头
text 字符串

integer 整形

real 浮点型
4> 主键:保证数据唯一性,区分相同的数据。主键:自动增长
5.sql****语句1> 为什么要学习sql语句,、以后数据库肯定是运行时创建的,我们不可能去用户的手机上装个navcat先创建好数据库,在存储。2> 想要操作数据库,就要学习sql语句,跟操作iOS,学习oc一样。PPT简介,主要学习增删查改(CRUD) 增加(Create)、读取(Retrieve)(重新得到数据)、更新(Update)和删除(Delete)3> SQL语句特点
• 不区分大小写4> SQL语句种类

DDL语句(数据定义语句:定义数据格式):创表和删表 creat和drop

DML语句(数据操作语句):增删查改 insert,delete,update,select• DQL语句(数据查询语句)

3> SQL语句特点

• 不区分大小写4> SQL语句种类

DDL语句(数据定义语句:定义数据格式):创表和删表 creat和drop

DML语句(数据操作语句):增删查改 insert,delete,update,select

DQL语句(数据查询语句)
6.DDL语句1> 创建表格

数据库表格是唯一的,创建表格的时候加上一句if not exists,不存在才需求创建,就不会报sql语句错误。

创建没有主键的key2>删除表格
• 删除没有主键的key

• 创建一个有主键的key,primary key,自动增长 autoincrement7.DML语句
1> 插入数据• 数据库字符串用单引号'
2> 更新数据3> 删除数据4> 条件语句
8.DQL语句1> select
2> 别名,可以不用as,• 给数据库取别名的好处:用别名获取字段,有提示。
3> 计算查询数量count4> 排序: 有条件语句,需要放在条件语句后。5> limit : limit 0,5 跳过第0个,取5个数据,意味着取前5个数据。这个语句必须放在查询语句最后面。
9.****通过代码访问数据库1> 导入系统自带框架sqlite32> 打开数据库,没有创建数据库,会自动创建,并且返回数据库实例3>增删改4> 查,不能用exec,因为exec执行完就没了,不会返回数据。
查询数据,首先要做一些准备操作,获取stmt句柄,有了句柄就能拿到数据了

调用step,执行stmt,通过stmt能查询下一条数据

stmt:是一行一行往下提取,用while判断是否还有数据,如果没有
数据,就不会返回SQLITE_ROW.

根据stmt获取每条记录的字段值
10.数据库的封装

要变成模型,展示到视图。
2> 搞个专门的工具类处理数据库的逻辑。11.模糊查询

1> 通常开发中,面向模型开发,也就是把模型保存到数据库,取出来也要变成模型,展示到视图。

• 根据stmt获取每条记录的字段值10.数据库的封装

• %:通配符表示任意1> 搞个搜索框,输入条件,展示数据2> 添加按钮,插入100条数据,并且保存到数据库3> 封装工具类进行模糊查询

sqlite3是轻量级嵌入式数据库、C源代码,完全开放。

掌握常用的SQL语句:
创建表:"create table if not exists 表名(id intager primary key, 数据对象1 对象类型text,数据对象2 对象类型BLOB)"
添加数据:"insert into 表名 values(null,?,?)"
删除数据 : "delete from 表名 where intTeger = ?"
修改数据: "update 表名 set 数据对象1 = ?,数据对象2 = ? where intTeger"
查询获取数据:"select *from 表名"

掌握SQLite3的使用及常用函数的作用
导入libsqlite3.dylib库并添加头文件#import
数据库连接指针:sqlite3*
打开数据库:int sqlite3_open(const char *fileName, sqlite3 **ppDb);
创建SQL语句预编译指针:sqlite3_stmt *
预编译SQL语句:int sqlite3_prepare[prepare_v2](sqlite3 *db,const char *zSql,int nByte,sqlite3_stmt **ppStmt,const char **pzTail);
绑定SQL语句占位符:int sqlite3_bind_xxx
执行预编译的SQL语句:int sqlite3_step(sqlite3_stmt *)
获取数据表中数据:sqlite3_column_xxx(sqlite3_stmt *,int iCol);
销毁预编译指针:int sqlite3_finalize(sqlite3_stmt *pStmt)
关闭数据库:int sqlite3_close(sqlite3 *db)

创建一个Demo工程,可以使用SQLite3实现数据的增、删、改、查

第三方:MBProgressHUD(提示框)
Project.pch

#ifndef Project_pch
#define Project_pch

// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.


#import "MBProgressHUD.h"
#import "User.h"
#endif /* Project_pch */

AppDelegate.m

  #import "AppDelegate.h"
#import "ShowViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    ShowViewController *showVc = [[ShowViewController alloc]init];
    
    showVc.navigationItem.title = @"全部用户";
    
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:showVc];
    
    self.window.rootViewController = nav;
    
   
    return YES;
}


首先先创建数据对象类
User.h

#import 

@interface User : NSObject
@property (nonatomic,strong)NSString *phone;
@property (nonatomic,strong)NSString *password;
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)NSInteger ID;
@end

User.m

#pragma mark - NSCopy
//方法1 无需协议
- (id)copy
{
    User *u = [[User alloc]init];
    u.phone = self.phone;
    u.name = self.name;
    u.password = self.password;
    u.ID = self.ID;
    
    return u;
}
//方法2
//浅复制
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

创建业务处理层
SQLiteDataBase.h

#import 

@interface SQLiteDataBase : NSObject
//创建表
- (BOOL)creatTableByName:(NSString *)name;

+(instancetype)defaultDataBase;
///添加
- (BOOL)addNew:(id)newObj;
///删除
- (BOOL)deleteOne:(id)deleteobj;
///修改
- (BOOL)updataOne:(id)upObj;
///获取所有
- (id)getAllObjects;
@end

SQLiteDataBase.m

#import "SQLiteDataBase.h"
#import 
#define USER_PATH @"users.db" //数据库文件的名称
static SQLiteDataBase *_dataBase = nil;


//延展
@interface SQLiteDataBase()
{
    sqlite3 *_db; // 操作数据库内存的指针
    NSString *_tableName; //表名字符串
}

@end



@implementation SQLiteDataBase

#pragma  mark  -单例类的方法
//重写allocWithZone方法,让外部文件使用alloc方法创建对象时,只得到一块内存空间
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    if (_dataBase == nil)
    {
        _dataBase = [super allocWithZone:zone];
    }
    return _dataBase;
}

+(instancetype)defaultDataBase
{
    if (_dataBase == nil)
    {
        _dataBase = [[SQLiteDataBase alloc]init];
    }
    return _dataBase;
}
- (id)copy
{
    return self;
}
- (id)mutableCopy
{
    return self;
}
#pragma  mark - 私有方法
//打开数据库
- (BOOL)openDB:(NSString *)dbPath
{
    //打开数据库
    //如果数据库文件不存在,先创建再打开,如果存在,直接打开
    //参数1 - 持久化文件的路径字符串
    NSString *fPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:dbPath];
    NSLog(@"db文件%@",fPath);
   int res =  sqlite3_open(fPath.UTF8String, &_db);
    if (res == SQLITE_OK)
    {
        return YES;
    }
    else
        return NO;
}
///关闭数据库
- (void)closeDB
{
    sqlite3_close(_db);
}

///创建一个数据表
- (BOOL)creatTableByName:(NSString *)name
{
    _tableName = name;
   BOOL success =  [self openDB:USER_PATH];
    if (!success) {
        [self closeDB];
        return NO;
    }
    
    //执行创建数据表操作
    // 1)先做一个sql语句
    //UNIQUE 唯一约束  PRIMARY KEY 主键自增
    NSString *sql = [NSString stringWithFormat:@"CREATE TABLE %@ (id INTEGER PRIMARY KEY AUTOINCREMENT,phone TEXT UNIQUE,name TEXT,password TEXT)",name];
    //2)定义一个预编译指针,用于存储编译结果
    sqlite3_stmt *statement = NULL;
    //3)执行编译操作,将sql语句转换为机器可以读懂的机器码
    sqlite3_prepare_v2(_db, sql.UTF8String, -1, &statement,NULL);
    //4)执行编译结果
    int res = sqlite3_step(statement);
    //5)释放预编译指针指向的内存
    sqlite3_finalize(statement);
    //关闭数据库
    [self closeDB];

    return res == SQLITE_DONE ? YES :NO;
}

#pragma  mark - 对外公开的方法
///添加
- (BOOL)addNew:(User *)newObj
{
    if (![self openDB:USER_PATH])
    {
        [self closeDB];
        return NO;
    }
    
    // 1)先做一个sql语句
    NSString *sql = [NSString stringWithFormat:@"INSERT INTO %@ (phone,name,password) VALUES (?,?,?)",_tableName];
    //2)定义一个预编译指针,用于存储编译结果
    sqlite3_stmt *statement = NULL;
    //3)执行编译操作,将sql语句转换为机器可以读懂的机器码
    sqlite3_prepare_v2(_db, sql.UTF8String, -1, &statement,NULL);
    //4)绑定?号
    //参数1 - 预编译指针变量
    //参数2 - 第几个问号
    //参数3 - 绑定的数据
    //参数4 - 读取绑定数据的前几个字符,-1表示全部内容
    //参数5 - 短暂,固定两个选择
    sqlite3_bind_text(statement, 1, newObj.phone.UTF8String, -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 2, newObj.name.UTF8String, -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 3, newObj.password.UTF8String, -1, SQLITE_TRANSIENT);
    
    
    //4)执行编译结果
    int res = sqlite3_step(statement);
    //5)释放预编译指针指向的内存
    sqlite3_finalize(statement);
    //关闭数据库
    [self closeDB];
    
    return res == SQLITE_DONE ? YES :NO;
    
}
///删除
- (BOOL)deleteOne:(User *)deleteobj
{
    
    if (![self openDB:USER_PATH])
    {
        [self closeDB];
        return NO;
    }

    NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE id = ?",_tableName];
    //2)定义一个预编译指针,用于存储编译结果
    sqlite3_stmt *statement = NULL;
    //3)执行编译操作,将sql语句转换为机器可以读懂的机器码
    sqlite3_prepare_v2(_db, sql.UTF8String, -1, &statement,NULL);
    
    sqlite3_bind_int(statement, 1, (int)deleteobj.ID);
    //4)执行编译结果
    int res = sqlite3_step(statement);
    //5)释放预编译指针指向的内存
    sqlite3_finalize(statement);
    //关闭数据库
    [self closeDB];
    
    return res == SQLITE_DONE ? YES :NO;
    
}
///修改
- (BOOL)updataOne:(User *)upObj
{
    
    if (![self openDB:USER_PATH])
    {
        [self closeDB];
        return NO;
    }
    
    NSString *sql = [NSString stringWithFormat:@"UPDATE %@ SET name = ?,password = ? WHERE id = ?",_tableName];
    //2)定义一个预编译指针,用于存储编译结果
    sqlite3_stmt *statement = NULL;
    //3)执行编译操作,将sql语句转换为机器可以读懂的机器码
    sqlite3_prepare_v2(_db, sql.UTF8String, -1, &statement,NULL);
    
    sqlite3_bind_text(statement, 1, upObj.name.UTF8String, -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 2, upObj.password.UTF8String,-1, SQLITE_TRANSIENT);
    sqlite3_bind_int(statement, 3, (int)upObj.ID);
    
    //4)执行编译结果
    int res = sqlite3_step(statement);
    //5)释放预编译指针指向的内存
    sqlite3_finalize(statement);
    //关闭数据库
    [self closeDB];
    
    return res == SQLITE_DONE ? YES :NO;
}
///获取所有
- (id)getAllObjects
{
    if (![self openDB:USER_PATH])
    {
        [self closeDB];
        return nil;
    }
    
    // 1)先做一个sql语句
    NSString *sql = [NSString stringWithFormat:@"SELECT *FROM %@",_tableName];
    //2)定义一个预编译指针,用于存储编译结果
    sqlite3_stmt *statement = NULL;
    //3)执行编译操作,将sql语句转换为机器可以读懂的机器码
    sqlite3_prepare_v2(_db, sql.UTF8String, -1, &statement,NULL);
    //4)每行每行的读取数据
    NSMutableArray *arr = [[NSMutableArray alloc]init];
    
    while (sqlite3_step(statement) == SQLITE_ROW)
    {
        int ID = sqlite3_column_int(statement, 0);
        const char *phone = (const char *)sqlite3_column_text(statement, 1);
        const char *name = (const char *)sqlite3_column_text(statement, 2);
        const char *pwd = (const char *)sqlite3_column_text(statement, 3);
        
        User *u = [[User alloc]init];
        u.ID = ID;
        u.phone = [NSString stringWithUTF8String:phone];
        u.name = [NSString stringWithUTF8String:name];
        u.password = [NSString stringWithUTF8String:pwd];
        [arr addObject:u];
        
    }
    //5)释放预编译指针指向的内存
    sqlite3_finalize(statement);
    //关闭数据库
    [self closeDB];

    return arr;
}

@end

ShowViewController.h

#import 

@interface ShowViewController : UIViewController

@end

ShowViewController.m

#import "ShowViewController.h"
#import "AddViewController.h"
#import "User.h"
#import "DetailViewController.h"
#import "SQLiteDataBase.h"

@interface ShowViewController ()
{
    NSMutableArray *_tableDataArr; //表格赋值数组
}
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)AddViewController *addVc;
@property (nonatomic,strong)DetailViewController *detailVc;
@property (nonatomic,strong)id db; //数据库对象
@end

@implementation ShowViewController

#pragma  mark - 懒加载 ,属性getter重写
- (UITableView *)tableView
{
    if (!_tableView)
    {
        _tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];
        _tableView.delegate  =self;
        _tableView.dataSource = self;
    }
    return _tableView;
}
- (AddViewController *)addVc
{
    if (!_addVc)
    {
        _addVc = [[AddViewController alloc]init];
        
    }
    return _addVc;
}

- (DetailViewController *)detailVc
{
    if (!_detailVc)
    {
        _detailVc = [[DetailViewController alloc]init];
        
    }
    return _detailVc;
}
- (id)db
{
    if (!_db)
    {
        _db = [[SQLiteDataBase alloc]init];
        [_db creatTableByName:@"users"];      
    }
    return _db;
}
//添加子视图
- (void)loadView
{
    [super loadView];
    //
    NSLog(@"%@",NSStringFromSelector(_cmd));
    [self.view addSubview:self.tableView];
    
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addDidHandle:)];
    
    
}

- (void)addDidHandle:(id)sender
{
    [self.navigationController pushViewController:self.addVc animated:YES];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    _tableDataArr = [self.db getAllObjects];
    
    [self.tableView reloadData];
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _tableDataArr.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifer = @"CELL";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifer];
    if (!cell)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifer];
    }
    
    User *u = _tableDataArr[indexPath.row];
    cell.textLabel.text = u.phone;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"ID:%ld名字:%@密码:%@",u.ID,u.name,u.password];
    return cell;
}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        //删除底层数据
        [self.db deleteOne:_tableDataArr[indexPath.row]];
        //删除给表格赋值的数组中相对应的数据
        [_tableDataArr removeObjectAtIndex:indexPath.row];
        //删除单元格
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self.tableView reloadData];
    }
}
#pragma mark----UITableViewDelegate----
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    self.detailVc.passUser = _tableDataArr[indexPath.row];
    [self.navigationController pushViewController:self.detailVc animated:YES];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

AddViewController.h


#import 

@interface AddViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *phoneTF;
@property (weak, nonatomic) IBOutlet UITextField *pwdTF;
@property (weak, nonatomic) IBOutlet UITextField *nameTF;
- (IBAction)saveHandle:(id)sender;

@end

AddViewController.m

#import "AddViewController.h"
#import "User.h"
#import "SQLiteDataBase.h"

@interface AddViewController ()
{
    MBProgressHUD *_hud;
}
@end

@implementation AddViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    _hud = [[MBProgressHUD alloc]init];
    [self.view addSubview:_hud];
    [_hud hide:YES];
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.phoneTF.text = @"";
    self.pwdTF.text = @"";
    self.nameTF.text=  @"";
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction)saveHandle:(id)sender {
    
    if (self.phoneTF.text.length == 0 || self.pwdTF.text.length == 0 || self.nameTF.text.length == 0)
    {
        //设置弹出框的样式
        _hud.mode = MBProgressHUDModeText;
        //设置提示文本
        _hud.labelText = @"输入的内容不能为空";
        //显示
        [_hud show:YES];
        //2秒后隐藏
        [_hud hide:YES afterDelay:2.0];
        return;
    }
    
 
     id db = [[SQLiteDataBase alloc]init];
   
    
    User *u = [[User alloc]init];
    u.phone = self.phoneTF.text;
    u.password  = self.pwdTF.text;
    u.name = self.nameTF.text;
    
    BOOL success = [db addNew:u];
    if (success) {
        //设置弹出框的样式
        _hud.mode = MBProgressHUDModeText;
        //设置提示文本
        _hud.labelText = @"添加成功!";
        //显示
        [_hud show:YES];
        [self performSelector:@selector(back:) withObject:nil afterDelay:2.0];
    }
    else
    {
        //设置弹出框的样式
        _hud.mode = MBProgressHUDModeText;
        //设置提示文本
        _hud.labelText = @"用户已存在!";
        //显示
        [_hud show:YES];
        //2秒后隐藏
        [_hud hide:YES afterDelay:2.0];

    }
    
}

- (void)back:(id)sender
{
    if (_hud.isHidden == NO)
    {
        [_hud hide:YES];
    }
    [self.navigationController popViewControllerAnimated:YES];

    
}
@end

AddViewController.xib

Oc 数据库SQLite3_第1张图片
屏幕快照 2017-09-14 08.45.03.png

DetailViewController.h

#import 

@interface DetailViewController : UIViewController
@property (nonatomic,strong)User *passUser;
@end

DetailViewController.m

#import "DetailViewController.h"

#import "SQLiteDataBase.h"

@interface DetailViewController ()
@property (weak, nonatomic) IBOutlet UITextField *phoneTF;
@property (weak, nonatomic) IBOutlet UITextField *pwdTF;
@property (weak, nonatomic) IBOutlet UITextField *nameTF;
- (IBAction)updataHandle:(id)sender;

@end

@implementation DetailViewController

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    self.phoneTF.text = self.passUser.phone;
    self.pwdTF.text=  self.passUser.password;
    self.nameTF.text = self.passUser.name;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
   
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



- (IBAction)updataHandle:(id)sender {
    
//    User *newU = [[User alloc]init];
//    
//    newU.ID = self.passUser.ID;
//    newU.phone = self.passUser.phone;
//    newU.password = self.pwdTF.text;
//    newU.name = self.nameTF.text;
    //这句话实现与上面4句代码等效的结果
    User *newU = [self.passUser copy];
    newU.password = self.pwdTF.text;
    newU.name = self.nameTF.text;
   
    SQLiteDataBase *db = [[SQLiteDataBase alloc]init];    
    BOOL success = [db updataOne:newU];
    
    MBProgressHUD *hud = [[MBProgressHUD alloc]initWithView:self.view];
    [self.view addSubview:hud];
    hud.removeFromSuperViewOnHide = YES;
    hud.mode = MBProgressHUDModeText;
    hud.labelText = success ? @"更新成功" :@"更新失败";
    [hud show:YES];
    [hud hide:YES afterDelay:2.0];
      
}
@end

DetailViewController.xib


Oc 数据库SQLite3_第2张图片
屏幕快照 2017-09-14 08.45.15.png

你可能感兴趣的:(Oc 数据库SQLite3)