Go sql-web
今天把database/sql部分的内容学习了一下,然后写了一个小项目,巩固一下,代码整体不难。
这个项目用net/http和database/sql实现了一个简单的用户注册和登录功能。
全局变量和初始化
代码语言:javascript复制 var db *sql.DB
var tmpl *template.Template
func init() {
var err error
// 使用你自己的数据库凭证替换
dsn := "root:root@tcp(127.0.0.1:3306)/sql-web?charset=utf8"
db, err = sql.Open("mysql", dsn)
if (err != nil) {
log.Fatal(err)
}
// 测试数据库连接
if (err = db.Ping(); err != nil) {
log.Fatal(err)
}
tmpl, err = template.ParseFiles("index.html")
if (err != nil) {
log.Fatalf("解析模板失败: %v", err)
}
}
var db *sql.DB
:声明一个全局变量,用于数据库连接。var tmpl *template.Template
:声明一个全局变量,用于 HTML 模板。func init()
:init
函数在main
函数之前执行。这里用于:- 使用数据源名称(DSN)
root:root@tcp(127.0.0.1:3306)/sql-web?charset=utf8
打开 MySQL 数据库连接。 - 使用
db.Ping()
测试数据库连接。 - 解析
index.html
模板文件,并将其赋值给tmpl
变量。
- 使用数据源名称(DSN)
主函数
代码语言:javascript复制 go复制代码func main() {
http.HandleFunc("/register", registerHandler)
http.HandleFunc("/login", loginHandler)
log.Println("服务器启动在 :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
http.HandleFunc("/register", registerHandler)
:注册registerHandler
函数来处理/register
请求。http.HandleFunc("/login", loginHandler)
:注册loginHandler
函数来处理/login
请求。log.Println("服务器启动在 :8080")
:记录一条信息,指示服务器启动在端口8080
。log.Fatal(http.ListenAndServe(":8080", nil))
:启动 HTTP 服务器并监听8080
端口。如果服务器启动失败,则记录错误并退出程序。
注册处理函数
代码语言:javascript复制 func registerHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
username := r.FormValue("username")
password := r.FormValue("password")
if username == "" || password == "" {
http.Error(w, "用户名和密码不能为空", http.StatusBadRequest)
return
}
var exists bool
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE username = ?)", username).Scan(&exists)
if err != nil {
http.Error(w, "服务器错误", http.StatusInternalServerError)
return
}
if exists {
http.Error(w, "用户已存在", http.StatusConflict)
return
}
_, err = db.Exec("INSERT INTO users (username, password) VALUES (?, ?)", username, password)
if err != nil {
http.Error(w, "服务器错误", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "login", http.StatusSeeOther)
return
}
err := tmpl.ExecuteTemplate(w, "index.html", nil)
if err != nil {
http.Error(w, "执行模板错误", http.StatusInternalServerError)
}
}
registerHandler
:处理用户注册请求。r.Method == "POST"
:检查请求方法是否为 POST。r.FormValue("username")
和r.FormValue("password")
:获取表单中的用户名和密码。if username == "" || password == ""
:检查用户名和密码是否为空。如果为空,返回错误。db.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE username = ?)", username).Scan(&exists)
:查询数据库检查用户名是否已存在。if exists
:如果用户已存在,返回错误。db.Exec("INSERT INTO users (username, password) VALUES (?, ?)", username, password)
:将新用户插入数据库。http.Redirect(w, r, "login", http.StatusSeeOther)
:重定向到登录页面。tmpl.ExecuteTemplate(w, "index.html", nil)
:如果请求方法不是 POST,渲染index.html
模板。
登录处理函数
代码语言:javascript复制 func loginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
username := r.FormValue("username")
password := r.FormValue("password")
if username == "" || password == "" {
http.Error(w, "用户名和密码不能为空", http.StatusBadRequest)
return
}
var dbPassword string
err := db.QueryRow("SELECT password FROM users WHERE username = ?", username).Scan(&dbPassword)
if err != nil {
if err == sql.ErrNoRows {
http.Error(w, "用户名或密码无效", http.StatusUnauthorized)
} else {
http.Error(w, "服务器错误", http.StatusInternalServerError)
}
return
}
if password != dbPassword {
http.Error(w, "用户名或密码无效", http.StatusUnauthorized)
return
}
fmt.Fprint(w, "登录成功")
return
}
err := tmpl.ExecuteTemplate(w, "index.html", nil)
if err != nil {
http.Error(w, "执行模板错误", http.StatusInternalServerError)
}
}
loginHandler
:处理用户登录请求。r.Method == "POST"
:检查请求方法是否为 POST。r.FormValue("username")
和r.FormValue("password")
:获取表单中的用户名和密码。if username == "" || password == ""
:检查用户名和密码是否为空。如果为空,返回错误。db.QueryRow("SELECT password FROM users WHERE username = ?", username).Scan(&dbPassword)
:从数据库中查询用户名对应的密码。if err != nil
:如果查询出错,处理错误。if password != dbPassword
:如果密码不匹配,返回错误。fmt.Fprint(w, "登录成功")
:登录成功,输出成功信息。tmpl.ExecuteTemplate(w, "index.html", nil)
:如果请求方法不是 POST,渲染index.html
模板。
前端代码
前端代码也很简单,几个按钮和输入框
代码语言:javascript复制 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register/Login</title>
</head>
<body>
<h1>Register</h1>
<form method="POST" action="/register">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br>
<input type="submit" value="Register">
</form>
<h1>Login</h1>
<form method="POST" action="/login">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br>
<input type="submit" value="Login">
</form>
</body>
</html>