使用 SQLiteManager 操作 sqlite3 数据库

前端之家收集整理的这篇文章主要介绍了使用 SQLiteManager 操作 sqlite3 数据库前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

sqliteManager

https://github.com/misato/SQLiteManager4iOS

本人以前从事过嵌入式开发,后来转职为iOS开发,即使如此,也绝不想去碰C语言级别的面向过程的 sqlite3 来操作数据库,做高级语言开发还去折腾面向过程的东西,一个小小的nil没判断好就导致程序崩溃,这就是 sqlite3 APIs 给你带来的问题,只有封装成面向对象的接口才有可能会去用.有一个封装得挺好的 FMDB 是不二的选择,但这个 sqliteManager 属于轻量级封装,满足了最最基本的需求,但是,他是在开了ARC的情形下使用的,也就是说,没开ARC后会各种泄露......

上面的链接可以下载源码,修改了源码,适用于我自己,提供如下:

sqliteManager.h

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


enum errorCodes {
    kDBNotExists,kDBFailAtOpen,kDBFailAtCreate,kDBErrorQuery,kDBFailAtClose
};

@interface sqliteManager : NSObject {

    sqlite3 *db; // The sqlite db reference
    NSString *databaseName;  The database name
}

- (id)initWithDatabaseNamed:(NSString *)name;

 sqlite Operations
- (NSError *) openDatabase;
- (NSError *) doQuery:(NSString *)sql;
- (NSError *)doUpdateQuery:(NSString *)sql withParams:(NSArray *)params;
- (NSArray *) getRowsForQuery:(NSString *)sql;
- (NSError *) closeDatabase;
- (NSInteger)getLastInsertRowID;

- (NSString *)getDatabaseDump;

@end

sqliteManager.m

sqliteManager.h#define FOLDER_PATH @"/Library/Caches/YOU_FOLDER_NAME" Private methods @interface sqliteManager (Private) - (NSString *)getDatabasePath; - (NSError *)createDBErrorWithDescription:(NSString*)description andCode:(int)code; @end @implementation sqliteManager #pragma mark Init & Dealloc /** * Init method. * Use this method to initialise the object,instead of just "init". * * @param name the name of the database to manage. * * @return the sqliteManager object initialised. */ - (id)initWithDatabaseNamed:(NSString *)name; { self = [super init]; if (self != nil) { databaseName = [[NSString alloc] initWithString:name]; db = nil; } return self; } #pragma mark sqlite Operations * * Open or create a sqlite3 database. * * If the db exists,then is opened and ready to use. If not exists then is created and opened. * * @return nil if everything was ok,an NSError in other case. * */ - (NSError *) openDatabase { NSError *error = nil; NSString *databasePath = [self getDatabasePath]; NSLog(@"%@",databasePath); const char *dbpath = [databasePath UTF8String]; int result = sqlite3_open(dbpath,&db); if (result != sqlITE_OK) { char *errorMsg = sqlite3_errmsg(db); NSString *errorStr = [NSString stringWithFormat:The database could not be opened: %@ [self createDBErrorWithDescription:errorStr andCode:kDBFailAtOpen]; } return error; } * * Does an sql query. * * You should use this method for everything but SELECT statements. * * @param sql the sql statement. * * @return nil if everything was ok,NSError in other case. */ - (NSError *)doQuery:(NSString *)sql { NSError *openError = nil; NSError *errorQuery = nil; Check if database is open and ready. if (db == nil) { openError = [self openDatabase]; } if (openError == nil) { sqlite3_stmt *statement; char *query = [sql UTF8String]; sqlite3_prepare_v2(db,query,-1,&statement,NULL); if (sqlite3_step(statement) == sqlITE_ERROR) { char *errorMsg = sqlite3_errmsg(db); errorQuery = [self createDBErrorWithDescription:[NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding] andCode:kDBErrorQuery]; } sqlite3_finalize(statement); errorQuery = [self closeDatabase]; } else { errorQuery = openError; } return errorQuery; } * * Does an sql parameterized query. * * You should use this method for parameterized INSERT or UPDATE statements. * * @param sql the sql statement using ? for params. * * @param params NSArray of params type (id),in CORRECT order please. * * @return nil if everything was ok,0)">*/ - (NSError *)doUpdateQuery:(NSString *)sql withParams:(NSArray *)params { NSError *openError = nil; NSError *errorQuery = nil; BIND the params! int count =0; for (id param in params ) { count++; if ([param isKindOfClass:[NSString class]] ) sqlite3_bind_text(statement,count,[param UTF8String],128)">1,sqlITE_TRANSIENT); if ([param isKindOfClass:[NSNumber class]] ) { if (!strcmp([param objCType],@encode(float))) sqlite3_bind_double(statement,[param doubleValue]); else int))) sqlite3_bind_int(statement,[param intValue]); if (!strcmp([param objCType],@encode(BOOL))) sqlite3_bind_int(statement,255)">else NSLog(unknown NSNumber"); } if ([param isKindOfClass:[NSDate class]]) { sqlite3_bind_double(statement,[param timeIntervalSince1970]); } if ([param isKindOfClass:[NSData class]] ) { sqlite3_bind_blob(statement,[param bytes],[param length],sqlITE_STATIC); } } return errorQuery; } - (NSInteger)getLastInsertRowID { NSError *openError = nil; sqlite3_int64 rowid = 0; if (openError == nil) { rowid = sqlite3_last_insert_rowid(db); } return (NSInteger)rowid; } * * Does a SELECT query and gets the info from the db. * * The return array contains an NSDictionary for row,made as: key=columName value= columnValue. * * For example,if we have a table named "users" containing: * name | pass * ------------- * admin| 1234 * pepe | 5678 * * it will return an array with 2 objects: * resultingArray[0] = name=admin,pass=1234; * resultingArray[1] = name=pepe,pass=5678; * * So to get the admin password: * [[resultingArray objectAtIndex:0] objectForKey:@"pass"]; * * @param sql the sql query (remember to use only a SELECT statement!). * * @return an array containing the rows fetched. */ - (NSArray *)getRowsForQuery:(NSString *)sql { NSMutableArray *resultsArray = [[NSMutableArray alloc] initWithCapacity:1]; if (db == nil) { [self openDatabase]; } sqlite3_stmt *statement; char *query = [sql UTF8String]; int returnCode = sqlite3_prepare_v2(db,-if (returnCode == sqlITE_ERROR) { char *errorMsg = sqlite3_errmsg(db); NSError *errorQuery = [self createDBErrorWithDescription:[NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding] andCode:kDBErrorQuery]; NSLog(while (sqlite3_step(statement) == sqlITE_ROW) { int columns = sqlite3_column_count(statement); NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:columns]; int i = 0; i<columns; i++) { char *name = sqlite3_column_name(statement,i); NSString *columnName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; int type = sqlite3_column_type(statement,i); switch (type) { case sqlITE_INTEGER: { int value = sqlite3_column_int(statement,i); [result setObject:[NSNumber numberWithInt:value] forKey:columnName]; break; } case sqlITE_FLOAT: { float value = sqlite3_column_double(statement,i); [result setObject:[NSNumber numberWithFloat:value] forKey:columnName]; case sqlITE_TEXT: { char *value = (char*)sqlite3_column_text(statement,i); [result setObject:[NSString stringWithCString:value encoding:NSUTF8StringEncoding] forKey:columnName]; break; } case sqlITE_BLOB: { int bytes = sqlite3_column_bytes(statement,i); if (bytes > 0) { void *blob = sqlite3_column_blob(statement,i); if (blob != NULL) { [result setObject:[NSData dataWithBytes:blob length:bytes] forKey:columnName]; } } case sqlITE_NULL: [result setObject:[NSNull null] forKey:columnName]; break; default: { char *)sqlite3_column_text(statement,255)">break; } } end switch } end for [resultsArray addObject:result]; } end while sqlite3_finalize(statement); [self closeDatabase]; return resultsArray; } * * Closes the database. * * @return nil if everything was ok,0)">*/ - (NSError *) closeDatabase { NSError *error = nil; if (db != nil) { if (sqlite3_close(db) != sqlITE_OK){ char *errorMsg = sqlite3_errmsg(db); NSString *errorStr = [NSString stringWithFormat:The database could not be closed: %@ [self createDBErrorWithDescription:errorStr andCode:kDBFailAtClose]; } db = nil; } * * Creates an sql dump of the database. * * This method could get a csv format dump with a few changes. * But i prefer working with sql dumps ;) * * @return an NSString containing the dump. */ - (NSString *)getDatabaseDump { NSMutableString *dump = [[NSMutableString alloc] initWithCapacity:256]; info string ;) please do not remove it [dump appendString:;\n; Dump generated with sqliteManager4iOS \n;\n; By Misato (2011)\n"]; [dump appendString:[NSString stringWithFormat:; database %@;\n first get all table information NSArray *rows = [self getRowsForQuery:SELECT * FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"]; last sql query returns something like: { name = users; rootpage = 2; sql = "CREATE TABLE users (id integer primary key autoincrement,user text,password text)"; "tbl_name" = users; type = table; } loop through all tables 0; i<[rows count]; i++) { NSDictionary *obj = [rows objectAtIndex:i]; get sql "create table" sentence NSString *sql = [obj objectForKey:sql"]; [dump appendString:[NSString stringWithFormat:%@;\nsql]]; get table name NSString *tableName = [obj objectForKey:name"]; get all table content NSArray *tableContent = [self getRowsForQuery:[NSString stringWithFormat:SELECT * FROM %@int j = 0; j<[tableContent count]; j++) { NSDictionary *item = [tableContent objectAtIndex:j]; keys are column names NSArray *keys = [item allKeys]; values are column values NSArray *values = [item allValues]; start constructing insert statement for this item [dump appendString:[NSString stringWithFormat:insert into %@ (loop through all keys (aka column names) NSEnumerator *enumerator = [keys objectEnumerator]; id obj; while (obj = [enumerator nextObject]) { [dump appendString:[NSString stringWithFormat:%@,delete last comma NSRange range; range.length = 1; range.location = [dump length]-1; [dump deleteCharactersInRange:range]; [dump appendString:) values ("]; loop through all values value types could be: NSNumber for integer and floats,NSNull for null or NSString for text. enumerator = [values objectEnumerator]; while (obj = [enumerator nextObject]) { if it's a number (integer or float) if ([obj isKindOfClass:[NSNumber class]]){ [dump appendString:[NSString stringWithFormat:if it's a null if ([obj isKindOfClass:[NSNull class]]){ [dump appendString:null,0)">"]; } else is a string ;) else{ [dump appendString:[NSString stringWithFormat:'%@',obj]]; } } delete last comma again range.length = 1; [dump deleteCharactersInRange:range]; finish our insert statement [dump appendString:);\n"]; } } return dump; } @end #pragma mark - @implementation sqliteManager (Private) * * Gets the database file path (in NSDocumentDirectory). * * @return the path to the db file. */ - (NSString *)getDatabasePath{ if([[NSFileManager defaultManager] fileExistsAtPath:databaseName]){ Already Full Path return databaseName; } else { 判断文件夹是否存在,不存在则创建文件 NSString *docsDir = [NSHomeDirectory() stringByAppendingString:FOLDER_PATH]; if (sqliteManager_fileOrFolderExistFromSandBox(docsDir) == NO) { sqliteManager_createFolderForSandBox(docsDir); } return [docsDir stringByAppendingPathComponent:databaseName]; } } #pragma mark 沙盒中创建文件 BOOL sqliteManager_createFolderForSandBox(NSString *filePath) { return [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil]; } #pragma mark 文件或者文件夹是否存在 BOOL sqliteManager_fileOrFolderExistFromSandBox(NSString *filePath) { return [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO]; } * * Creates an NSError. * * @param description the description wich can be queried with [error localizedDescription]; * @param code the error code (code erors are defined as enum in the header file). * * @return the NSError just created. * */ - (NSError *)createDBErrorWithDescription:(NSString*)description andCode:(int)code { NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:description,NSLocalizedDescriptionKey,nil]; NSError *error = [NSError errorWithDomain:sqlite Error" code:code userInfo:userInfo]; return error; }
以下是增删改查以及常规操作:

打开数据库

    打开数据库
    sqliteManager *dbManager = [[sqliteManager alloc] initWithDatabaseNamed:@"Y.X.db"];

创建表

    NSError *error = nil;
    创建表
    
     id        int    主键
     user      text
     password  text
     */
    error = [dbManager doQuery:CREATE TABLE IF NOT EXISTS users (id integer primary key autoincrement,password text);if (error != nil) {
        NSLog(Error: %@ 
   插入

在表中插入一条记录 error = [dbManager doQuery:insert into users (user,password) values ('YouXian','19871220'); 查询

查询记录 [[dbManager getRowsForQuery:SELECT * FROM users"] enumerateObjectsUsingBlock:^(id obj,NSUInteger idx,BOOL *stop) { NSLog( 修改

修改一条记录 error = [dbManager doQuery:update users set user = 'YX',password = '1' where id = 1; 删除

删除一条记录 error = [dbManager doQuery:delete from users where id = 1;

心得:

如果觉得自己想去捣鼓 C 语言级别的 API 不怕崩溃,可以去试试,对于我而言,不是我对其不感兴趣不愿意研究他,只是,在对性能没有要求的前提下花精力去造车轮子完全没有必要,真心话.

原文链接:https://www.f2er.com/sqlite/200620.html

猜你在找的Sqlite相关文章