เอาปัญหาและวิธีแก้ไขสำหรับ 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 }