iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Software Development

可以Go一輩子嗎?系列 第 26

Day26. 透過SQL語法與ORM操作資料庫

  • 分享至 

  • xImage
  •  

Day26. 透過SQL語法與ORM操作資料庫

今天來介紹如何透過SQL語法與ORM操作資料庫,這邊會使用到GORM這個套件,GORM是一個Go語言的ORM套件,可以讓我們透過Go語言的struct來操作資料庫,GORM支援多種資料庫,包含MySQL、PostgreSQL、SQLite、SQL Server等等,這邊我們會使用MySQL資料庫來做示範。

SQL語法操作

在開始之前,我們需要先根據自己使用的資料庫管理系統來安裝對應的驅動程式,這邊我會列出各種資料庫與其對應的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操作

接著我們來看看如何透過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來操作資料庫

  • 初始化DB
// 千萬不要學我直接用明文寫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
time

話說用Go操作MySQL算不算是一種MyGOhttps://ithelp.ithome.com.tw/upload/images/20241004/20161880f3TdZmZOHG.jpg

REF


上一篇
Day25. Gin的Middleware
下一篇
專案練習: 字幕搜尋API (1/4)
系列文
可以Go一輩子嗎?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言