周日花时间研究了gin框架的使用,基本上还算满意。
参考:https://blog.csdn.net/u010649766/article/details/79458004
代码参考:https://github.com/onebig32/gin-learn
教程代码:https://github.com/caogenlaoxian/golang/tree/master/app
本文的实现基于windows系统。
一、项目文件建立
(1)首先确定你的workspace,我在F盘下创建了一个叫gin的工作目录,通过设置环境变量,加入GOPATH中,进入到gin目录中,执行go env 查看是否已经加入GOPATH
(2)在gin下创建项目的目录,比如app,为了实现简单的mvc,我们在app下创建controllers/apis/,models,database,views,conf
创建完后的目录结构应该是:
二、创建文件
在各个文件夹里创建需要的文件,无需与文件夹的名字一样。
三、code
在写实例的时候,遇到个困惑就是import文件的时候,一定要注意你当前文件所在的目录,否则会报错,找不到对应的文件,我在文件的import中,使用了"../app/controllers/apis"来导入文件
四、遇到的坑
(1)在练习过程中,方法如果要被外部调用,首字母必须大写,这个对于已经习惯驼峰写法来讲非常难受,包括定义的变量、结构体都要遵循这种规则,一定要注意。
(2) 在设置路由的时候同样的请求方式如GET:
router.GET("/user/list", GetUserApi)
router.GET("/user/:id", GetUserByIdApi)
这样写会报【panic: wildcard route ':id' conflicts with existing children in path '/user/:id'】,经过试验,需要对其中一个进行修改。具体还没太明白为什么。
(3) 在main.go中router.Run(":8080"),一定要传递字符串,端口号前要跟冒号
(4) 执行 go run *.go
以下是本次的代码
创建user表:
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
`last_name` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
文件地址:F:/gin/app/controllers/apis/userApi.go
package apis
import (
"fmt"
"log"
"net/http"
"strconv"
. "../../../app/models"
"github.com/gin-gonic/gin"
)
func IndexApi(c *gin.Context) {
c.String(http.StatusOK, "It Works!")
}
func AddUserApi(c *gin.Context) {
firstName := c.Request.FormValue("first_name")
lastName := c.Request.FormValue("last_name")
u := User{FirstName: firstName, LastName: lastName}
rs, err := u.AddUser()
if err != nil {
log.Fatalln(err)
return
}
msg := fmt.Sprintf("insert success %d", rs)
c.JSON(http.StatusOK, gin.H{
"data": true,
"msg": msg,
})
}
func UpdateUserApi(c *gin.Context) {
firstName := c.Request.FormValue("first_name")
lastName := c.Request.FormValue("last_name")
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Fatalln(err)
}
u := User{Id: id}
u.GetUserInfoById()
if u.Id > 0 {
u.FirstName = firstName
u.LastName = lastName
ra, err := u.UpdateUser()
if err != nil {
log.Fatalln(err)
}
msg := fmt.Sprintf("update success %d", ra)
c.JSON(http.StatusOK, gin.H{
"data": true,
"msg": msg,
})
} else {
c.JSON(http.StatusOK, gin.H{
"data": nil,
"msg": "not found",
})
}
}
func DelUserApi(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
u := User{Id: id}
u.GetUserInfoById()
if u.Id > 0 {
rs, _err := u.DelUser()
if _err != nil {
log.Fatalln(_err)
}
msg := fmt.Sprintf("delete success %d", rs)
c.JSON(http.StatusOK, gin.H{
"data": true,
"msg": msg,
})
}
}
//查询所有
func GetUserApi(c *gin.Context) {
var u User
users, err := u.GetUserInfo()
if err != nil {
log.Fatalln(err)
}
c.JSON(http.StatusOK, gin.H{
"data": users,
"msg": "success",
})
}
//根据id查询
func GetUserByIdApi(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
u := User{Id: id}
u.GetUserInfoById()
if u.Id > 0 {
c.JSON(http.StatusOK, gin.H{
"data": u,
"msg": "success",
})
} else {
c.JSON(http.StatusOK, gin.H{
"data": nil,
"msg": "user not found",
})
}
}
文件地址:f:/gin/app/database/mysql_driver.go
package database
import (
"database/sql"
"log"
_ "github.com/go-sql-driver/mysql"
)
var SqlDB *sql.DB
//初始化
func init() {
var err error
SqlDB, err = sql.Open("mysql", "数据库用户名:数据库密码@tcp(数据库ip地址:端口号)/test?charset=utf8")
if err != nil {
log.Fatal(err.Error())
}
err = SqlDB.Ping()
if err != nil {
log.Fatal(err.Error())
}
}
文件地址: f:/gin/app/models/userModel.go
package models
import (
. "../../app/database"
)
type User struct {
Id int `json:"id" form "id"`
FirstName string `json:"first_name" form:"first_name"`
LastName string `json:"last_name" form: "last_name"`
}
//查询
func (u *User) GetUserInfo() (users []User, err error) {
//创建一个切片
users = make([]User, 0)
rows, err := SqlDB.Query("select id, first_name, last_name from user")
if err != nil {
return
}
for rows.Next() {
var user User
rows.Scan(&user.Id, &user.FirstName, &user.LastName)
users = append(users, user)
}
if err = rows.Err(); err != nil {
return
}
return
}
//第二种查询方法
func (u *User) GetUserInfoById() (err error) {
SqlDB.QueryRow("select id,first_name,last_name from user where id = ?", u.Id).Scan(&u.Id, &u.FirstName, &u.LastName)
return
}
//插入
func (u *User) AddUser() (lastId int64, err error) {
rs, err := SqlDB.Exec("INSERT INTO user(first_name,last_name)VALUES(?,?)", u.FirstName, u.LastName)
if err != nil {
return
}
lastId, err = rs.LastInsertId()
return lastId, err
}
//修改
func (u *User) UpdateUser() (effect_num int64, err error) {
rs, err := SqlDB.Exec("UPDATE user SET first_name= ?,last_name = ? where id = ?", u.FirstName, u.LastName)
if err != nil {
return
}
effect_num, err = rs.RowsAffected()
return effect_num, err
}
//删除
func (u *User) DelUser() (effort_num int64, err error) {
rs, err := SqlDB.Exec("DELETE FROM user where id= ?", u.Id)
if err != nil {
return
}
effort_num, err = rs.RowsAffected()
return
}
文件地址:f:/gin/app/router.go
package main
import (
. "../app/controllers/apis"
"github.com/gin-gonic/gin"
)
func initRouter() *gin.Engine {
router := gin.Default()
router.GET("/", IndexApi)
router.POST("/user", AddUserApi)
router.GET("/userlist/list", GetUserApi)
router.GET("/user/:id", GetUserByIdApi)
router.GET("/delUser/:id", DelUserApi)
return router
}
文件地址:f:/gin/app/main.go
package main
import (
. "../app/database"
)
func main() {
defer SqlDB.Close()
router := initRouter()
router.Run(":8080")
}