Screen Shot 2557-05-05 at 9.29.25 PM

หลังจากที่ทดลองเขียน Go มาบ้างเล็กน้อย
ได้โจทย์มาเล็กๆ ว่า เราจะติดต่อฐานข้อมูลได้อย่างไร
เนื่องจากโลกการพัฒนา software หนีไม่พ้นมันอย่างแน่นอน
ดังนั้นจึงไปดูว่า Go มีอะไรให้ใช้บ้าง
และใช้งานมันอย่างไร

เริ่มต้นการเดินทางเพื่อเรียนรู้

เมื่อเข้าไปดูที่ package ของ Go
พบว่ามีการจัดการฐานข้อมูลด้วย package database
โดยใน package นี้ประกอบไปด้วย 2 ส่วนย่อยคือ
1. database/sql เป็นส่วนกำหนด generic interface สำหรับการใช้งานฐานข้อมูลผ่านชุดคำสั่ง SQL
2. database/sql/driver เป็นส่วนกำหนด generic interface สำหรับการสร้าง database driver ของฐานข้อมูลชนิดต่างๆ

Driver ของฐานข้อมูลชนิดต่างๆ นั้นมีคนพัฒนาไว้ให้แล้วที่นี่  SQL Driver
ส่วนการใช้งาน SQL ผ่าน interface ที่ Go เตรียมไว้นั้น
มีตัวอย่างการใช้งานอยู่ที่นี่ SQL Interface
ในตัวอย่างการใช้งาน ประกอบไปด้วยส่วนต่างๆ ต่อไปนี้

1. package ที่ใช้งานคือ database/sql

import "database/sql"

2. การติดต่อฐานข้อมูล

db, err := sql.Open(driver, dataSourceName)
…

db.Close()

คำอธิบาย
driver คือ ชื่อของฐานข้อมูลที่ต้องการติดต่อ เช่น mysql เป็นต้น
dataSourceName คือ รูปแบบการติดต่อฐานข้อมูล เช่น user:password@/database-name
การใช้งานคำสั่งนี้ จะไม่ทำการเปิดการเชื่อมต่อไปยังฐานข้อมูลโดยตรง
แต่จะทำการเปิดการเชื่อมต่อเมื่อทำการ query ข้อมูล
หรือทำการทดสอบการเชื่อมต่อผ่าน function Ping() ได้

และเมื่อใช้งานเสร็จแล้ว ให้ทำการปิดการเชื่อมต่อด้วย function Close()

3. การประมวลผลคำสั่ง SQL

ตัวอย่างการใช้งานเพื่อสร้างข้อมูลลงในฐานข้อมูล

result, err := db.Exec(
   "INSERT INTO users (name, age) VALUES (?, ?)",
   "gopher",
   27,
)

และสามารถดึงข้อมูลของ ID และ จำนวนข้อมูลที่ได้รับผลกระทบด้วยคำสั่ง

result.LastInsertId()
result.RowsAffected()

ตัวอย่างการดึงข้อมูลจากฐานข้อมูล

rows, err := db.Query("SELECT id, name FROM users WHERE age = ?", age)
if err != nil {
   log.Fatal(err)
}
for rows.Next() {
   var id int
   var name string
   if err := rows.Scan(&id, &name); err != nil {
      log.Fatal(err)
   }
   fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
   log.Fatal(err)
}

คำอธิบาย
ทำการดึงข้อมูลจากฐานข้อมูล ทำการ binding ด้วย parameter 1 ตัว
ทำการดึงข้อมูลที่ได้จาก result หรือถ้าเทียบคือ ResultSet นั่นเอง
ต่อจากนั้น ทำการดึงข้อมูลจากแต่ละ column ด้วย function Scan()
โดยจะ binding ข้อมูลจาก result เข้ากับตัวแปรที่กำหนดตามลำดับ

ถ้ามั่นใจว่าข้อมูลที่ต้องการดึงออกมานั้น มีเพียง 1 row เท่านั้น สามารถเขียน code ได้ดังนี้

var age int64
row := db.QueryRow("SELECT age FROM users WHERE name = ?", name)
err := row.Scan(&age)

แล้วถ้าถามว่ามี function แนวๆ  Prepare statement บ้างไหม
ตอบว่ามี ซึ่งสามารถเขียนได้ดังนี้

age := 27
stmt, err := db.Prepare("SELECT name FROM users WHERE age = ?")
if err != nil {
   log.Fatal(err)
}
rows, err := stmt.Query(age)

เริ่มต้นการใช้งานจริงๆ ดีกว่า

เมื่อทำการเรียนรู้ในเบื้องต้น สำหรับการใช้งานเบื้องต้นแล้ว
เข้ามาเรื่องสิ่งที่ต้องการเลยดีกว่า นั่นคือ ต้องการใช้งานฐานข้อมูล MySQL ด้วย Go
โดยจาก driver ที่มีคนเขียนให้ผมเลือก GoSQLDriver:MySQL
เหตุผลง่ายมาก คือ อ่านเอกสารแล้วรู้เรื่องนั่นเอง รวมทั้งหลายๆ สำนักแนะนำตัวนี้
ดังนั้นจึงนำมาใช้งาน

การใช้งานง่ายมากๆ โดยทำการติดตั้ง package ด้วยคำสั่ง

$go get github.com/go-sql-driver/mysql

จากนั้นทำการเขียน code เพื่อใช้งานดังนี้
เป็นตัวอย่างการใช้ function Ping() เพื่อทดสอบการเชื่อมต่อกับฐานข้อมูล

ต่อมาทำการเพิ่มข้อมูลลงในฐานข้อมูล

และปิดท้ายด้วยการดึงข้อมูลตามเงื่อนไขขึ้นมาเพื่อแสดงผล

เพียงเท่านี้ เราก็สามารถจัดการข้อมูลใน MySQL ได้แล้ว
ซึ่งการใช้งานนั้นง่าย ไม่มีอะไรที่ซับซ้อน
ส่วนฐานข้อมูลอื่นๆ ก็ง่ายเลยเพียงไปเลือกใช้ driver ให้ตรงกับที่ต้องการเท่านั้นเอง

Have Fun With Go  ครับ ….