连接数据库。总是在引gorm

问题描述?

代码:

package main

import (
    "database/sql"
    "fmt"
    "html/template"
    "log"
    "net/http"
    "net/url"
    "strings"
    "time"
    "unicode/utf8"

    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "gorm.io/driver/mysql" 
)

// ArticlesFormData 创建博文表单数据
type ArticlesFormData struct {
    Title, Body string
    URL         *url.URL
    Errors      map[string]string
}

var router = mux.NewRouter()
var db *sql.DB

func initDB() {

    var err error
    // 提示没有 Config 方法
    config := mysql.Config{
        User:                 "homestead",
        Passwd:               "secret",
        Addr:                 "127.0.0.1:33060",
        Net:                  "tcp",
        DBName:               "goblog",
        AllowNativePasswords: true,
    }

    // 准备数据库连接池
    db, err = sql.Open("mysql", config.FormatDSN())
    checkError(err)

    // 设置最大连接数
    db.SetMaxOpenConns(25)
    // 设置最大空闲连接数
    db.SetMaxIdleConns(25)
    // 设置每个链接的过期时间
    db.SetConnMaxLifetime(5 * time.Minute)

    // 尝试连接,失败会报错
    err = db.Ping()
    checkError(err)
}

func checkError(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "<h1>Hello, 欢迎来到 goblog!</h1>")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "此博客是用以记录编程笔记,如您有反馈或建议,请联系 "+
        "<a href=\"mailto:summer@example.com\">summer@example.com</a>")
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusNotFound)
    fmt.Fprint(w, "<h1>请求页面未找到 :(</h1><p>如有疑惑,请联系我们。</p>")
}

func articlesShowHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]
    fmt.Fprint(w, "文章 ID:"+id)
}

func articlesIndexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "访问文章列表")

}

func articlesStoreHandler(w http.ResponseWriter, r *http.Request) {
    title := r.PostFormValue("title")
    body := r.PostFormValue("body")

    errors := make(map[string]string)

    if title == "" {
        errors["title"] = "标题不能为空"
    } else if utf8.RuneCountInString(title) < 3 || utf8.RuneCountInString(title) > 10 {
        errors["title"] = "标题长度需介于 3-40"
    }

    if body == "" {
        errors["body"] = "内容不能为空"
    } else if utf8.RuneCountInString(body) < 10 {
        errors["body"] = "内容长度需大于或等于 10 个字节"
    }

    // 检查是否有错误
    if len(errors) == 0 {
        fmt.Fprint(w, "验证通过!<br>")
        fmt.Fprintf(w, "title 的值为: %v <br>", title)
        fmt.Fprintf(w, "title 的长度为: %v <br>", len(title))
        fmt.Fprintf(w, "body 的值为: %v <br>", body)
        fmt.Fprintf(w, "body 的长度为: %v <br>", len(body))
    } else {
        storeURL, _ := router.Get("articles.store").URL()
        data := ArticlesFormData{
            Title:  title,
            Body:   body,
            URL:    storeURL,
            Errors: errors,
        }
        tmpl, err := template.ParseFiles("resources/views/articles/create.gohtml")

        if err != nil {
            panic(err)
        }

        err = tmpl.Execute(w, data)

        if err != nil {
            panic(err)
        }
    }
}

func articlesCreateHandler(w http.ResponseWriter, r *http.Request) {
    storeURL, _ := router.Get("articles.store").URL()
    data := ArticlesFormData{
        Title:  "",
        Body:   "",
        URL:    storeURL,
        Errors: nil,
    }
    tmpl, err := template.ParseFiles("resources/views/articles/create.gohtml")
    if err != nil {
        panic(err)
    }

    err = tmpl.Execute(w, data)
    if err != nil {
        panic(err)
    }
}

func forceHTMLMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 1. 设置标头
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        // 2. 继续处理请求
        next.ServeHTTP(w, r)
    })
}

func removeTrailingSlash(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 1. 除首页以外,移除所有请求路径后面的斜杆
        if r.URL.Path != "/" {
            r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
        }

        // 2. 将请求传递下去
        next.ServeHTTP(w, r)
    })
}

func main() {
    initDB()

    router.HandleFunc("/", homeHandler).Methods("GET").Name("home")
    router.HandleFunc("/about", aboutHandler).Methods("GET").Name("about")

    router.HandleFunc("/articles/{id:[0-9]+}", articlesShowHandler).Methods("GET").Name("articles.show")
    router.HandleFunc("/articles", articlesIndexHandler).Methods("GET").Name("articles.index")
    router.HandleFunc("/articles", articlesStoreHandler).Methods("POST").Name("articles.store")
    router.HandleFunc("/articles/create", articlesCreateHandler).Methods("GET").Name("articles.create")

    // 自定义 404 页面
    router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

    // 中间件:强制内容类型为 HTML
    router.Use(forceHTMLMiddleware)

    // 通过命名路由获取 URL 示例
    homeURL, _ := router.Get("home").URL()
    fmt.Println("homeURL: ", homeURL)
    articleURL, _ := router.Get("articles.show").URL("id", "1")
    fmt.Println("articleURL: ", articleURL)

    http.ListenAndServe(":3000", removeTrailingSlash(router))
}

连接数据库。总是在引gorm

3. 您期望得到的结果?

能正常按照教程执行

4. 您实际得到的结果?

错误:
main.go:16:2: no required module provides package gorm.io/driver/mysql; to add it:
go get gorm.io/driver/mysql

支付宝领个红包就是对我最大的赞赏了
shijf
讨论数量: 2

因为你用 _ 引用,只执行了包的 init,里面的属性拿不到

# config 是 github.com/go-sql-driver/mysql 这个包的一个 struct
config := mysql.Config{
        User:                 "homestead",
        Passwd:               "secret",
...
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!