IOS——从头介绍数据库sqlite3的创建,使用及可能出现的问题
2015-06-17 11:33
471 查看
首先导入数据库sqlite3.h,这个就不多说了(以项目Book为例)
1. 创建新的数据库,表格以及查询,插入,删除,更新操作。
1.1 创建一个.plist文件存储数据库数据
当然,这个文件也可以存储别的固定参数
方法:NewFile -> Resource选项 -> Property List(例如命名为BookDocumentSetting.plist)
添加两个键值对:
1.2 创建DBManager,统一创建,管理和获取数据库路径
不多说,贴代码:
.h文件
该Manager只能提供getDBPath方法
.m文件:
解释说明:
(1). initialize方法是每个类初次创建的时候系统都会调用的方法,无论你是否alloc,例如直接使用类方法[DBManager getDBPath], 系统都会调用initialize方法。
所以我把初始化数据库和创建表格的方法写在这里。
(2). 例子中创建的表格名字是AllBook,里面包含的参数有:BOOKID(自增长int类型,primary key),BOOKTYPE(int类型,记录书的类型),BOOKAMOUNT(书的价格,本来SQL3中有浮点数REAL,但是浮点存储不符合我的需求,所以使用String类型存储),TIME(记录时间)
(3). 需要更多的表格可以仿照方法createTable来写,添加到initTable即可。
(4). getDBPath是唯一给外界调用的方法,目的是确保数据库的路径正确,才可以打开数据库进行操作。
1.3 每个表格的增删改查操作(持续添加中)
实现对每个表格的数据操作,以AllBOOK为例,创建AllBOOKDAO
.h文件
.m文件
2. 如何使用现有数据库
例如数据库的名字叫做Test.db
3. 使用数据库可能出现的问题
3.1 提示database is locked解决方法
我在这里并没有使用多线程,我的问题是select语句没有进行reset操作
sqlite3_reset(selectStmt);
if(selectStmt)sqlite3_finalize(selectStmt);
添上这两行就好
1. 创建新的数据库,表格以及查询,插入,删除,更新操作。
1.1 创建一个.plist文件存储数据库数据
当然,这个文件也可以存储别的固定参数
方法:NewFile -> Resource选项 -> Property List(例如命名为BookDocumentSetting.plist)
添加两个键值对:
Key | Value |
DataBaseName | BookDatabase |
DataBaseDir | Database |
不多说,贴代码:
.h文件
#import <Foundation/Foundation.h> #import <sqlite3.h> #define BOOK_DOCUMENT_SETTING @"BookDocumentSetting" #define DB_DIRECTORY_KEY @"DataBaseDir" #define DB_NAME_KEY @"DataBaseName" #define BOOK_DB_RECORD_NOTFOUND -1 @interface DBManager : NSObject +(NSString *) getDBPath; @end
该Manager只能提供getDBPath方法
.m文件:
#import "DBManager.h" static sqlite3 *database=nil; @implementation DBManager + (void)initialize { if (self == [DBManager class]) { [DBManager initDB]; [DBManager initTables]; } } + (void) initDB { NSError *initDB_Error; //get db setting NSString *dbSettingPlist=[[NSBundle mainBundle] pathForResource:BOOK_DOCUMENT_SETTING ofType:@"plist"]; NSMutableDictionary *dbSettingDictionary=[[NSMutableDictionary alloc]initWithContentsOfFile:dbSettingPlist]; NSString *dbDir=[dbSettingDictionary objectForKey:DB_DIRECTORY_KEY]; NSString *dbName=[dbSettingDictionary objectForKey:DB_NAME_KEY]; //create db dir if not exists NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDir2 = [paths objectAtIndex:0]; NSString *dataPath = [documentsDir2 stringByAppendingPathComponent:dbDir]; if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){ if ([[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&initDB_Error]) { NSLog(@"initDB Database Dir created success"); }else{ NSLog(@"initDB Database Dir created failed"); } }else{ NSLog(@"initDB Database Dir did existed"); } //create DB if not exists //Using NSFileManager we can perform many file system operations. NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *dbPath = [DBManager getDBPath]; if ([fileManager fileExistsAtPath:dbPath]) { NSLog(@"DB file exists"); }else{ if (sqlite3_open([[DBManager getDBPath] UTF8String], &database) == SQLITE_OK) { NSLog(@"initDB Database Created Success"); sqlite3_close(database); } else { NSLog(@"initDB Databse Created Failed"); } } } +(void)initTables{ NSLog(@"start to initTables"); if (sqlite3_open([[self getDBPath] UTF8String], &database) == SQLITE_OK) { [self createTable_AllBook]; <pre name="code" class="objc"> // 这里可以插入多条创建Table的代码 }else{ NSLog(@"initTables Failed"); } sqlite3_close(database); } +(BOOL)createTable_AllBook{ char *errorMsg=NULL; const char *sql_stmt2 = "CREATE TABLE IF NOT EXISTS ALLBOOK (BOOKID INTEGER PRIMARY KEY AUTOINCREMENT, BOOKTYPE INTEGER, BOOKAMOUNT TEXT, TIME TEXT)"; if (sqlite3_exec(database, sql_stmt2, NULL, NULL, &errorMsg) == SQLITE_OK) { NSLog(@"Create table AllBook success"); return YES; }else{ NSLog(@"Create table AllBook failed"); return NO; } } +(NSString *) getDBPath{ NSError *error; NSString *dbSettingPlist=[[NSBundle mainBundle] pathForResource:BOOK_DOCUMENT_SETTING ofType:@"plist"]; NSMutableDictionary *dbSettingDictionary=[[NSMutableDictionary alloc]initWithContentsOfFile:dbSettingPlist]; NSString *dbDir=[dbSettingDictionary objectForKey:DB_DIRECTORY_KEY]; NSString *dbName=[dbSettingDictionary objectForKey:DB_NAME_KEY]; //create db dir if not exists NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDir2 = [paths objectAtIndex:0]; NSString *dataPath = [documentsDir2 stringByAppendingPathComponent:dbDir]; if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){ if ([[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]) { NSLog(@"getDBPath Database create successed"); }else{ NSLog(@"getDBPath Databse DIR create failed"); } }else{ NSLog(@"getDBPath Database is existed."); } return [[NSMutableString stringWithString:dataPath] stringByAppendingPathComponent:[dbName stringByAppendingString:@".sqlite"]]; }
解释说明:
(1). initialize方法是每个类初次创建的时候系统都会调用的方法,无论你是否alloc,例如直接使用类方法[DBManager getDBPath], 系统都会调用initialize方法。
所以我把初始化数据库和创建表格的方法写在这里。
(2). 例子中创建的表格名字是AllBook,里面包含的参数有:BOOKID(自增长int类型,primary key),BOOKTYPE(int类型,记录书的类型),BOOKAMOUNT(书的价格,本来SQL3中有浮点数REAL,但是浮点存储不符合我的需求,所以使用String类型存储),TIME(记录时间)
(3). 需要更多的表格可以仿照方法createTable来写,添加到initTable即可。
(4). getDBPath是唯一给外界调用的方法,目的是确保数据库的路径正确,才可以打开数据库进行操作。
1.3 每个表格的增删改查操作(持续添加中)
实现对每个表格的数据操作,以AllBOOK为例,创建AllBOOKDAO
.h文件
#import <Foundation/Foundation.h> #import <sqlite3.h> #import "DBManager.h" @interface AllBookDAO : NSObject{ int bookID; int bookType; NSString *bookAmount; NSString *time; } @property (nonatomic, readwrite) int bookID; @property (nonatomic, readwrite) int bookType; @property (nonatomic, readwrite,retain) NSString *bookAmount; @property (nonatomic, readwrite,retain) NSString *time; + (NSMutableArray *) getAllBookList; @end
.m文件
#import "AllBookDAO.h" @implementation AllBookDAO @synthesize bookID,bookType,bookAmount,time; static sqlite3 *database = nil; //查询 + (NSMutableArray *) getAllBookList{ NSMutableArray *resultArray = [[NSMutableArray alloc] init ]; if (sqlite3_open([[DBManager getDBPath] UTF8String], &database) == SQLITE_OK) { const char *sql = "select BOOKID,BOOKTYPE,BOOKAMOUNT,TIME from ALLBOOK"; sqlite3_stmt *selectstmt; if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { while(sqlite3_step(selectstmt) == SQLITE_ROW) { AllBookDAO *allBook = [[AllBookDAO alloc] init]; allBook.bookID = sqlite3_column_int(selectstmt, 0); allBook.bookType=sqlite3_column_int(selectstmt, 1); allBook.bookAmount=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]; allBook.time = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)]; [resultArray addObject:allBook]; } } sqlite3_reset(selectstmt); if(selectstmt) sqlite3_finalize(selectstmt); } else{ NSLog(@"Open Database Failed."); } sqlite3_close(database); return resultArray; } @end
2. 如何使用现有数据库
例如数据库的名字叫做Test.db
NSString *dbFilePath = [[NSBundlemainBundle]pathForResource:@"数据库名字,如Test"ofType:@"db"]; NSLog(@"DB file path: %@",dbFilePath); // FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbFilePath]; sqlite3 *database; if (sqlite3_open([dbFilePathUTF8String], &database) ==SQLITE_OK) { NSLog(@"DB open success"); } else { sqlite3_close(database); NSLog(@"DB open failed"); }
3. 使用数据库可能出现的问题
3.1 提示database is locked解决方法
我在这里并没有使用多线程,我的问题是select语句没有进行reset操作
sqlite3_reset(selectStmt);
if(selectStmt)sqlite3_finalize(selectStmt);
添上这两行就好
相关文章推荐
- Oracle Analyze
- Redis 作为缓存服务器的配置
- 主从复制同步mysql数据库后会导致从上用户无法登陆
- MySQL 基本操作
- innodb聚集索引与非聚集索引区别
- 连接Oracle时报错ORA-12541: TNS: 无监听程序
- 关于权限的数据库设计
- python cx_Oracle模块的安装和使用
- MySQL更改表的存储引擎
- oracle 数据类型详解---日期型
- sqlserver
- RHEL 6/CentOS 6上安装Oracle 11.2.0.3(Gird/Database)及以上缺少pdksh包的解决方法
- 插入到MySql数据库中乱码问题
- (error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.
- oracle数据库中varchar2陷阱
- MySQL数据库读写分离amoeba技术研究分享
- SQLServer——如何完整地复制一个数据库
- Spark-sql 运行提示too many open files
- MySQL 索引优化全攻略
- VB使用ADO操作Access数据库