2013-08-22 125 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

相關問題