安装搭建项目基本框架
创建基本文件夹即go运行文件
创建一个(名字自定义)文件夹,创建src文件在src文件夹创建以下
conf : 用来存放一些配置信息 例如redis数据库的端口号密码等
controller : 用来编写接口方法等
model : 来链接数据库 配置gorm 创建表等
route : 用来分发路由 给子路由添加路由前缀等
schemas :用来存放结构体 获取数据用的 更方便
static :静态文件夹 可以存放图片等
tool :可以存放一些方法 需要用的时候直接调用 使代码更加整洁
utils:用来存放工具方法 例如jwt 发送验证码等
go.mod : Go模块文件
main.go : 项目运行文件
安装gin框架进行配置
打开终端cd进入项目内的src文件夹 输入以下代码进行安装
go get -u github.com/gin-gonic/gin
安装好后 go.mod是下图样子
在main.go文件里进行编辑
在main()里添加GET方法测试一下是否成功渲染
确认没问题后可以删除
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// 前后端跨域
func Cors() gin.HandlerFunc {
return func(context *gin.Context) {
method := context.Request.Method
context.Header("Access-Control-Allow-Origin", "*")
context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token")
context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT")
context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
context.Header("Access-Control-Allow-Credentials", "true")
if method == "OPTIONS" {
context.AbortWithStatus(http.StatusNoContent)
}
}
}
func main() {
// 1.创建路由
r := gin.Default()
r.Use(Cors()) //配置跨域
//测试一下是否成功渲染
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "hello World!")
})
r.Run(":8000")
}
成功的效果
配置mysql数据库链接及gorm操作’
安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u gorm.io/driver/sqlite
配置
在model文件加里创建model.go文件进行编辑
package model
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// 用户表
type User struct {
gorm.Model //系统自带的一个模型
Name string `gorm:"type:varchar(20);not null"` // 三个约束类型意思都差不多
Mobile string `gorm:"varchar(11);not null;unique"` //unique 唯一性
Password string `gorm:"size:255;not null"`
Tscore int //整形
Tmoney float32 //浮点型
BeoverdueMoney float32 //逾期金额
}
var DB *gorm.DB
func InitDB() *gorm.DB {
dsn := "root:数据库密码@tcp(127.0.0.1:3306)/数据库名?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) //使用mysq连接数据库,第二个参数可以增加更多的配置(可有可无)
if err != nil {
fmt.Println(err)
}
db.AutoMigrate(&User{}) //创建表?判断是否表结构存在
DB = db
return db
}
func GetDb() *gorm.DB { //使用gorm的话调用这个就可以了
return DB
}
在main()里导入进去
然后运行程序 数据库就生成表了
package main
import (
"myproject/model"
"net/http"
"github.com/gin-gonic/gin"
)
// 前后端跨域
func Cors() gin.HandlerFunc {
... //代码太长省略了
}
func main() {
model.InitDB() //导入model
// 1.创建路由
r := gin.Default()
r.Use(Cors()) //配置跨域
r.Run(":8000")
}
配置路由 创建接口方法文件
在controller文件夹里创建接口文件
例如:创建 user_controller.go文件在里面进行编写
package controller
import (
"fmt"
"github.com/gin-gonic/gin"
)
func User(userGrp *gin.RouterGroup) {
userGrp.Use().GET("/user", getuser) //路由前缀 指定方法
}
func getuser(c *gin.Context) {
name := c.PostForm("name")
fmt.Println(name)
c.JSON(200, gin.H{
"code": 200,
"name": name,
})
}
在route路由分配文件夹里创建router.go路由分配文件
package route
import (
"github.com/gin-gonic/gin"
"myproject/controller"
)
func PathRoute(r *gin.Engine) *gin.Engine {
userPath := r.Group("") //添加前缀
{
controller.User(userPath)
}
return r
}
在main()里导入进去
注意:导入路由一定要在配置跨域之后,要不然前端会接收不到
package main
import (
"myproject/model"
"myproject/route"
"net/http"
"github.com/gin-gonic/gin"
)
... //代码过长 上面的代码省略了
func main() {
model.InitDB() //导入model
// 1.创建路由
r := gin.Default()
r.Use(Cors()) //配置跨域
route.PathRoute(r) //导入路由
r.Run(":8000")
}
jwt token的配置及封装
安装
go get -u github.com/dgrijalva/jwt-go
在utils里创建jwt.go文件进行配置
package utils
import (
"time"
"github.com/dgrijalva/jwt-go"
)
var jwtKey = []byte("a_secret_crect")
type Claims struct {
UserId int
jwt.StandardClaims
}
//加密
func ReleaseToken(user int) (string, error) {
expirationTime := time.Now().Add(7 * 24 * time.Hour)
claims := &Claims{
UserId: user,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
IssuedAt: time.Now().Unix(),
Issuer: "oceanlearn.tech",
Subject: "user token",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", err
}
return tokenString, nil
}
//解密
func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (i interface{}, err error) {
return jwtKey, nil
})
return token, claims, err
}
在接口文件里调用示范
func Token(c *gin.Context) {
var id int = 3
token, _ := utils.ReleaseToken(id)
fmt.Println("sssss", token)
token2, res, _ := utils.ParseToken(token)
fmt.Println("aaaaaaaa", token2, res)
c.JSON(200, gin.H{
"code": 200,
"msg": "发送成功",
"res": res,
"token1": token,
"token2": token2,
"resid": res.UserId,
})
}
redis的链接与封装
在创建好的conf文件里创建app.ini文件
[redis]
address = 127.0.0.1:6379
password = ""
db = 0
安装
go get -u github.com/go-ini/ini
go get -u github.com/gomodule/redigo/redis
在创建好的utils文件夹里创建myredis.go文件
package utils
import (
"fmt"
"os"
"sync"
"time"
"github.com/go-ini/ini"
"github.com/gomodule/redigo/redis"
)
var once sync.Once
// RedisClient Redis 服务
type RedisClient struct {
Client *redis.Pool
}
// Redis 全局 Redis
var RedisPool *RedisClient
// ConnectRedis 连接 redis 数据库,设置全局的 Redis 对象
func ConnectRedis() {
config, err := ini.Load("./conf/app.ini")
if err != nil {
//失败
fmt.Printf("Fail to read file: %v", err)
os.Exit(1)
}
address := config.Section("redis").Key("address").String()
password := config.Section("redis").Key("password").String()
db, _ := config.Section("redis").Key("db").Int()
once.Do(func() {
RedisPool = NewClient(address, password, db)
})
con_err := RedisPool.Ping()
if con_err != nil {
panic(con_err)
}
}
// Ping 用以测试 redis 连接是否正常
func (rds *RedisClient) Ping() error {
_, err := rds.Client.Get().Do("ping")
return err
}
// NewClient 创建一个新的 redis 连接
func NewClient(address string, password string, db int) *RedisClient {
// 初始化自定的 RedisClient 实例
rds := &RedisClient{}
// 使用 redis 库里的 NewClient 初始化连接
rds.Client = &redis.Pool{
MaxIdle: 100, //最大空闲
MaxActive: 1000, //最大连接
IdleTimeout: time.Duration(60) * time.Second,
Wait: true,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial(
"tcp",
address,
redis.DialPassword(password),
redis.DialDatabase(int(db)),
redis.DialConnectTimeout(time.Duration(60)*time.Second),
redis.DialReadTimeout(time.Duration(60)*time.Second),
redis.DialWriteTimeout(time.Duration(60)*time.Second),
)
if err != nil {
return nil, err
}
return c, err
},
}
return rds
}
// Set 存储 key 对应的 value,且设置 expiration 过期时间(单位纳秒)
func (rds *RedisClient) Setex(key string, expiration int, value interface{}) bool {
conn := rds.Client.Get()
defer conn.Close()
if _, err := conn.Do("setex", key, expiration, value); err != nil {
fmt.Println(err)
return false
}
return true
}
// //redis分布式锁
//
// func (rds *RedisClient) Setnx(key string) bool {
// conn := rds.Client.Get()
// defer conn.Close()
// val, err := redis.Int(conn.Do("setnx", key, time.Second*100))
// if err != nil {
// return false
// }
// if val == 1 {
// return true
// }
// return false
//
// }
// Get 获取 key 对应的 value
func (rds *RedisClient) Get(key string) string {
conn := rds.Client.Get()
defer conn.Close()
result, err := redis.String(conn.Do("Get", key))
if err != nil {
return ""
}
return result
}
// string删除指定Del key Exists
func (rds *RedisClient) StrDel(key string) {
conn := rds.Client.Get()
defer conn.Close()
result, _ := redis.String(conn.Do("Del", key))
fmt.Println(result)
}
// list 添加
func (rds *RedisClient) ListAdd(key string, value int) bool {
conn := rds.Client.Get()
defer conn.Close()
fmt.Println("存入:", value)
if _, err := conn.Do("LPush", key, value); err != nil {
return false
}
return true
}
// 读取List一个
func (rds *RedisClient) ListPop(key string) string {
conn := rds.Client.Get()
defer conn.Close()
res, err := redis.String(conn.Do("RPop", key))
if err != nil {
return ""
}
return res
}
// 读取所有
func (rds *RedisClient) ListGetAll(key string) []uint8 {
conn := rds.Client.Get()
defer conn.Close()
arr, _ := conn.Do("LRange", key, 0, -1)
//[[49] [49]]
fmt.Println("获取:", arr)
res := arr.([]interface{})
//定义切片
var idlist []uint8
for _, val := range res {
idlist = append(idlist, val.([]uint8)[0])
}
return idlist
}
// 获取长度
func (rds *RedisClient) ListLen(key string) int64 {
conn := rds.Client.Get()
defer conn.Close()
res, err := conn.Do("LLen", key)
fmt.Println(res)
if err != nil {
return 0
}
return res.(int64)
}
func GetRedis() *RedisClient {
return RedisPool
}
在main()里导入进去
package main
import (
"myproject/model"
"myproject/route"
"myproject/utils"
"net/http"
"github.com/gin-gonic/gin"
)
...
func main() {
model.InitDB() //导入model
utils.ConnectRedis() //导入redis
// 1.创建路由
r := gin.Default()
route.PathRoute(r) //导入路由
r.Use(Cors()) //配置跨域
r.Run(":8000")
}
项目的准别工作完成,接下来就是写接口完成功能了