美文网首页数据存储
iOS数据存储之Sqlite3封装

iOS数据存储之Sqlite3封装

作者: charlotte2018 | 来源:发表于2017-03-22 11:30 被阅读29次

Sqlite3的函数介绍

1.打开数据库
int sqlite3_open(
    const char *filename,   // 数据库的文件路径
    sqlite3 **ppDb          // 数据库实例
);

2.执行任何SQL语句
int sqlite3_exec(
    sqlite3*,                                  // 一个打开的数据库实例
    const char *sql,                           // 需要执行的SQL语句
    int (*callback)(void*,int,char**,char**),  // SQL语句执行完毕后的回调
    void *,                                    // 回调函数的第1个参数
    char **errmsg                              // 错误信息
);

3.检查SQL语句的合法性(查询前的准备)
int sqlite3_prepare_v2(
    sqlite3 *db,            // 数据库实例
    const char *zSql,       // 需要检查的SQL语句
    int nByte,              // SQL语句的最大字节长度
    sqlite3_stmt **ppStmt,  // sqlite3_stmt实例,用来获得数据库数据
    const char **pzTail
);

4.查询一行数据
int sqlite3_step(sqlite3_stmt*); // 如果查询到一行数据,就会返回SQLITE_ROW

5.利用stmt获得某一字段的值(字段的下标从0开始)
double sqlite3_column_double(sqlite3_stmt*, int iCol);  // 浮点数据
int sqlite3_column_int(sqlite3_stmt*, int iCol); // 整型数据
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); // 长整型数据
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 二进制文本数据
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);  // 字符串数据

SQL语句介绍

 ------------------SQL语句初级-------------------
 SQL语句格式记录《重点内容》
 1.创建表
 create table 表的名字(字段的名字 字段的类型,...)
 create table if not exists 表的名字(字段的名字 字段的类型,...)
 2.删除表
 drop table 表的名字
 drop table if exists 表的名字
 3.往表中插入数据
 insert into 表的名字(字段的名字1,字段的名字2,...) values(内容1,内容2,...)
 4.查询表中的数据
 select * from 表的名字   (*)表示查看表中所有的字段
 select 字段名字1,字段名字2,... from 表的名字   (查询指定字段信息)
 5.条件语句
 关键字 where
 条件类型:=、is、!=、is not、>=、<=、like
 多条件连接的时候:and(&&)、or(||)
 结构:
 where 字段的名字 =(条件的类型) 比较内容   and(多条件连接) 字段的名字 like '%张%'
 6.修改
 update 表的名字 set 字典的名字=内容,... where...
 7.删除
 delete from 表的名字 where 字段 = 内容
 
 ------------------SQL语句提高-------------------
 1.排序
 order by 字段名字,... asc(默认升序)
 order by 字段名字,... desc(降序)
 2.翻页(为了限制数据亮过大,造成的读取过慢,内存过大的问题)
 limit 从第几个条内容后开始读取,读取多少条数据
 3.多表查询
 select * from 表的名字1,表的名字2 where 表1.字段名字 = 表2.字典名字
 事例
 select student.stu_name,class.class_name from student,class where student.classid = class.class_id
 4.重命名
 select s.stu_name,c.class_name from student as s,class as c where s.classid = c.class_id
 
 ------------------SQL语句进阶--------------------
 1.不能为空
 not null
 2.唯一约束
 unique
 3.设置默认值
 default
 4.自定增长(必须是integer)
 autoincrement
 5.主键约束
 primary key (由not null 和unique两个约束的结合体)
 例子:CREATE TABLE class (id integer primary key autoincrement,name not null,num integer default 1)
 6.主外键约束
 foreign key(classid) references class(id)
 外键(字段)关联 表2(主键字典)
 例子:create table student(id integer primary key autoincrement,name text not null,classid integer not null, foreign key(classid) references class(id))

SQL自学网址:http://www.yiibai.com/sqlite/sqlite_overview.html

自己写了个Sqlite3Manager,练练手。

//
//  Sqlite3Manager.h
//  数据库demo
//
//  Created by wyb on 2017/3/21.
//  Copyright © 2017年 xxx. All rights reserved.
//

#import <Foundation/Foundation.h>
typedef void(^Myblock) (NSArray * array);

@interface Sqlite3Manager : NSObject

+ (instancetype)shareManager;


/**
 创建manager

 @param name 数据库的名字
 @return manager
 */
- (instancetype)initWithDatabaseNamed:(NSString *)name;


/**
 设置数据库的名字

 @param name 数据库的名字
 */
- (void)setDataBaseName:(NSString *)name;


/**
  创建表

 @param sql sql语句
 @return 如果执行成功返回YES,否返回NO
 */
- (BOOL)createTableWithSql:(NSString *)sql;


/**
 执行数据库表的(增,删,改)操作

 @param sql sql语句
 @param params sql语句对应参数的添加
 @return 如果执行成功返回YES,否返回NO
 */
- (BOOL)execTableWithSql:(NSString *)sql params:(NSArray *)params;


/**
 执行数据库表的(查询)操作异步操作

 @param sql sql语句
 @param params sql语句对应参数的添加
 @param block 返回的数据
 */
- (void) selectTableWithSql:(NSString *)sql params:(NSArray *)params finshBlock:(Myblock)block;

@end

//
//  Sqlite3Manager.m
//  数据库demo
//
//  Created by wyb on 2017/3/21.
//  Copyright © 2017年 xxx. All rights reserved.
//

#import "Sqlite3Manager.h"
#import <sqlite3.h>
typedef void(^Myblock) (NSArray *);
@interface Sqlite3Manager ()
{
    sqlite3 *db;
    
}

@property(nonatomic,strong)NSString *databaseName;

@end

@implementation Sqlite3Manager

+ (instancetype)shareManager
{
    static Sqlite3Manager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        manager = [[Sqlite3Manager alloc]init];
        
    });
    return manager;
}

- (instancetype)initWithDatabaseNamed:(NSString *)name
{
    self = [super init];
    if (self) {
        
        self.databaseName = name;
        
    }
    return self;
}

- (void)setDataBaseName:(NSString *)name
{
    self.databaseName = name;
}

- (NSString *)getDatabaseFilePath
{
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *dataBaseFilePath = [docPath stringByAppendingPathComponent:self.databaseName];
    
    return dataBaseFilePath;
}

- (BOOL)openDataBase
{
    NSString *filePath = [self getDatabaseFilePath];
    int result = sqlite3_open(filePath.UTF8String, &db);
    if (result == SQLITE_OK) {
        NSLog(@"数据库打开成功");
        return YES;
    }else{
        NSLog(@"数据库打开失败");
        return NO;
    }
    
}

- (BOOL)createTableWithSql:(NSString *)sql
{
    
    BOOL result = [self openDataBase];
    
    if (result == YES) {
        
        //定义编译sql语句的变量(数据句柄)
        sqlite3_stmt *stmt = NULL;
        //开始编译sql语句
        sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, NULL);
        //执行sql语句
        result = sqlite3_step(stmt);
        
        if (result == SQLITE_ERROR) {
            const char *errorMsg = sqlite3_errmsg(db);
            NSString *error = [NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding];
            NSLog(@"%@",error);
            return NO;
        }
        
        //关闭数据句柄和数据库
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        
        return  YES;

        
    }else{
        
        return result;
    }
    
    
    
}

- (BOOL)execTableWithSql:(NSString *)sql params:(NSArray *)params
{
    
   BOOL result = [self openDataBase];

    if (result == YES) {
        
        //定义编译sql语句的变量(数据句柄)
        sqlite3_stmt *stmt = NULL;
        //开始编译sql语句
        sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, NULL);
        
        //绑定参数
        for (int i = 0; i < params.count; i++) {
            // 获取参数内容
            id param = params[i];
            if ([param isKindOfClass:[NSString class]] )
                sqlite3_bind_text(stmt, i+1, [param UTF8String], -1, SQLITE_TRANSIENT);
            if ([param isKindOfClass:[NSNumber class]] ) {
                if (!strcmp([param objCType], @encode(float)))
                    sqlite3_bind_double(stmt, i+1, [param doubleValue]);
                else if (!strcmp([param objCType], @encode(int)))
                    sqlite3_bind_int(stmt, i+1, [param intValue]);
                else if (!strcmp([param objCType], @encode(BOOL)))
                    sqlite3_bind_int(stmt, i+1, [param intValue]);
                else
                    NSLog(@"unknown NSNumber");
            }
            if ([param isKindOfClass:[NSDate class]]) {
                sqlite3_bind_double(stmt, i+1, [param timeIntervalSince1970]);
            }
            if ([param isKindOfClass:[NSData class]] ) {
                sqlite3_bind_blob(stmt, i+1, [param bytes], (int)[param length], SQLITE_STATIC);
            }
        }
        
        
        //执行sql语句
        result = sqlite3_step(stmt);
        
        if (result == SQLITE_ERROR) {
            const char *errorMsg = sqlite3_errmsg(db);
            NSString *error = [NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding];
            NSLog(@"%@",error);
            return NO;
        }
        
        //关闭数据句柄和数据库
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        
        return  YES;
        
        
    }else{
        
        return result;
    }

}

- (NSArray *)selectTableWithSql:(NSString *)sql params:(NSArray *)params
{
    BOOL result = [self openDataBase];
    
    if (result == YES) {
        
        //定义编译sql语句的变量(数据句柄)
        sqlite3_stmt *stmt = NULL;
        //开始编译sql语句
       BOOL prepareResult = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, NULL);
        if (prepareResult == SQLITE_ERROR) {
            const char *errorMsg = sqlite3_errmsg(db);
            NSString *error = [NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding];
            NSLog(@"%@",error);
        }
        
        //绑定参数
        for (int i = 0; i < params.count; i++) {
            // 获取参数内容
            id param = params[i];
            if ([param isKindOfClass:[NSString class]] )
                sqlite3_bind_text(stmt, i+1, [param UTF8String], -1, SQLITE_TRANSIENT);
            if ([param isKindOfClass:[NSNumber class]] ) {
                if (!strcmp([param objCType], @encode(float)))
                    sqlite3_bind_double(stmt, i+1, [param doubleValue]);
                else if (!strcmp([param objCType], @encode(int)))
                    sqlite3_bind_int(stmt, i+1, [param intValue]);
                else if (!strcmp([param objCType], @encode(BOOL)))
                    sqlite3_bind_int(stmt, i+1, [param intValue]);
                else
                    NSLog(@"unknown NSNumber");
            }
            if ([param isKindOfClass:[NSDate class]]) {
                sqlite3_bind_double(stmt, i+1, [param timeIntervalSince1970]);
            }
            if ([param isKindOfClass:[NSData class]] ) {
                sqlite3_bind_blob(stmt, i+1, [param bytes], (int)[param length], SQLITE_STATIC);
            }
        }
        
        NSMutableArray *resultsArray = [NSMutableArray array];
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int columns = sqlite3_column_count(stmt);
            NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:columns];
            
            for (int i = 0; i<columns; i++) {
                const char *name = sqlite3_column_name(stmt, i);
                
                NSString *columnName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
                
                int type = sqlite3_column_type(stmt, i);
                
                switch (type) {
                    case SQLITE_INTEGER:
                    {
                        int value = sqlite3_column_int(stmt, i);
                        [result setObject:[NSNumber numberWithInt:value] forKey:columnName];
                        break;
                    }
                    case SQLITE_FLOAT:
                    {
                        float value = sqlite3_column_double(stmt, i);
                        [result setObject:[NSNumber numberWithFloat:value] forKey:columnName];
                        break;
                    }
                    case SQLITE_TEXT:
                    {
                        const char *value = (const char*)sqlite3_column_text(stmt, i);
                        [result setObject:[NSString stringWithCString:value encoding:NSUTF8StringEncoding] forKey:columnName];
                        break;
                    }
                        
                    case SQLITE_BLOB:
                    {
                        int bytes = sqlite3_column_bytes(stmt, i);
                        if (bytes > 0) {
                            const void *blob = sqlite3_column_blob(stmt, i);
                            if (blob != NULL) {
                                [result setObject:[NSData dataWithBytes:blob length:bytes] forKey:columnName];
                            }
                        }
                        break;
                    }
                        
                    case SQLITE_NULL:
                        [result setObject:[NSNull null] forKey:columnName];
                        break;
                        
                    default:
                    {
                        const char *value = (const char *)sqlite3_column_text(stmt, i);
                        [result setObject:[NSString stringWithCString:value encoding:NSUTF8StringEncoding] forKey:columnName];
                        break;
                    }
                        
                }
                
                
            }
            
            [resultsArray addObject:result];
            
        }
       
        //关闭数据句柄和数据库
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        
        return  resultsArray;
        
        
    }else{
        
        return nil;
    }
    
}

- (void) selectTableWithSql:(NSString *)sql params:(NSArray *)params finshBlock:(Myblock)block
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        NSArray *array =[self selectTableWithSql:sql params:params];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (block) {
                block(array);
            }
            
        });
        
    });
}



@end

demo的下载地址 吻我😄😄😄

相关文章

网友评论

    本文标题:iOS数据存储之Sqlite3封装

    本文链接:https://www.haomeiwen.com/subject/tsqonttx.html