今天來介紹如何透過SQL語法與ORM操作資料庫,這邊會使用到GORM這個套件,GORM是一個Go語言的ORM套件,可以讓我們透過Go語言的struct來操作資料庫,GORM支援多種資料庫,包含MySQL、PostgreSQL、SQLite、SQL Server等等,這邊我們會使用MySQL資料庫來做示範。
在開始之前,我們需要先根據自己使用的資料庫管理系統來安裝對應的驅動程式,這邊我會列出各種資料庫與其對應的package(為了方便之後的操作,這邊提到的package都支援database/sql
的介面)。
接著在你的Code中將對應的package import進來,這邊我們使用MySQL作為範例
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
眼尖的你可能發現了,我們在import的時候多了一個_
,這是因為我們只需要使用這個package的init
函數來初始化資料庫驅動,真正的操作都是透過database/sql
來進行的。
接著我們來看看如何透過SQL語法來操作資料庫
func shoutError(err error) {
// you can also use errors.Is if your Go version is 1.13 or later
switch err.(type) {
case *mysql.MySQLError:
fmt.Println("MySQL Error: ", err)
// add more error type here
default:
fmt.Println("Error: ", err)
}
}
func CreateDB() {
// ...
db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/test")
if err != nil {
shoutError(err)
return
}
err = db.Ping() // 測試連線
if err != nil {
shoutError(err)
return
}
defer db.Close()
}
SELECT
)func main() {
// ...
rows, err := db.Query("SELECT * FROM users")
if err != nil {
return returnError(err)
}
defer rows.Close()
for rows.Next() { // 持續讀取下一筆資料
var id int
var name string
// 透過Scan函數將資料填入變數
if err := rows.Scan(&id, &name); err != nil {
return returnError(err)
}
fmt.Printf("ID: %d, Name: %s\n", id, name)
}
}
UPDATE
, DELETE
, INSERT
, etc.),對,如果沒有要抓取資料的話都只需要使用
Exec
函數就行
func main() {
// statement
// args...
_, err = db.Exec(statement, args...)
if err != nil {
return returnError(err)
}
}
接著我們來看看如何透過ORM(Object-Relational Mapping)來操作資料庫,這邊我們會使用GORM這個套件來操作資料庫。
GORM是一個透過ORM來操作資料庫的套件,我們只需要透過Go語言的struct來定義資料表,GORM就會幫我們在操作時自動處理成對應的SQL語法。
首先我們需要先安裝GORM套件
go get -u gorm.io/gorm
然後import進來
import (
"gorm.io/gorm"
_ "gorm.io/driver/mysql"
)
接著我們來看看如何透過GORM來操作資料庫
// 千萬不要學我直接用明文寫dsn, 你可以使用環境變數或是config來設定
const dsn = "anon:tokyo:localhost:3306/mygo?charset=utf8mb4&parseTime=True&loc=Local"
var Database *gorm.DB
func initDB() {
var err error
Database, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
shoutError(err)
return
}
}
type User struct {
gorm.Model
Name string
Age int
}
// 可以透過tag設定資料表屬性
type User struct {
gorm.Model
Name string `gorm:"column:name;type:varchar(100);not null"`
Age int `gorm:"column:age;type:int;not null"`
}
type AnyStruct struct {
gorm.Model
}
func createTable(table &AnyStruct) {
if err:= Database.AutoMigrate(table); err != nil {
shoutError(err)
return
}
}
func createUser(name string, age int) {
user := User{Name: name, Age: age}
if err := Database.Create(&user).Error; err != nil {
shoutError(err)
return
}
}
func getUser(id int) {
var user User
if err := Database.First(&user, id).Error; err != nil {
shoutError(err)
return
}
}
func getUsers() {
var users []User
if err := Database.Find(&users).Error; err != nil {
shoutError(err)
return
}
}
func updateUser(id int, name string, age int) {
if err := Database.Model(&User{}).Where("id = ?", id).Updates(User{Name: name, Age: age}).Error; err != nil {
shoutError(err)
return
}
}
func deleteUser(id int) {
if err := Database.Delete(&User{}, id).Error; err != nil {
shoutError(err)
return
}
}
那麼今天的文章就到這告一段落,如果我的文章有任何地方有錯誤請在留言區反應
明天將會開始真正的實作一個API
話說用Go操作MySQL算不算是一種MyGO