1.简介

本文将介绍IOS的开发过程中如何集成Sqlite的方法,目前Sqlite的版本为3,所以我们称之为Sqlite3.

在本文中我将介绍Sqlite3的开发配置,本地Sqlite3数据库的建立通用的数据库访问类。

2.Sqlite3的开发环境配置

1.在工程中引入SQlite3开发库。

按照下图进行设定:

3.建立Sqlite数据库和表

1.打开终端窗口,输入如下命令:

172-11-253-106:~ apple$ sqlite3 exampleSqlite3_db.sql

SQLite version 3.8.5 2014-08-15 22:37:57

Enter ".help" for usage hints.

sqlite>

如上我们建立了一个名为exampleSqlite3_db的数据库。

2.建表

CREATE TABLE peopleInfo(peopleInfoID integer primary key, firstname text, lastname text, age integer);

表建立完毕后我们可以通过命令查询表是否建立成功:

sqlite> .tables
peopleInfo
sqlite>

随后退出:

sqlite> .quit
172-11-253-106:~ apple$

3. 至此本地所需要的数据库和表初始化完毕,将文件导入当前工程

4.至此本地数据库和数据库连接文件都已经创建完毕。

4.建立通用的数据库访问类

1.建立数据库model

#import <Foundation/Foundation.h>

@interface PeopleInfo : NSObject
@property(nonatomic, assign) NSInteger peopleInfoID;
@property(nonatomic, strong) NSString * firstname;
@property(nonatomic, strong) NSString * lastname;
@property(nonatomic, assign) NSInteger age;

@end

2.建立通用的Sqlite3访问类

.h文件

//
//  DBManager.h
//  how_to_playwith_Sqlite3
//
//  Created by apple on 15/12/14.
//  Copyright © 2015年 xufeng. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 *  Sqlite3访问类
 */
@interface DBManager : NSObject

/**
 *  sql执行后受影响的行数,如delete、insert和update的时候可以以此判断数据库是否操作正常
 */
@property (nonatomic) int affectedRows;

/**
 *  记录最后一次的操作索引
 */
@property (nonatomic) long long lastInsertedRowID;

/**
 *  加载数据库文件
 *
 *  @param dbFilename 沙盘中的数据库文件
 *
 *  @return 数据库操作handler
 */
-(instancetype)initWithDatabaseFilename:(NSString *)dbFilename;

/**
 *  执行查询操作
 *
 *  @param query 查询语句
 *
 *  @return 查询结果
 */
-(NSArray *)loadDataFromDB:(NSString *)query;

/**
 *  执行增删和更新的语句
 *
 *  @param query 执行语句
 */
-(void)executeQuery:(NSString *)query;
@end

.m文件

//
//  DBManager.m
//  how_to_playwith_Sqlite3
//
//  Created by apple on 15/12/14.
//  Copyright © 2015年 apple. All rights reserved.
//

#import "DBManager.h"
#import <sqlite3.h>

@interface DBManager()

/**
 *  应用的Documents Directory
 */
@property (nonatomic, strong) NSString *documentsDirectory;

/**
 *  数据库文件
 */
@property (nonatomic, strong) NSString *databaseFilename;

/**
 *  结果数组
 */
@property (nonatomic, strong) NSMutableArray *arrResults;

/**
 *  将bundle中的文件拷贝到Documents Directory
 */
-(void)copyDatabaseIntoDocumentsDirectory;

/**
 *  执行SQLite语句
 *
 *  @param query           SQLite语句
 *  @param queryExecutable 查询还是修改
 */
-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable;
@end

@implementation DBManager

-(instancetype)initWithDatabaseFilename:(NSString *)dbFilename{
    self = [super init];
    if (self) {
        // 查找Documents Directory路径
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        self.documentsDirectory = [paths objectAtIndex:];

        // 保存传入的数据库文件
        self.databaseFilename = dbFilename;

        // 将bundle中的文件拷贝到Documents Directory
        [self copyDatabaseIntoDocumentsDirectory];
    }
    return self;
}

-(void)copyDatabaseIntoDocumentsDirectory{
    // 查询数据库文件是否在ocuments Directory已经存在?
    NSString *destinationPath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
    if (![[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
        // 如果不不存在则从bundle中将数据库文件拷贝到Documents Directory
        NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseFilename];
        NSError *error;
        [[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destinationPath error:&error];

        // 查看是够有错误
        if (error != nil) {
            NSLog(@"%@", [error localizedDescription]);
        }
    }
}

-(NSArray *)loadDataFromDB:(NSString *)query{
    // 执行查询
    [self runQuery:[query UTF8String] isQueryExecutable:NO];

    // 返回查询结果
    return (NSArray *)self.arrResults;
}

-(void)executeQuery:(NSString *)query{
    // 执行修改操作
    [self runQuery:[query UTF8String] isQueryExecutable:YES];
}

-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable
{
    // 数据库连接变量
    sqlite3 *sqlite3Database;

    // 设定数据库文件
    NSString *databasePath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];

    // 重置结果容器
    if (self.arrResults != nil) {
        [self.arrResults removeAllObjects];
        self.arrResults = nil;
    }
    self.arrResults = [[NSMutableArray alloc] init];

    // 打开数据库
    int openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
    if(openDatabaseResult == SQLITE_OK) {
        // Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement.
        sqlite3_stmt *compiledStatement;

        // Load all data from database to memory.
        , &compiledStatement, NULL);
        if(prepareStatementResult == SQLITE_OK) {
            // Check if the query is non-executable.
            if (!queryExecutable){
                // In this case data must be loaded from the database.

                // Declare an array to keep the data for each fetched row.
                NSMutableArray *arrDataRow;

                // Declare an array to keep the col name for each fetched row.
                NSMutableArray *arrColRow;

                // Loop through the results and add them to the results array row by row.
                while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                    // Initialize the mutable array that will contain the data of a fetched row.
                    arrDataRow = [[NSMutableArray alloc] init];
                    arrColRow = [[NSMutableArray alloc] init];

                    // Get the total number of columns.
                    int totalColumns = sqlite3_column_count(compiledStatement);

                    // Go through all columns and fetch each column data.
                    ; i<totalColumns; i++){
                        // Convert the column data to text (characters).
                        char *dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);
                        char *dbColAsChars = (char *)sqlite3_column_name(compiledStatement, i);

                        // If there are contents in the currenct column (field) then add them to the current row array.
                        if (dbDataAsChars != NULL) {
                            // Convert the characters to string.
                            [arrDataRow addObject:[NSString  stringWithUTF8String:dbDataAsChars]];
                            [arrColRow addObject:[NSString  stringWithUTF8String:dbColAsChars]];
                        }
                    }

                    // Store each fetched data row in the results array, but first check if there is actually data.
                    ) {
                        // first of all, we should put them in dictionary
                        [self.arrResults addObject:[NSDictionary dictionaryWithObjects:arrDataRow forKeys:arrColRow]];
                    }
                }
            }
            else {
                // This is the case of an executable query (insert, update, ...).

                // Execute the query.
                int executeQueryResults = sqlite3_step(compiledStatement);
                if (executeQueryResults == SQLITE_DONE) {
                    // Keep the affected rows.
                    self.affectedRows = sqlite3_changes(sqlite3Database);

                    // Keep the last inserted row ID.
                    self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database);
                }
                else {
                    // If could not execute the query show the error message on the debugger.
                    NSLog(@"DB Error: %s", sqlite3_errmsg(sqlite3Database));
                }
            }
        }
        else {
            // In the database cannot be opened then show the error message on the debugger.
            NSLog(@"%s", sqlite3_errmsg(sqlite3Database));
        }

        // Release the compiled statement from memory.
        sqlite3_finalize(compiledStatement);
    }

    // Close the database.
    sqlite3_close(sqlite3Database);
}
@end

3. 测试(先插入后查询)

插入如下测试语句:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // 数据库客户端操作-打开
    DBManager *dbm = [[DBManager alloc] initWithDatabaseFilename:@"exampleSqlite3_db.sql"];

    // 数据库客户端操作-插入s
    [dbm executeQuery:@"insert into peopleInfo values(100,'zhang','san',20)"];

     != dbm.affectedRows) {
        NSLog(@"%@", @"error happend!");
    }
    else{
        // 数据库客户端操作-查询
        NSArray *result = [dbm loadDataFromDB:@"select * from peopleInfo"];

        // 每行既是一个item,将其转化为具体的对象
        PeopleInfo *peopleInfo = nil;
        NSMutableArray *resultArray = [[NSMutableArray alloc] init];
        for (NSDictionary *rowDict in result)
        {
            peopleInfo = [[PeopleInfo alloc] init];
            // 使用方法的时候必须model的属性名称和字典的key要保持完全一致
            [peopleInfo setValuesForKeysWithDictionary:rowDict];
            [resultArray addObject:peopleInfo];
        }

        NSLog(@"%@", resultArray);
    }
}

结果:

至此Sqlite3的集成方法介绍完毕。

[How to]集成SQLite3的更多相关文章

  1. delphi Sqlite

    Delphi中SQLite如何读写二进制字段(Blob类型) 在Delphi中,有大量的组件可以操作SQLite数据库,如UniDAC就是其中一个比较优秀的,当然还有ASQLite3Component ...

  2. 从零开始用electron整个跨平台桌面应用---基础配置篇

    1.安装node.npm node以及npm都需要是最新版本(版本过低有坑) 2.安装淘宝镜像cnpm(建议,下载较快) npm install -g cnpm --registry=https:// ...

  3. electron 集成 nedb / sqlite3

    nedb nedb 无法创建文件 // webpack 构建的前提 externals: process.env.web ? {} : { "nedb": "requir ...

  4. Python开发入门与实战9-基于vs的集成开发环境

    9. 基于visual studio的Python的集成开发环境 上一章我们描述了如何安装使用Java的集成开发环境Eclipse IDE,本章我们来说明另一种集成开发环境,也是笔者多年的开发习惯使用 ...

  5. 第三十三章 metrics(1) - graphite搭建 + whisper存储模式 + 高精度向低精度聚合方式 + 集成StatsD + 集成grafana

    组件介绍: carbon:Carbon实际上是一系列守护进程,组成一个Graphite安装的存储后端.这些守护进程用一个名为Twisted的事件驱动网络引擎监听时间序列数据.Twisted框架让Car ...

  6. 【解决】Django项目废弃SQLite3拥抱MySQL

    SQLite3数据库就一个文件,拷贝着随时带走,调试方便,超级轻量级,有它的好处. 不过,MySQL才是中小项目的主流,最近想把Django里程碑项目部署到SAE上,所以试着把原来的项目数据库替换成M ...

  7. Android adb使用sqlite3对一个数据库进行sql查询

    sqlite是Android下集成的一个轻量级数据库,我们可以通过adb程序进入数据库命令行,对数据进行查询,具体操作如下: ①打开windows的cmd ②输入adb shell.此时进入了该安卓系 ...

  8. Cloud Foundry中 JasperReports service集成

    Cloud Foundry作为业界第一个开源的PaaS解决方案,正越来越多的被业界接受和认可.随着PaaS的发展,Cloud Foundry顺应潮流,充分发挥开源项目的特点,到目前为止,已经支持了大批 ...

  9. apache+php+mysql常见集成环境安装包

    http://www.thinksaas.cn/group/topic/33/ apache+php+mysql是常见php环境,在windows下也称为WAMP,对于初学者自选版本搭建总是会遇到一些 ...

随机推荐

  1. 在git 服务器挂载、创建新的项目、克隆新的项目

     流程,服务器创建项目名-->客户端克隆-->客户端提交并且推送-->完成   详细步骤   1.在git服务器路径文件夹下创建空文件夹,名字为新的项目名,如在  F:\git   ...

  2. Unity游戏开发技术的最佳实践

    活动详情   作为全球规模最大的Unity开发者聚会,历年的Unite大会都成为开发者们获取Unity最新技术知识,交流开发经验,把握行业发展脉搏,体验全球前沿科技与高品质Made with Unit ...

  3. eclipse里配置Android ndk环境,用eclipse编译.so文件

    做Android NDK开发时,c代码需要用ndk-build来进行编译,而java代码则需要用Android sdk编译. 编译c代码有两种方法: 一.写好c代码后,然后用cygwin搭建ndk-b ...

  4. 关于wesocket大文件通讯的切片实现方法

    关于websocket的实现网上很多资料这里就不详说,这里大概讲我在websocket传输大文件的时的方法,websocket传输单个文件最大不能超过7kg,否则前段自动断掉,当我们用来语音通讯时,通 ...

  5. GYM 101875 2018 USP-ICMC

    3月自训 (1):10/12 A: 题意:每个人可以连边,最远连到第(i+k)%n个人,边权为这个人与另一个人连边距离,求生成一颗最大生成树的权值和是多少 题解:可以证明的是,我们每一个人都向接下来的 ...

  6. HDU3585 最大团+二分

    maximum shortest distance Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  7. 有向图的强联通分量 Tarjan算法模板

    //白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...

  8. [Android篇]Android Studio + Genymotion 一夜无眠 ,超级详细版本[请使用新版2.0]

    环境说明:这里很重要,因为我在windows10中吃过很多的亏 操作系统: windows 7 64位系统 JDK 64位 : jdk1.7.0_75 注意我这里吃过亏!都用64位的! Android ...

  9. 【c#】winform 上传图片

    1.拖拽上传图片 1.1.后台代码中修改窗体属性,添加 AllowDrop = true 1.2.给窗体添加拖拽事件,在事件列表找到拖拽 双击即可: 在 DragDrop 生成的方法中添加代码如下: ...

  10. LightOJ 1151 - Snakes and Ladders 高斯消元+概率DP

    首先来个期望的论文,讲的非常好,里面也提到了使用线性方程组求解,尤其适用于有向图的期望问题. 算法合集之<浅析竞赛中一类数学期望问题的解决方法> http://www.lightoj.co ...