您的位置:首页 > 数据库

[How to]集成SQLite3

2015-12-14 15:19 363 查看
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:0];

// 保存传入的数据库文件
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.
int prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &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.
for (int i=0; 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.
if (arrDataRow.count > 0) {
// 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)"];

if (1 != 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的集成方法介绍完毕。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: