IOS上路_17-简单示例-数据库

本文详细介绍了一个iOS应用如何通过SQLite数据库实现数据的存储、查询及删除功能。文章通过具体步骤介绍了如何在项目中添加SQLite依赖、创建数据库、实现数据插入、显示数据等功能。

1.添加依赖框架:

    1)点击项目,BP,LWL,加号:

    2)libsqlite3:


3.声明数据库和UI控件:


4.创建UI:

    1)在默认ViewController上添加两个文本框和一个按钮。然后为VC添加NC:

    2)添加一组新的NC,和上一组附加到同一个工具条:

    3)关联原ViewController的UI:


5.实现数据库创建和数据插入:

//
//  CVUViewController.m
//  0719-Sqlite
//
//  Created by vigiles on 13-7-19.
//  Copyright (c) 2013年 vigiles. All rights reserved.
//

#import "CVUViewController.h"

@interface CVUViewController ()

@end

@implementation CVUViewController

/* 在视图加载时创建数据库和UI */
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSArray * arrDoc;   //路径阵列-数组
    NSString * strDoc;  //定义数据库路径
    
    // 获取documents(我的文档)目录所在的路径阵列
    arrDoc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 因为是获取document目录,只返回一个。so,取索引0
    strDoc = [arrDoc objectAtIndex:0];
    
    // 构造数据库文件的保存路径和名称
    dbPath = [[NSString alloc] initWithString:[strDoc stringByAppendingPathComponent:@"user.sqlite"]];
    
    // 文件管理器,用于管理/删除/复制文件,
    NSFileManager * fm = [NSFileManager defaultManager];
    
    // 如果数据库不存在,即尚未创建。SQLite的策略是如果有就打开,如果没有就创建
    if([fm fileExistsAtPath:dbPath] == NO)
    {
        // 数据库编码
        const char * dbEncoded = [dbPath UTF8String];
        
        // 创建,并打开数据库
        if (sqlite3_open(dbEncoded, &dbUser) == SQLITE_OK) {
            
            //错误信息
            char * charErrMsg;
            
            //SQL语句=如果不存在就创建tbuser数据库(字段 类型,字段 类型)。不区分大小写
            const char * sqlCreateTb ="create table if not exists TbUser (name text, id text)";
            
            // 创建数据表
            if(sqlite3_exec(dbUser, sqlCreateTb, NULL, NULL, &charErrMsg) != SQLITE_OK){
                NSLog(@"创建表单失败了!");
            }
            
            // 关闭数据库
            sqlite3_close(dbUser);
            
            NSLog(@"创建数据库或打开成功:%@",dbPath);//打印出字符串路径
        } else
        {
            NSLog(@"创建/打开数据库失败了!");
        }
    }
    else
    {
        // [fm removeItemAtPath:dbPath error:nil];//删除文件;
        // NSLog(@"数据库文件已删除");
    }
    
}

/* 向数据库添加数据 */
-(IBAction)doAddData
{
    //定义错误的指针,保存错误信息
    char * charErrMsg;
    
    //数据库字符编码
    const char * dbEncoded = [dbPath UTF8String];
    
    //打开数据库
    if(sqlite3_open(dbEncoded, &dbUser) == SQLITE_OK)
    {
        //创建插入语句
        NSString * strSqlInsert = [NSString
                                   stringWithFormat:@"insert into TbUser(name, id) values(\"%@\",  \"%@\")",
                                   self.tfName.text,
                                   self.tfId.text];
        
        //创建Sqlite语句。UTF8编码
        const char * charSqlInsert= [strSqlInsert UTF8String];
        
        //执行SQL语句
        if (sqlite3_exec(dbUser, charSqlInsert, NULL, NULL, &charErrMsg) == SQLITE_OK)
        {
            //执行成功后清空文本框
            self.tfName.text= @"";
            self.tfId.text = @"";
        }
        else
        {
            NSLog(@"插入记录错误: %s", charErrMsg);
            sqlite3_free(charErrMsg);//释放错误指针
        }
        sqlite3_close(dbUser);//关闭数据库
    }
}

/* 关闭虚拟键盘 */
-(IBAction)doHideKey
{
    [self.tfName resignFirstResponder];
    [self.tfId resignFirstResponder];
}

@end

6.创建数据封装对象:

    1)创建OC文件:

    2)继承自基类:

    3)声明数据变量:


7.创建显示数据的表单类:

    1)OC文件:

    2)继承UITableViewController:

    3)声明数据变量:


8.实现数据显示:

这里又用到了对表单的操作。

//
//  TabShowData.m
//  SqliteTest
//
//  Created by vigiles on 13-7-19.
//  Copyright (c) 2013年 vigiles. All rights reserved.
//

#import "TabShowData.h"

@interface TabShowData ()

@end

@implementation TabShowData
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSLog(@"加载显示页面");
    
    NSArray * arrDocShow;   //路径阵列-数组
    NSString * strDocShow;  //定义数据库路径
    
    // 获取documents(我的文档)目录所在的路径阵列
    arrDocShow = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 因为是获取document目录,只返回一个。so,取索引0
    strDocShow = [arrDocShow objectAtIndex:0];
    
    // 获取已有的数据库路径
    dbPathShow = [[NSString alloc] initWithString:[strDocShow stringByAppendingPathComponent:@"user.sqlite"]];
    
    //动态数组进行初始化
    self.arrDataShow = [[NSMutableArray alloc] init];
    
    //对路径进行编码
    const char * dbEncodedShow = [dbPathShow UTF8String];
    
    //数据库模型
    sqlite3_stmt * statement;
    
    //数据库打开成功
    if(sqlite3_open(dbEncodedShow, &dbUserShow) == SQLITE_OK)
    {
        NSLog(@"打开数据库成功");
        
        //查询语句
        NSString * strSqlSelect = [NSString stringWithFormat:@"select name, id from TbUser "];
        
        //对语句编码
        const char * charSqlSelect = [strSqlSelect UTF8String];
        
        if(sqlite3_prepare_v2(dbUserShow, charSqlSelect, -1, &statement, NULL) == SQLITE_OK)//数据库查询成功
        {
            NSLog(@"查询数据成功");
            
            while (sqlite3_step(statement) == SQLITE_ROW)//对数据库进行循环遍历
            {
                ObjData * objUser = [[ObjData alloc] init];//创建一个数据封装对象
                
                objUser.objName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];//获取索引为0的数据
                objUser.objId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];//获取索引为1的数据
                
                [self.arrDataShow addObject:objUser];//对数据进行初始化
                
                NSLog(@"遍历数据...");
            }
        } else {
            NSLog(@"查询数据模型出现错误: %s", sqlite3_errmsg(dbUserShow));//如果出现问题就打印出来
        }
        
        // 销毁Statement对象
        sqlite3_finalize(statement);
        
    }
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;//返回一个分组
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.arrDataShow count];//返回分组的数量
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * identifier = @"CellShow";//标示符
    
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];//从队列中抓取一个单元格
    
    if (cell == nil)
    {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];//单元格初始化
    }
    
    //字符串赋值,进行类型转换,根据index.path
    cell.textLabel.text =((ObjData *)[self.arrDataShow objectAtIndex:indexPath.row]).objName;
    
    cell.detailTextLabel.text =((ObjData *)[self.arrDataShow objectAtIndex:indexPath.row]).objId;
    
    return cell;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        if (editingStyle == UITableViewCellEditingStyleDelete)
        {
            // 获取要删除的信息
            ObjData * objUser = [self.arrDataShow objectAtIndex:indexPath.row];
            
            sqlite3_stmt *statement;
            NSString * querySql = [NSString stringWithFormat:@"delete from TbUser where id = \"%@\"",objUser.objId];
            const char * sql = [querySql UTF8String];
            
            // 编译SQL 语句,创建Statement 对象
            if(sqlite3_prepare_v2(dbUserShow, sql, -1, &statement, NULL) != SQLITE_OK)
            {
                NSAssert1(0, @"创建删除对象模型失败:'%s'", sqlite3_errmsg(dbUserShow));
            }
            if (sqlite3_step(statement)  != SQLITE_DONE)
            {
                NSAssert1(0, @"删除失败:'%s'", sqlite3_errmsg(dbUserShow));
            }
            
            // 重置数据库信息
            sqlite3_reset(statement);
            // 删除当前的状态
            sqlite3_finalize(statement);
            
            // 从数组中去掉删除的信息
            [self.arrDataShow removeObject:objUser];
            
            // 从表格显示中删除
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            
        }
    }
}

@end


9.关联TableViewController和显示类:

    1)修改表单的映射类:

    2)修改单元格的标示符:

    3)配置表单代理:


10.测试:

可以成功执行插入数据操作。但显示数据却不是即时的。


另:

本例使用Xcode5没有成功。报错信息:

这似乎和NC自带的TVC有关。


- end

转载于:https://my.oschina.net/vigiles/blog/145792

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值