GO web 開發 實戰二,資料庫相關

阿兵雲原生發表於2023-01-29

xdm 上次有分享到GO web 開發 中 http 包中的簡單方法使用,最後還有一個 模板 , 在這裡補充一下

直接上案例

模板

  • 我們在 main.go 裡面寫一個 服務端的 demo,使用模板來將冬天的資料寫入到 html 檔案中
  • 對應的需要寫一個 html 檔案,並設定好 需要模板注入的資料位置

main.go

package main

import (
    "fmt"
    "html/template"
    "net/http"
)

var myTemp *template.Template

type Person struct {
    Name  string
    Title string
    Age   int
}

//開始處理資料和做響應
func userInfo(w http.ResponseWriter, req *http.Request) {
    defer req.Body.Close()

    var pp []Person
    // 簡單模擬資料
    p1 := Person{
        Name:  "xmt 1號",
        Title: "1 號 展示臺",
        Age:   18,
    }
    p2 := Person{
        Name:  "xmt 2號",
        Title: "2 號 展示臺",
        Age:   15,
    }
    p3 := Person{
        Name:  "xmt 3號",
        Title: "3 號 展示臺",
        Age:   29,
    }

    pp = append(pp, p1, p2, p3)

    // 將資料寫到模板中
    err := myTemp.Execute(w, pp)
    if err != nil {
        fmt.Println("Execute err ;%v", err)
        return
    }

}

func main() {

    //初始化模板
    var err error
    myTemp, err = template.ParseFiles("./index.html")
    if err != nil {
        fmt.Println("ParseFiles err ;%v", err)
        return
    }

    //註冊處理模板的函式  並 開啟監聽
    http.HandleFunc("/", userInfo)
    err = http.ListenAndServe("0.0.0.0:9999", nil)
    if err != nil {
        fmt.Println("ListenAndServe err ;%v", err)
        return
    }

}

index.html

<html>
    <head>

    </head>
    <body>
        <p>hello world</p>
        <table border="1" align="center" width="600px">
            <tr>
                <td>{{.Name}}</td> <td>{{.Age}}</td><td>{{.Title}}</td>
            </tr>
        </table>
    </body>
</html>

上述程式碼也比較簡單,直接執行 main.go 就可以啟動服務端,我們們只需要在瀏覽器中訪問

http://localhost:8888/

即可看到我們們 html 展示的效果,資料是動態的

另外,接下來一起來看看 go web 中使用的 mysql 資料庫

Mysql

連線資料庫

運算元據庫,基本是如下幾個步驟

  • 先 open,再 ping , 必須要 ping 通了之後才可以算是連線上了MySQL資料庫
  • 寫 mysql 的程式碼,必須引入這個包 _ "github.com/go-sql-driver/mysql" , 需要先執行 mysql 中的 init 函式
  • 此處記得填寫對自己 mysql 的密碼,如果覺得密碼不好記,可以設定密碼為 123456 ,用於學習和實踐

    package main
    
    import (
        "database/sql"
        "fmt"
    
        _ "github.com/go-sql-driver/mysql" // 註釋掉後異常 _ 呼叫初始化函式
    
    )
    
    func main() {
        //開啟mysql 資料庫 進行連線 , 必須要 ping 通 才算是連線上 mysql 資料庫
        db, err := sql.Open("mysql", "root:xxxxxx@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4")
        if err != nil {
            fmt.Println("Open err : ", err)
            return
        }
    
        err = db.Ping()
        if err != nil {
            fmt.Println("Ping err : ", err)
            return
        }
        db.Close()
    }

此處我們可以看到 charset=utf8mb4 ,這裡是設定字元編碼格式為 utf8mb4 ,主要是用於

這裡需要說一下,基本上我們現在的 mysql 編碼設定都是設定成 utf8mb4字符集 ,因為它支援 4 個位元組的 Unicode 字元

在早期 Unicode 還不夠完善的時候,是使用的 UTF8 ,只需要最長 3 個位元組就可以表示 Unicode 字元

增加

做資料增加操作,向資料庫中插入資料

  • 此處我們們使用 佔位符的方式來插入資料
  • sqlInfo 變數裡面填寫 標準的 sql 語句即可
func insertPiceInfo(db *sql.DB) {
    // ? 作為佔位符號
    sqlInfo := "insert into user(name,age)values(?,?)"
    ret, err := db.Exec(sqlInfo, "xxx", 19)
    if err != nil {
        fmt.Println("Exec err : ", err)
        return
    }

    //插入資料的id
    id, err := ret.LastInsertId()
    if err != nil {
        fmt.Println("LastInsertId err : ", err)
        return
    }

    fmt.Println("LastInsertId == ", id)

    //本次操作影響的行數
    rows, err := ret.RowsAffected()
    if err != nil {
        fmt.Println("RowsAffected err : ", err)
        return
    }
    fmt.Println("rows == ", rows)

}

執行插入語句後,可以透過插入的結果,來獲取插入資料成功的 id 和本次插入資料影響的行數

刪除

刪除資料就比較簡單,同樣的我們可以拿到刪除資料的結果,來獲取對應影響的行數等等

func deletePiceInfo(db *sql.DB) {
    // ? 作為佔位符號
    sqlInfo := "delete from user where id=  xx "
    ret, err := db.Exec(sqlInfo)
    if err != nil {
        fmt.Println("Exec err : ", err)
        return
    }

    //本次操作影響的行數
    rows, err := ret.RowsAffected()
    if err != nil {
        fmt.Println("RowsAffected err : ", err)
        return
    }
    fmt.Println("rows == ", rows)

}

修改

func updatePiceInfo(db *sql.DB) {
    // ? 作為佔位符號
    sqlInfo := "update user set name='xxx' where id=xx"
    ret, err := db.Exec(sqlInfo)
    if err != nil {
        fmt.Println("Exec err : ", err)
        return
    }

    //本次操作影響的行數
    rows, err := ret.RowsAffected()
    if err != nil {
        fmt.Println("RowsAffected err : ", err)
        return
    }
    fmt.Println("rows == ", rows)

}

看,修改操作和其他增加,刪除操作類似,寫法基本上差不多,還比較簡單

查詢

查詢操作的話,應該是資料庫操作裡面用的相對更多的操作了 , go 操作 mysql 查詢的話,簡單的 有 2 個注意點:

  • Query 之後的 得到的 rows 需要記得 close
  • 呼叫查詢資料之後,需要記得馬上呼叫 Scan 方法否則持有的資料庫連結不會被釋放
type myInfo struct{
    id int
    name string
    age int
}

func selectInfo(db *sql.DB) {
    sqlInfo := "select * from user"
    rows, err := db.Query(sqlInfo)
    if err != nil {
        fmt.Println("Exec err : ", err)
        return
    }
    // 非常重要:關閉 rows 釋放持有的資料庫連結
    defer rows.Close()
    //輸出查詢出來的行數

    for rows.Next(){
        var u myInfo
        rows.Scan(&u.id,&u.name,&u.age)
        fmt.Printf("id = %d, name = %s, age = %d\n",u.id,u.name,u.age)
    }

}

歡迎點贊,關注,收藏

朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裡

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是阿兵雲原生,歡迎點贊關注收藏,下次見~

相關文章