码迷,mamicode.com
首页 > 数据库 > 详细

2015.9.29-数据存取(SQLite)

时间:2015-09-29 11:17:14      阅读:342      评论:0      收藏:0      [点我收藏+]

标签:

SQLite

主流嵌入式关系数据库:轻量级,跨平台
 
基于C语言,在ios中需要用C语言进行数据库操作
采用动态数据类型,即使创建时定义了一种类型,在实际操作时也可以
存储其他类型,推荐建库时使用合适的类型(跨平台)
建立连接后通常不需要关闭连接(可以手动关闭)
 
使用SQLite步骤,先在项目中导入libsqlite3框架
 
 
 
 
 

1.打开库:sqlite3_open(),指定一个数据库文件保存路径,如果文件存在就直接打开,否则就创建然后打开,得到一个sqlite3类型的对象

2.执行sql语句
3.如果没有返回值(增删改),sqlite3_exec()执行
4.如果有返回值(查),
sqlite3_perpare_v2()语法检测,
sqlite3_step()依次取出查询结果的每一行数据,
sqlite3_column_类型()方法获得对应列
循环便利
类似于游标
-------------------------------------------------------------------------------------------------------------------------------------------
基本写法
//
//  DbManager.h
//  DataAccess
//
//  Created by Kenshin Cui on 14-3-29.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <sqlite3.h>
#import "KCSingleton.h"

@interface KCDbManager : NSObject

singleton_interface(KCDbManager);

#pragma mark - 属性
#pragma mark 数据库引用,使用它进行数据库操作
@property (nonatomic) sqlite3 *database;


#pragma mark - 共有方法
/**
 *  打开数据库
 *
 *  @param dbname 数据库名称
 */
-(void)openDb:(NSString *)dbname;

/**
 *  执行无返回值的sql
 *
 *  @param sql sql语句
 */
-(void)executeNonQuery:(NSString *)sql;

/**
 *  执行有返回值的sql
 *
 *  @param sql sql语句
 *
 *  @return 查询结果
 */
-(NSArray *)executeQuery:(NSString *)sql;
@end

 

主要定义了一个sqlite3 的数据库对象,
一个打开数据库openDb方法
一个执行无返回值的方法executeNonQuery方法
一个执行有返回值的方法executeQuery方法
sqlite不支持存储过程
//
//  DbManager.m
//  DataAccess
//
//  Created by Kenshin Cui on 14-3-29.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCDbManager.h"
#import <sqlite3.h>
#import "KCSingleton.h"
#import "KCAppConfig.h"

#ifndef kDatabaseName

#define kDatabaseName @"myDatabase.db"

#endif

@interface KCDbManager()
@end

@implementation KCDbManager

singleton_implementation(KCDbManager)

#pragma mark 重写初始化方法
-(instancetype)init{
    KCDbManager *manager;
    if((manager=[super init]))
    {
        [manager openDb:kDatabaseName];
    }
    return manager;
}

-(void)openDb:(NSString *)dbname{
    //取得数据库保存路径,通常保存沙盒Documents目录
    NSString *directory=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@",directory);
    NSString *filePath=[directory stringByAppendingPathComponent:dbname];
    //如果有数据库则直接打开,否则创建并打开(注意filePath是ObjC中的字符串,需要转化为C语言字符串类型)
    if (SQLITE_OK ==sqlite3_open(filePath.UTF8String, &_database)) {
        NSLog(@"数据库打开成功!");
    }else{
        NSLog(@"数据库打开失败!");
    }
}

-(void)executeNonQuery:(NSString *)sql{
    char *error;
    //单步执行sql语句,用于插入、修改、删除
    if (SQLITE_OK!=sqlite3_exec(_database, sql.UTF8String, NULL, NULL,&error)) {
        NSLog(@"执行SQL语句过程中发生错误!错误信息:%s",error);
    }
}

-(NSArray *)executeQuery:(NSString *)sql{
    NSMutableArray *rows=[NSMutableArray array];//数据行
    
    //评估语法正确性
    sqlite3_stmt *stmt;
    //检查语法正确性
    if (SQLITE_OK==sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL)) {
        //单步执行sql语句
int columnCount= sqlite3_column_count(stmt);
            while (SQLITE_ROW==sqlite3_step(stmt)) {
            NSMutableDictionary *dic=[NSMutableDictionary dictionary];
            for (int i=0; i<columnCount; i++) {
                const char *name= sqlite3_column_name(stmt, i);//取得列名
                const unsigned char *value= sqlite3_column_text(stmt, i);//取得某列的值
                dic[[NSString stringWithUTF8String:name]]=[NSString stringWithUTF8String:(const char *)value];
            }
            [rows addObject:dic];
        }
    }
    
    //释放句柄
    sqlite3_finalize(stmt);    
    return rows;
}
 

 

-------------------------------------------------------------------------------------------------------------------------------------------
分析
 
重写初始化方法init,在初始化的时候执行opendb,打开数据库(名字字符串通过#define 来定义)
opendb方法中先取得数据库的保存地址,然后打开
//取得数据库保存路径,通常保存沙盒Documents目录(这一步是取沙盒目录)
    NSString *directory=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    //传入数据库名字字符串得到数据库地址
    NSString *filePath=[directory stringByAppendingPathComponent:dbname];
//如果有数据库则直接打开,否则创建并打开(注意filePath是ObjC中的字符串,需要转化为C语言字符串类型)
    sqlite3_open(filePath.UTF8String, &_database)
executeNonQuery直接执行sql语句,无返回值(其实是有返回值的SQLite_OK表示语句是否执行成功)
sqlite3_exec(_database, sql.UTF8String, NULL, NULL,&error)
executeQuery先检查sql语句的语法,有返回值,一条一条的读数据
首先需要一个整体的存放数据的数组(相当于C#的DataTable.Rows集合)
 NSMutableArray *rows=[NSMutableArray array];//数据行
然后需要一个sqlite3_stmt对象检查语法
  //评估语法正确性
    sqlite3_stmt *stmt;

然后检查语法

//检查语法正确性
    if (SQLITE_OK==sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL))
然后循环执行(类似于游标,一行一行的读,每行都要检查语法)
while (SQLITE_ROW==sqlite3_step(stmt))

 

然后定义一个NSmutableDicrtionary,用于接受每一行的数据,这一行的每一列的列名就是dic的键名,dic的值就是这一列这行对应的值,然后将这个dic添加到存放数据的数组
while (SQLITE_ROW==sqlite3_step(stmt)) {
            NSMutableDictionary *dic=[NSMutableDictionary dictionary];
            for (int i=0; i<columnCount; i++) {
                const char *name= sqlite3_column_name(stmt, i);//取得列名
                const unsigned char *value= sqlite3_column_text(stmt, i);//取得某列的值
                dic[[NSString stringWithUTF8String:name]]=[NSString stringWithUTF8String:(const char *)value];
            }
            [rows addObject:dic];
最后释放检查语法的句柄(不知道是什么意思)
 
在实际使用的时候,Controller不直接和db进行交互,而是通过一个Service层间接完成数据的传递,Service层封装了针对Model层的
业务方法,Controller针对Service中对Model方法的调用实际上就是对db的操作。完成了解耦
 
技术分享
 
技术分享
-------------------------------------------------------------------------------------------------------------------------------------------

实际应用 待续.....

 

2015.9.29-数据存取(SQLite)

标签:

原文地址:http://www.cnblogs.com/wuxian781999/p/4845720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!