เอาปัญหาและวิธีแก้ไขสำหรับ GORM มารวม ๆ กันไว้เลย ถ้าเคนเจอ ทุกคนก็ต้องเจอแน่นอน
แยกไฟล์สำหรับ Open กับ Close ของตัวแปร DB
อันนี้น่าจะเป็นพื้นฐานแรกที่ทุกคนต้องงงอ่ะ เพราะเคนก็งง หลักสำคัญมันอยู่ที่การประกาศตัวแปร และการใช้ :=
อย่างที่เคนรู้คือถ้าใช้ := กับตัวแปรใดแล้ว ตัวแปรนั้นจะต้องถูกใช้งานในฟังก์ชั่นนั้นด้วย ถ้าไม่ใช้มันจะ Error
แต่ถ้าเราประกาศตัวแปรเป็น Global แล้วตอนสั่ง Open แล้วใช้ = แทน := จะทำให้มันสามารถเก็บค่าไว้โดยที่ยังไม่ต้องเรียกใช้ในฟังก์ชั่นนั้น ๆ ได้
## File: models/init.go
## Package: models
## ---------------------------------------------
package models
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// DB variable for open and close database
var (
DB *gorm.DB
DBErr error
)
// DBOpen open database
func DBOpen() {
DB, DBErr = gorm.Open("mysql", "username:password@/mydatabase?charset=utf8&parseTime=True&loc=Local")
if DBErr != nil {
panic(DBErr)
}
}
// DBClose set defer close db
func DBClose() {
DB.Close()
}
ทีนี้ก็ประกาศตัวแปรแบบ Global ได้อย่างไม่มีปัญหาแล้ว ตอนนี้ก็ให้ไฟล์อื่น ๆ import package models ไปก็สามารถใช้งานตัวแปร DB ได้เลย แบบนี้
## File: controllers/page.go
## Package: controllers
## ---------------------------------------------
package controllers
import (
"github.com/my-github-username/my-project-name/models"
"github.com/astaxie/beego"
)
type PageController struct {
beego.Controller
}
func (this *PageController) GetAll() {
models.DBOpen()
defer models.DBClose()
}
Query ไม่ได้ติด Error (sql: Scan error on column index 1, name “created_at”: unsupported Scan, storing driver.Value type []uint8 into type *time.Time)
วิธีแก้คือไปทำการ parse time ครับ หรือเอาแบบง่ายๆ คือไปเพิ่มโค้ด ?parseTime=true ตอนต่อ Database แบบนี้
root:root@tcp(127.0.0.1:3306)/revelblog?parseTime=true
โค้ดตัวอย่างการ Insert ข้อมูลลง Database
สมมติเรามีการสร้าง Model ชื่อ Users ไว้อีกไฟล์นึงอยู่แล้ว และมีตัวแปล DB *gorm.DB อยู่ที่ไฟล์หลัก
// add value to model struct Users
user := models.Users{
Username: username,
Password: newHashPassword,
}
// insert to database
DB.Create(&user)
// if success to create to database this checker will return false
if DB.NewRecord(user) {
fmt.Println("error can't insert to database. Please contact admin website")
return
}
โค้ดตัวอย่างการ Query และเช็ค Hash Password
โค้ดส่วนนี้จะใช้ร่วมกับ Revel Framework
สมมติเรามีการสร้าง Model ชื่อ Users ไว้อีกไฟล์นึงอยู่แล้ว และมีตัวแปล DB *gorm.DB อยู่ที่ไฟล์หลัก
username := c.Params.Form.Get("inputUsername")
password := c.Params.Form.Get("inputPassword")
var user models.Users
DB.Where("username = ?", username).First(&user)
if user.Username == "" {
fmt.Println("error username is not found.")
return
}
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil {
fmt.Println("error password is not correct.")
return
}
