Sqlite3 目标 c 单例数据库连接在执行准备好的语句之前关闭我在目标 c 中创建了一个单例数据库连接,但它在执行准备好的语句之前关闭。
我来自 java 背景,这是我的第一个 xcode 项目。使用 xcode 4.5.2。我只想建立一个所有文件都可以使用的数据库连接。我查看了许多有关该主题的留言板,并花了难以置信的时间试图解决它,我似乎无法解决这个问题。如果有人能解释在执行准备好的语句之前我需要做什么才能使 sql 连接不关闭,我将不胜感激。我在下面包含了代码和运行时输出。
我制作了一个数据库单例并在 appDelegate 中成功初始化它。然后在我需要连接的类中,我指的是这样的数据库连接:
[Database database];
db = [database getSqlite3Connection];
在我使用之前:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]
delegate];
db = [appDelegate db];
在这两种情况下,代码都会运行但无法执行准备好的语句。但是,当我将创建数据库连接代码放入需要使用连接的类时,连接执行准备好的语句没有问题:即:
NSString *dbPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:@"hsk1.sqlite"];
if (sqlite3_open([dbPath UTF8String], &dbConnection) != SQLITE_OK)
我对这些类如何接收全局 sqlite3 连接感到困惑。有人可以告诉这是否是正确的方法:
在我的数据库类中,我使用此代码将我创建的数据库对象传递给 sqlite3,因此我可以将它用于我所有类的准备语句:
sqlite3 *dbConnection = (__bridge sqlite3 *)(database);
我的代码:
// AppDelegate.h
// StoryboardTutorial
#import <UIKit/UIKit.h>
#import "Database.h"
#import <sqlite3.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic,readonly) Database *database;
@property (nonatomic,readonly) sqlite3 *db;
@end
// AppDelegate.m
// StoryboardTutorial
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize database;
@synthesize db;
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[Database database];
db = [database getSqlite3Connection];
return YES;
}
// Database.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
@interface Database : NSObject {
}
+ (Database *)database;
- (id)init;
+ (Database *)getInstance;
-(sqlite3 *)getSqlite3Connection;
- (void)dealloc;
@end
//
// database.m
//
#import "Database.h"
@implementation Database
static Database *database;
sqlite3 *dbConnection =nil;
+ (Database*)database {
if (database == nil) {
database = [[Database alloc] init];
}
return database;
}
- (id)init{
if (self = [super init]) {
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]
stringByAppendingPathComponent:@"hsk1.sqlite"];
NSLog(@"DB CONNECTION - INTIALISING NEW CONNECTION");
if (sqlite3_open([dbPath UTF8String], &dbConnection) != SQLITE_OK) {
NSLog(@"[SQLITE] Unable to open database!");
return nil; // if it fails, return nil obj
}
dbConnection = (__bridge sqlite3 *)(database);
NSLog(@"*DB CONNECTION Address: %p", database);
}
return self;
}
+(Database *)getInstance {
@synchronized(self)
{
NSLog(@"*DB CONNECTION getInstance:");
if (database == nil){
NSLog(@"DB CONNECTION - none");
database = [[self alloc] init];
NSLog(@"DB CONNECTION getInstance() Address: %p", database);
}
}
return(database);
}
-(sqlite3*)getSqlite3Connection {
return dbConnection;
}
- (void)dealloc {
NSLog(@"DB CONNECTION*Closing Connection");
sqlite3_close(dbConnection);
}
@end
// ViewController.h
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController : UIViewController<UITableViewDelegate,
UITableViewDataSource, AVAudioPlayerDelegate>{
AVAudioPlayer *audioPlayer;
}
@property(nonatomic, retain)NSMutableArray *wordListsArray;
@end
// ViewController.m
//
#import "ViewController.h"
#import "WordLists.h"
#import "Database.h"
#import "AppDelegate.h"
@implementation ViewController
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
int wordid =1;
WordLists * mywords =[[WordLists alloc] init];
self.wordListsArray = [mywords getWordforId:(NSInteger)wordid];
}
// WordLists.h
//
#import <Foundation/Foundation.h>
@interface WordLists : NSObject{
}
- (NSMutableArray *) getWordforId :(NSInteger)wordid;
@end
// WordLists.m
//
#import "AppDelegate.h"
#import "WordLists.h"
#import "Word.h"
#import "Database.h"
@implementation WordLists
Database *database =nil;
sqlite3 *db = nil;
- (id)init {
Database *database = [Database getInstance];
db = [database getSqlite3Connection];
if (db == nil) {
database = [[Database alloc] init];
NSLog(@"**Wordlists:init: db is nil");
}
return self;
}
- (NSMutableArray *) getWordforId :(NSInteger)wid{
int wordid = wid;
sqlite3_stmt *sqlStatement;
NSMutableArray *WordArray = [[NSMutableArray alloc] init];
@try {
const char *sql = "SELECT id,ename,pname,hname,hsound FROM words WHERE id=?";
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(@"WordsList:getWordforId: Problem with prepare statement");
}
sqlite3_bind_int(sqlStatement,1, wordid);
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
NSLog(@"MyWords:getMyWords: Record numbers");
Word *MyWord = [[Word alloc]init];
MyWord.wordId = sqlite3_column_int(sqlStatement, 0);
MyWord.ename = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(sqlStatement,1)];
MyWord.pname = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(sqlStatement, 2)];
MyWord.hname = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(sqlStatement, 3)];
MyWord.hsound = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(sqlStatement, 4)];
[WordArray addObject:MyWord];
NSLog(@"wineId : %d", MyWord.wordId);
}
sqlite3_reset(sqlStatement);
sqlite3_finalize(sqlStatement);
return WordArray;
}@catch (NSException *exception) {
NSLog(@"An exception occured: %@", [exception reason]);
}
@finally {
}
}
@end
运行时输出:
2013-08-03 22:01:05.320 StoryboardTutorial[716:c07] 数据库连接 - 初始化新 联系 2013-08-03 22:01:05.322 StoryboardTutorial[716:c07] *DB 连接地址:0x0 2013-08-03 22:01:05.328 StoryboardTutorial[716:c07] *DB CONNECTION getInstance: 2013-08-03 22:01:05.329 StoryboardTutorial[716:c07] 数据库连接初始化新 联系 2013-08-03 22:01:05.330 StoryboardTutorial[716:c07] *DB 连接地址:0x7d78ea0 2013-08-03 22:01:05.330 StoryboardTutorial[716:c07] **Wordlists:init: db is nil 2013-08-03 22:01:05.331 StoryboardTutorial[716:c07] DB CONNECTION*关闭连接 2013-08-03 22:01:05.331 StoryboardTutorial[716:c07] WordsList:getWordforId: 准备语句的问题