2013-08-22 122 views
0

我将图像存储在服务器中。然后我通过图像URL获取图像并保存到db1.sqlite文件。图像保存为像URL一样的db1.sqlite文件。如何显示保存的URL中的图像。 product_image具有imageURL路径。将图像保存到数据库并从服务器加载

代码:

SQLite表结构:

CREATE TABLE "product" ("id" INTEGER PRIMARY KEY NOT NULL , "cat_id" INTEGER NOT NULL , "product_image" VARCHAR NOT NULL , "order_by" INTEGER NOT NULL) 

插入代码:

const char *sqlInsert = [[NSString stringWithFormat:@"insert into product (id, cat_id,product_image,order_by) values ('%@','%@','%@','%@')", [tuser objectForKey:@"id"], [tuser objectForKey:@"cat_id"],[tuser objectForKey:@"product_image"],[tuser objectForKey:@"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding]; 

NSLog(@"product insert %s", sqlInsert); 

if(sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK) 
    NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 

if(SQLITE_DONE != sqlite3_step(addStmt)) 
    NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 

图像取:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
//NSLog(@"docs dir is %@", documentsDirectory); 

NSString *path = [documentsDirectory stringByAppendingPathComponent:@"db1.sqlite"]; 
//NSLog(@"filepath %@",path); 

mArray = [[NSMutableArray alloc]init]; 
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) { 

    const char *sql = "SELECT id,cat_id,product_image FROM product order by order_by"; 

    NSLog(@"sql is %s",sql); 

    sqlite3_stmt *statement; 
    // int catID = 0; 
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) { 
     // We "step" through the results - once for each row. 
     while (sqlite3_step(statement) == SQLITE_ROW) { 

      int length = sqlite3_column_bytes(statement, 2); 
      NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 2) length:length]; 

      UIImage *image = [UIImage imageWithData:imageData]; 

      [mArray addObject:image]; 

      [image release]; 
     } 
    } 
    sqlite3_finalize(statement); 
} 
else { 
    sqlite3_close(database); 
    NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database)); 
    // Additional error handling, as appropriate... 
} 

回答

1

与你离线聊天,我发现,product_image不是NSData。 (我后来错误地推断出存在sqlite3_column_blob,你试图存储二进制数据,事实并非如此)。显然product_image是包含URL的字符串。因此将其存储为一个字符串。永远不要用你的SQL语句stringWithFormat,而是使用sqlite3_bind_xxx功能与?占位符,例如:

const char *sqlInsert = "insert into product (id, cat_id, product_image, order_by) values (?, ?, ?, ?)"; 

if (sqlite3_prepare_v2(database, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK) 
    NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 

if (sqlite3_bind_int(addStmt, 1, [[tuser objectForKey:@"id"] intValue]) != SQLITE_OK) 
    NSAssert1(0, @"Error binding 1. '%s'", sqlite3_errmsg(database)); 

if (sqlite3_bind_int(addStmt, 2, [[tuser objectForKey:@"cat_id"] intValue]) != SQLITE_OK) 
    NSAssert1(0, @"Error binding 2. '%s'", sqlite3_errmsg(database)); 

if (sqlite3_bind_text(addStmt, 3, [[tuser objectForKey:@"product_image"] UTF8String], -1, NULL) != SQLITE_OK) 
    NSAssert1(0, @"Error binding 3. '%s'", sqlite3_errmsg(database)); 

if (sqlite3_bind_int(addStmt, 4, [[tuser objectForKey:@"order_by"] intValue]) != SQLITE_OK) 
    NSAssert1(0, @"Error binding 4. '%s'", sqlite3_errmsg(database)); 

if (SQLITE_DONE != sqlite3_step(addStmt)) 
    NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 

// don't forget to finalize 

sqlite3_finalize(addStmt); 

如果你这样做,你必须改变你的代码,用于获取图片,太。例如,您有:

while (sqlite3_step(statement) == SQLITE_ROW) { 

    int length = sqlite3_column_bytes(statement, 2); 
    NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 2) length:length]; 

    UIImage *image = [UIImage imageWithData:imageData]; 

    [mArray addObject:image]; 

    [image release]; 
} 

一对夫妇的想法:

  1. [image release]是过度释放。 imageWithData返回autorelease对象,因此您不需要/想要释放它。这种错误可能是灾难性的,所以我建议你通过静态分析器运行你的代码,以帮助识别这些类型的错误(通过从“产品”菜单中选择“分析”,或者按命令 + 移位 + B)。你应该有由静态分析器产生的警告。该分析仪是一个非常有用的工具来识别编程错误,所以利用这个优秀的工具。

  2. 这点之前是没有实际意义,不过,因为你没有在NSData存储实际的图像,而是你在一个字符串存储URL,因此,您应该用sqlite3_column_text,来代替。

  3. 一旦转换,你从sqlite3_column_text进入一个NSStringconst char *,你再要采取该字符串,并创建一个URL,例如:

    NSURL *url = [NSURL URLWithString:urlStringFromDatabase]; 
    
  4. 然后,您可以使用与结合NSURLUIImageView类别如SDWebImage,以异步检索图像(并做所有适当的缓存等)。

    [imageView setImageWithURL:url 
          placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 
    
  5. 而且,在重复自己的风险,你的图像检索代码检查是否SQLite的函数返回,例如SQLITE_OK,但如果没有,你不显示sqlite3_errmsg。调试应用程序时始终要查看此内容。这将节省你几个小时的开发/调试。

+0

我应该在“product_image”中使用什么VARCHAR NOT NULL? BLOB或VarChar创建表时。 – user2674668

+0

我的图片获取代码是正确的? – user2674668

+0

1.由于'product_image'是一个包含图像URL的字符串,所以应该使用'TEXT'作为列定义,而不是'BLOB'。 2.不,您的图片获取代码不正确。看到我修改后的答案。 – Rob

相关问题