เทคนิคการใช้ SQLite มาพัฒนาร่วมในการดึงข้อมูลของจากฐานข้อมูลมาบนแอพพลิเคชันบน iPhone ของเราเบื้องต้น เทคนิคสำหรับนักพัฒนา iPhone Apps Development มือใหม่สำหรับแอพพลิเคชันบนสมาร์ทโฟนที่มีข้อมูลปริมาณมาก หากว่าเราทำการอัดข้อมูลเก็บไว้ใน คำสั่งหรือฟังก์ชันก็จะทำให้ขนาดของแอพพลิเคชันของเรามีขนาดใหญ่เกินความจำเป็น จึงต้องมีจัดเก็บข้อมูลเก็บไว้ในฐานข้อมูล จากบทเรียนก่อนหน้าที่เป็นการติดตั้ง SQLite เบื้องต้นลงบนเครื่องคอมพิวเตอร์ และวิธีใช้งาน Extension หรือส่วนเสริมของ FireFox อย่าง SQLite Manager แล้ว คราวนี้จะเป็นการเขียนคำสั่งเบื้องต้นสำหรับดึงข้อมูลจาก ฐานข้อมูลพร้อมทั้งคำสั่ง SQL เบื้องต้นมาช่วยเหลือ
ก่อนอื่นให้ไปสร้าง ฐานข้อมูล SQLite ขึ้นมาตั้งชื่อว่า “student” จาก SQLite Manager บน FireFox
กดที่ไอคอน Create Table เพื่อสร้าง ตารางข้อมูลที่ชื่อว่า “student” อีกครั้ง เพื่อเก็บข้อมูลของรายชื่อนักเรียนเป็นข้อมูลตัวอย่าง
ให้เข้าไปสร้าง Attribute หรือ Column บนตาราง “student” โดยตัวอย่างที่กำหนดไว้คือ “name” ประกาศรูปแบบเป็น “VARCHAR” เพื่อไว้ใช้เก็บรายชื่อ และนามสกุลของนักเรียน ตามด้วย “email” ประกาศเป็นรูปแบบว่า “VARCHAR” เช่นกันสำหรับเก็บข้อมูล Email ของนักเรียน และช่องสุดท้ายคือ “profiles” ประกาศรูปแบบเป็น “TEXT” เช่นกันไว้เก็บประวัติของนักเรียน หรือ ใช้คำสั่ง SQL ในช่อง Execute SQL ตามคำสั่งด้านล่างก็ได้
CREATE TABLE "student" (
"name" VARCHAR NOT NULL ,
"email" VARCHAR,
"images" VARCHAR,
"profiles" TEXT)
เมื่อสร้างตารางของ “student” เป็นที่เรียบร้อยแล้วให้ลองใส่ข้อมูลตัวอย่างลงไป สัก 4-5 รายชื่อ ให้เรียบร้อย ซึ่งตัวอย่างที่เห็นคือ
จะพบว่าข้อมูล “student” นั้นมีข้อมูลนักเรียนปรากฏอยู่ ตามแถวข้อมูลที่เรากรอกเข้าไปต่อไปให้เราสร้าง Project ใหม่ขึ้นมา
หลังจากที่สร้าง New Project ไปแล้วให้หยุดที่หน้า Project Detail ก่อนอย่าเพิ่งเปลี่ยนหรือปิดไปไหน เพราะเราจะต้องทำการเพิ่ม Framework ของ SQLite ลงไปใน Project ของเรา
เลือกไปที่แถบ Build Phases ของตัว Project เพื่อทำการเพิ่ม Library ของ SQLite ลงไป ในช่อง “Link Binary With Libraries” ที่ปุ่ม “+” บริเวณด้านล่างซ้ายของแถบนี้
กด “+” แล้วทำการค้นหา โดยใส่คำค้นหาว่า “SQL” จะพบไฟล์ libsqlite3.dylib และ libsqlite3.0.dylib ให้เลือก libsqlite3.0.dilib ลงไป ใน Project
ไปที่ไฟล์ AppDelegate.h ทำการประกาศ หน้า ViewController เป็น Class ตัวใหม่ขึ้นมาก่อนโดยคำสั่ง
#import
@class ViewController;
@interface AppDelegate : UIResponder {
UIWindow *window;
ViewController *viewController;
}
@property (strong, nonatomic) UIWindow *window;
@end
ทำการประกาศตัวแปล เพิ่มเติมในไฟล์ DetailViewController.h โดยเรียก Libraries ของ SQLite เข้ามาในส่วนนี้
#import
#import
@interface DatabasesViewController : UIViewController{
sqlite3 *database;
}
สร้างฟังก์ชันสำหรับ ทำการเก็บข้อมูลจาก SQLite ขึ้นมาด้านล่างก่อน @end
- (void) initDatabase;
@end
เป็นการเตรียมพร้อมการดึงข้อมูลจากไฟล์ SQLite ลงไปในตัวแอพพลิเคชัน ต่อจากนั้นให้นำไฟล์ SQLite ที่เราสร้างขึ้นมาที่ชื่อว่า student.sqlite มาไว้ใน Project โดยการเพิ่ม
ไปที่ไฟล์ DatabaseViewController.m ทำการเพิ่มคำสั่ง initDatabase เข้าไปในไฟล์ เพื่ออ่านค่าข้อมูลจากฐานข้อมูล
- (void) initDatabase
{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory
stringByAppendingPathComponent:@"student.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success)
{
return;
}
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"student.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath
toPath:writableDBPath error:&error];
if (!success)
{
NSAssert1(0, @"Failed to create writable database file with message '%@'.
", [error localizedDescription]);
}
}
เมื่อเพิ่มคำสั่งดังกล่าวลงไปแล้ว ให้ไปเรียกใช้งานฟังก์ชันนี้ที่ ViewDidLoad อีกที
- (void)viewDidLoad
{
[super viewDidLoad];
[self initDatabase];
// Do any additional setup after loading the view, typically from a nib.
}
เป็นการเก็บที่อยู่ของไฟล์ฐานข้อมูล นั่นคือไฟล์ student.sqliteไปฝากไว้ที่ตัวแปร paths แล้วทำการเขียนข้อมูลโดยคำสั่ง writableDBPath ลงในไฟล์ student.sqlite ทำการเชื่อมต่อ และตรวจสอบว่าแอพพลิเคชันเชื่อมต่อได้หรือไม่ บนตัวแปร defaultDBPath เพื่อเรียกไฟล์ฐานข้อมูลนี้
ต่อมาเป็นการใช้คำสั่งในการเรียกอ่านข้อมูลมาเก็บไว้ในตัวแปรชุดหนึ่ง ให้ทำการเพิ่มฟังก์ชันใหม่เข้าไปในไฟล์ DatabasesViewController.h อีกครั้งด้วย
@interface DatabasesViewController : UIViewController{
sqlite3 *database;
}
- (void) initDatabase;
- (void) getStudent;
เมื่อสร้างฟังก์ชันสำหรับ เรียกข้อมูลจากฐานข้อมูลมาแล้วให้เข้าไปเพิ่ม ฟังก์ชันการทำงานที่ไฟล์ DatabasesViewController.m อีกครั้ง
- (void) getStudent
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"student.sqlite"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
const char *sql = "select * from student WHERE rowid='1'";
sqlite3_stmt *searchStatement;
if (sqlite3_prepare_v2(database, sql, -1, &searchStatement, NULL) == SQLITE_OK)
{
while (sqlite3_step(searchStatement) == SQLITE_ROW)
{
NSString *name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement, 0)];
NSString *email = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement, 1)];
// NSString *email = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement, 2)];
NSLog(@"Name: %@ ,Categories: %@ ", name, email);
self.labelColor.text=name;
}
}
sqlite3_finalize(searchStatement);
}
}
หากสังเกตจะเห็นว่า คำสั่ง SQL นั้นผมจะทำการเรียกข้อมูล เพียงแถวเดียว จากเงื่อนไข คือ แถวที่ 1 หรือ rowid=’1′ ผ่านคำสั่ง ภาษา SQL ว่า
SELECT * FROM student WHERE rowid='1'
สิ่งที่ได้ก็คือ ชุดข้อมูลของ “Banyapon Poolsawasd” และอีเมล “[email protected]” เป็นต้นครับ
สร้างคำสั่งให้ เรียกข้อมูลจากฐานข้อมูลทันทีที่ ViewDidLoad โดยเพิ่มคำสั่งลงไปว่า
- (void)viewDidLoad
{
[super viewDidLoad];
[self initDatabase];
[self getStudent];
}
ลองทำการ “Run” ตัวแอพพลิเคชันของคุณดู หน้าจอของ Simulator ตัว iPhone หรือ iPad จะไม่มีผลลัพธ์อะไร ให้กดปุ่ม Command พร้อมกับปุ่ม Shift ค้างไว้แล้วกดแป้น “c” จะมี Target Output ปรากฏขึ้นสังเกตว่าผลลัพธ์จะเรียกข้อมูลขึ้นมาให้ตามตัวอย่างข้างล่าง
สังเกตว่าผมจะเรียกข้อมูลจากฐานข้อมูล student ในส่วนของ Columns ชื่อ “name” และ “email” ออกมาซึ่งเป็นไปตามเงื่อนไขแรก หากเปลี่ยน rowid=’2′ ก็จะได้ข้อมูลแตกต่างออกไป
ให้ทำการสร้าง UILabel ขึ้นมาหนึ่งตัว สร้าง IBOutlet ขึ้นมาตั้งชื่อว่า labelStudent จะด้วยการลากวาง UI หรือพมพ์คำสั่งก็ได้
#import
#import
@interface DatabasesViewController : UIViewController{
sqlite3 *database;
}
- (void) initDatabase;
- (void) getColors;
@property (retain, nonatomic) IBOutlet UILabel *labelStudent;
@end
และอย่าลืม Synthesize ตัวแปรของ UILabel บนไฟล์ DatabasesViewController.m อีกครั้ง
#import "DatabasesViewController.h"
@implementation DatabasesViewController
@synthesize labelStudent;
กลับไปเพิ่มคำสั่งเล็กๆ น้อยในฟังก์ชัน getStudent() อีกครั้งให้ UILabel ของเราดึงข้อมูลขึ้นมา
while (sqlite3_step(searchStatement) == SQLITE_ROW)
{
NSString *name = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 0)];
NSString *email = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 1)];
NSLog(@"Name: %@ ,Categories: %@ ", name, email);
self.labelColor.text=name;
}
ลองทำการ “Run” ตัวแอพพลิเคชันของเราดูอีกครั้งจะพบว่า แอพพลิเคชันของเราจะแสดงชื่อของนักเรียนจากฐานข้อมูล student ซึ่งเป็นข้อมูลชุดแรกออกมาตามเงื่อนไข
สิ่งที่ได้จากบทเรียนนี้ : การเชื่อมต่อฐานข้อมูลเบื้องต้น และเรียกข้อมูลขึ้นมาจากคำสั่ง SQL มาแสดงผลในตัวแปร และ UILabel อย่างง่าย
พี่จบมาจาก ม กรุงเทพหรอครับ.
จบตรี ม.หอการค้า
จบโท พระจอมเกล้าฯ ลาดกระบังครับ
แต่เป็น อ.พิเศษ ที่ ม.กรุงเทพ