go数据库-标准库-框架

go数据库-标准库-框架,第1张

go的数据 *** 作 数据库 *** 作mysql增删改查 redisstring的get和setstring的批量MGet和MSet *** 作list *** 作Hash表 *** 作kafkagorm 常用标准库time格式化时间 time.Format()时间戳时间戳转时间 log普通log配置logger 反射reflectreflect.TypeOf反射类型reflect.ValueOf反射值信息修改值信息 框架gin目录结构code

数据库 *** 作 mysql 增删改查

增加数据add

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

type Person1 struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}

type Place struct {
	Country string `db:"country"`
	City    string `db:"city"`
	TelCode int    `db:"telcode"`
}

var Db *sqlx.DB

func init()  {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
}

func main() {
	r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "弗拉基米尔", "男", "rita@qq.com")
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
	id, err := r.LastInsertId()
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}

	fmt.Println("insert succ:", id)
	defer Db.Close()  // 注意这行代码要写在上面err判断的下面

}

/*
insert succ: 3
*/

查询select

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

type Person1 struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}

type Place struct {
	Country string `db:"country"`
	City    string `db:"city"`
	TelCode int    `db:"telcode"`
}

var Db *sqlx.DB

func init()  {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
}

func main() {
	var person []Person1
	err := Db.Select(&person, "select user_id, username, sex, email from person")
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}

	fmt.Println("select succ:", person)
	defer Db.Close()  // 注意这行代码要写在上面err判断的下面

}


/*
select succ: [{2 stu001 man stu01@qq.com} {3 弗拉基米尔 男 rita@qq.com}]
 */

修改update

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

type Person1 struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}

type Place struct {
	Country string `db:"country"`
	City    string `db:"city"`
	TelCode int    `db:"telcode"`
}

var Db *sqlx.DB

func init()  {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
}

func main() {
	res, err := Db.Exec("update person set username=? where user_id=?", "伊泽瑞尔", 2)
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
	row, err := res.RowsAffected()
	if err != nil{
		fmt.Println("update failed..., ", err)
	}
	fmt.Println("udpate succ:", row)
	defer Db.Close()  // 注意这行代码要写在上面err判断的下面

}


/*
udpate succ: 1
 */

删除delete

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

type Person1 struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}

type Place struct {
	Country string `db:"country"`
	City    string `db:"city"`
	TelCode int    `db:"telcode"`
}

var Db *sqlx.DB

func init()  {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
}

func main() {
	res, err := Db.Exec("delete from person where user_id=?", 2)
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
	row, err := res.RowsAffected()
	if err != nil{
		fmt.Println("delete failed..., ", err)
	}
	fmt.Println("delete succ:", row)
	defer Db.Close()  // 注意这行代码要写在上面err判断的下面

}


/*
delete succ: 1
 */

redis string的get和set
package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
)

func main() {
	r, err := redis.Dial("tcp", "localhost:6379")
	if err != nil{
		fmt.Println("conn redis failed,", err)
		return
	}
	fmt.Println("redis conn success")
	defer r.Close()

	_, err = r.Do("Set", "abc", 100)
	if err != nil{
		fmt.Println(err)
		return
	}

	rg, err := redis.Int(r.Do("Get", "abc"))
	if err != nil{
		fmt.Println(err)
		return
	}
	fmt.Println(rg)

}


/*
redis conn success
100

 */
string的批量MGet和MSet *** 作
package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
)

func main() {
	r, err := redis.Dial("tcp", "localhost:6379")
	if err != nil{
		fmt.Println("conn redis failed,", err)
		return
	}
	fmt.Println("redis conn success")
	defer r.Close()

	_, err = r.Do("MSet", "杜拉基米尔", 100, "法外狂徒", 200)
	if err != nil{
		fmt.Println(err)
		return
	}

	rg, err := redis.Ints(r.Do("MGet", "杜拉基米尔", "法外狂徒"))
	if err != nil{
		fmt.Println(err)
		return
	}
	fmt.Println(rg)

}


/*
redis conn success
[100 200]

 */
list *** 作
package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
)

func main() {
	r, err := redis.Dial("tcp", "localhost:6379")
	if err != nil{
		fmt.Println("conn redis failed,", err)
		return
	}
	fmt.Println("redis conn success")
	defer r.Close()

	_, err = r.Do("lpush", "name_list", "死亡宣告", "黑暗收割者", "死神封印")
	if err != nil{
		fmt.Println(err)
		return
	}

	rg, err := redis.String(r.Do("lpop", "name_list"))
	if err != nil{
		fmt.Println("get name_list,", err)
		return
	}
	fmt.Println(rg)

}


/*
redis conn success
死神封印

 */
Hash表
package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
)

func main() {
	r, err := redis.Dial("tcp", "localhost:6379")
	if err != nil{
		fmt.Println("conn redis failed,", err)
		return
	}
	fmt.Println("redis conn success")
	defer r.Close()

	_, err = r.Do("HSet", "books", "efg", 200)
	if err != nil{
		fmt.Println(err)
		return
	}

	rg, err := redis.Int(r.Do("HGet", "books", "efg"))
	if err != nil{
		fmt.Println("get name_list,", err)
		return
	}
	fmt.Println(rg)

}


/*
redis conn success
200

 */
*** 作kafka 生产者
package main

import (
	"fmt"
	"github.com/Shopify/sarama"
)

func main() {
	config := sarama.NewConfig()
	config.Producer.RequiredAcks = sarama.WaitForAll
	config.Producer.Partitioner = sarama.NewRandomPartitioner
	config.Producer.Return.Successes = true

	// 构造一个消息
	msg := &sarama.ProducerMessage{}
	msg.Topic = "test"
	msg.Value = sarama.StringEncoder(`{"a": 1, "b": 2}`)
	client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config)
	if err != nil{
		fmt.Println("producer closed, err:", err)
	}
	defer client.Close()
	// 发送消息
	pid, offset, err := client.SendMessage(msg)
	if err != nil{
		fmt.Println("send msg failed, err:", err)
		return
	}
	fmt.Printf("pid:%v offset:%v\n", pid, offset)



}

消费者
package main

import (
	"fmt"
	"github.com/Shopify/sarama"
)

func main()  {
	consumer, err := sarama.NewConsumer([]string{"127.0.0.0.1:9092"}, nil)
	if err != nil{
		fmt.Printf("failed to start consumer, err:%v\n", err)
		return
	}
	patitionList, err := consumer.Partitions("test")
	if err != nil {
		fmt.Printf("failed to get list of patitionList, err:%v\n", err)
		return
	}
	fmt.Println(patitionList)
	for par:= range patitionList{
		pc, err := consumer.ConsumePartition("test", int32(par), sarama.OffsetNewest)
		if err != nil{
			fmt.Printf("failed to start consumer partition %d,err:%v\n", par, err)
			return
		}
		defer pc.AsyncClose()
		go func(sarama.PartitionConsumer) {
			for msg := range pc.Messages(){
				fmt.Printf("Partition:%d Offset:%d Key:%v Value:%v", msg.Partition,
					msg.Offset, msg.Key, msg.Value)
			}
		}(pc)
	}
}
gorm
package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"time"
)

func main() {
	db, err := gorm.Open("mysql", "root:root@(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local") // 这里的库后面是没有/的
	if err != nil {
		fmt.Println("failed to connect mysql:", err)
		return
	}
	defer db.Close()

	// 自动迁移数据结构(table schema)
	/*
	注意:在gorm中,默认的表名都是结构体名称的复数形式,比如User结构体默认创建的表为users;
		db.SingularTable(true)可以取消表名和结构体一致
	*/
	//db.AutoMigrate(&User{})

	//db.Create(&User{Name: "卡西奥佩娅", Age: 18, Birthday: time.Now(), Email: "ritashenv@qq.com", PassWord: "adcsadsad"})
	//db.Create(&User{Name: "诺克萨斯之手", Age: 25, Birthday: time.Now(), Email: "ritanuoke@qq.com", PassWord: "okmjjad"})

	var users []User
	db.Find(&users)
	fmt.Println(users)
}

type User struct {
	gorm.Model
	Id uint	`gorm:"AUTO_INCREMENT"`
	Name string `gorm:"size:50"`
	Age int `gorm:"size:3"`
	Birthday time.Time
	Email string `gorm:"type:varchar(50);unique_index"`
	PassWord string `gorm:"type:varchar(25)"`
}

/*
[{{1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC } 0 法外狂徒 22 0001-01-01 00:00:00 +0000 UTC rita@qq.com } {{2 0001-01-01 00:00:00 +0000 UTC 000101 00:00:00 +0000 UTC } 0 弗拉基米尔 24 0001-01-01 00:00:00 +0000 UTC rita1@qq.com } {{3 2021-11-12 15:00:10 +0800 CST 2021-11-12 15:00:10 +0800 CST } 0 卡西奥021-11-12 15:00:10 +0800 CST ritashenv@qq.com adcsadsad} {{4 2021-11-12 15:00:10 +0800 CST 2021-11-12 15:00:10 +0800 CST } 0 诺克萨斯之手 25 2021-11-12 15:00:10 +0T ritanuoke@qq.com okmjjad}]


 */

常用标准库 time 格式化时间 time.Format()
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now)
	// 24小时制
	fmt.Println(now.Format("2006-01-02 15:04:05"))
	fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
	// 12小时制
	fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
	fmt.Println(now.Format("2006/01/02 15:04"))
	fmt.Println(now.Format("15:04 2006/01/02"))
	fmt.Println(now.Format("2006/01/02"))
}

/*
2021-11-12 15:44:54.131919 +0800 CST m=+0.000099412
2021-11-12 15:44:54
2021-11-12 15:44:54.131 Fri Nov
2021-11-12 03:44:54.131 PM Fri Nov
2021/11/12 15:44
15:44 2021/11/12
2021/11/12

 */

时间戳
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now.Format("2006-01-02 15:04:05"))
	// 时间戳
	timestamp := now.Unix()
	fmt.Println(timestamp) // 秒级时间戳
	fmt.Println(timestamp * 1000) // 毫秒级时间戳
	nanostamp := now.UnixNano()
	fmt.Println(nanostamp) // 纳秒级时间戳

}

/*
2021-11-12 15:52:56
1636703576
1636703576000
1636703576717912000
 */
时间戳转时间
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now.Format("2006-01-02 15:04:05"))
	// 时间戳
	timestamp := now.Unix()
	timeFormat := time.Unix(timestamp, 0) // 将时间戳转时间
	fmt.Println(timeFormat.Format("2006-01-02 15:04:05"))

}

/*
2021-11-12 16:00:33
2021-11-12 16:00:33
 */

log 普通log
package main

import "log"

func main() {
	log.Println("这是一个很普通的日志")
	v := "花姿彩"
	log.Printf("这是一条%s日志\n", v)
	log.Fatalln("这是一条会触发fatal的日志")

}

/*
2021/11/12 16:09:54 这是一个很普通的日志
2021/11/12 16:09:54 这是一条花姿彩日志
2021/11/12 16:09:54 这是一条会触发fatal的日志
 */

配置logger

log标准库中的Flags函数会返回标准logger的输出配置,而SetFlags函数用来设置标准logger的输出配置。
log标准库提供了如下的flag选项,它们是一系列定义好的常量。

const (
    // 控制输出日志信息的细节,不能控制输出的顺序和格式。
    // 输出的日志在每一项后会有一个冒号分隔:例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
    Ldate         = 1 << iota     // 日期:2009/01/23
    Ltime                         // 时间:01:23:23
    Lmicroseconds                 // 微秒级别的时间:01:23:23.123123(用于增强Ltime位)
    Llongfile                     // 文件全路径名+行号: /a/b/c/d.go:23
    Lshortfile                    // 文件名+行号:d.go:23(会覆盖掉Llongfile)
    LUTC                          // 使用UTC时间
    LstdFlags     = Ldate | Ltime // 标准logger的初始值
)
package main

import (
	"log"
)

func main() {
	log.SetFlags(log.Llongfile|log.Lmicroseconds|log.Ldate)
	log.Println("这是一个很普通的日志")

	// 配置日志前缀
	log.SetPrefix("[INFO] ")
	log.Println("这是一个很普通的日志")

}

/*
2021/11/12 16:40:03.809404 /Users/tiger/GolandProjects/awesomeProject/10.go:9: 这是一个很普通的日志
[INFO] 2021/11/12 16:40:03.809523 /Users/tiger/GolandProjects/awesomeProject/10.go:13: 这是一个很普通的日志
*/

反射reflect reflect.TypeOf反射类型
package main

import (
	"fmt"
	"reflect"
)

func main() {
	x := 3.4
	t := reflect.TypeOf(x) // 查看类型
	fmt.Println(t)
	k := t.Kind() // kind可以获取具体类型
	fmt.Println(k)

}

/*
float64
float64
*/

reflect.ValueOf反射值信息
package main

import (
	"fmt"
	"reflect"
)

func main() {
	x := 3.4
	t := reflect.ValueOf(x) // 查看值信息
	fmt.Println(t)
	k := t.Kind() // kind可以获取具体类型
	fmt.Println(k)
}

/*
3.4
float64
*/

修改值信息
package main

import (
	"fmt"
	"reflect"
)

func main() {
	x := 3.4
	t := reflect.ValueOf(&x) // 查看值信息
	fmt.Println(t)
	k := t.Kind() // kind可以获取具体类型
	fmt.Println(k)
	switch k {
	case reflect.Float64:
		t.SetFloat(8.2)
		fmt.Println("a is ", t.Float())
	case reflect.Ptr:
		t.Elem().SetFloat(10.2)
		fmt.Println("case:", t.Elem().Float())
		// 地址
		fmt.Println(t.Pointer())
	}
}

/*
3.4
float64
*/

框架 gin 目录结构
.
├── air.conf
├── app
│   ├── blog
│   │   ├── handler.go
│   │   └── router.go
│   ├── shop
│   │   ├── handler.go
│   │   └── router.go
│   └── show
│       ├── handler.go
│       └── router.go
├── gin.log
├── go.mod
├── go.sum
├── logs
│   ├── myGin.log -> myGin.log.20211117.log
│   └── myGin.log.20211117.log
├── main.go
├── middleware
│   └── middleware.go
├── routers
│   └── router.go
└── utils
    └── log.go

code

myGin/main.go

package main

import (
	"fmt"
	blogHandler "myGin/app/blog"
	shopHandler "myGin/app/shop"
	"myGin/app/show"
	"myGin/routers"
)

func main() {
	routers.Include(shopHandler.Routers, blogHandler.Routers, show.Routers)
	r := routers.Init()
	if err := r.Run(":8888"); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

myGin/go.mod

module myGin

go 1.17

require (
	github.com/cosmtrek/air v1.27.3 // indirect
	github.com/creack/pty v1.1.17 // indirect
	github.com/fatih/color v1.13.0 // indirect
	github.com/fsnotify/fsnotify v1.5.1 // indirect
	github.com/gin-contrib/sse v0.1.0 // indirect
	github.com/gin-gonic/gin v1.7.4 // indirect
	github.com/go-playground/locales v0.14.0 // indirect
	github.com/go-playground/universal-translator v0.18.0 // indirect
	github.com/go-playground/validator/v10 v10.9.0 // indirect
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/imdario/mergo v0.3.12 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/leodido/go-urn v1.2.1 // indirect
	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
	github.com/lestrrat-go/strftime v1.0.5 // indirect
	github.com/mattn/go-colorable v0.1.11 // indirect
	github.com/mattn/go-isatty v0.0.14 // indirect
	github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/pelletier/go-toml v1.9.4 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
	github.com/sirupsen/logrus v1.8.1 // indirect
	github.com/ugorji/go/codec v1.2.6 // indirect
	github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
	golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
	golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
	golang.org/x/text v0.3.6 // indirect
	google.golang.org/protobuf v1.27.1 // indirect
	gopkg.in/yaml.v2 v2.4.0 // indirect
)

myGin/air.conf

# [Air](https://github.com/cosmtrek/air) TOML 格式的配置文件

# 工作目录
# 使用 . 或绝对路径,请注意 `tmp_dir` 目录必须在 `root` 目录下
root = "."
tmp_dir = "tmp"

[build]
# 只需要写你平常编译使用的shell命令。你也可以使用 `make`
cmd = "go build -o ./tmp/main ."
# 由`cmd`命令得到的二进制文件名
bin = "tmp/main"
# 自定义的二进制,可以添加额外的编译标识例如添加 GIN_MODE=release
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# 监听以下文件扩展名的文件.
include_ext = ["go", "tpl", "tmpl", "html"]
# 忽略这些文件扩展名或目录
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# 监听以下指定目录的文件
include_dir = []
# 排除以下文件
exclude_file = []
# 如果文件更改过于频繁,则没有必要在每次更改时都触发构建。可以设置触发构建的延迟时间
delay = 1000 # ms
# 发生构建错误时,停止运行旧的二进制文件。
stop_on_error = true
# air的日志文件名,该日志文件放置在你的`tmp_dir`中
log = "air_errors.log"

[log]
# 显示日志时间
time = true

[color]
# 自定义每个部分显示的颜色。如果找不到颜色,使用原始的应用程序日志。
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# 退出时删除tmp目录
clean_on_exit = true

myGin/utils

log.go

package utils

import (
	"fmt"
	"github.com/gin-gonic/gin"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	log "github.com/sirupsen/logrus"
	prefixed "github.com/x-cray/logrus-prefixed-formatter"
	"os"
	"path"
	"time"
)

// 实例化
var Llogger = log.New()
var stdFormatter *prefixed.TextFormatter  // 命令行输出格式
var fileFormatter *prefixed.TextFormatter // 文件输出格式

func Logger() *log.Logger {
	logFilepath := ""
	if dir, err := os.Getwd(); err == nil {
		logFilepath = dir + "/logs/"
	}
	if err := os.MkdirAll(logFilepath, 0777); err != nil {
		fmt.Println(err.Error())
	}
	logFileName := "myGin" + ".log"
	// 日志文件
	fileName := path.Join(logFilepath, logFileName)
	if _, err := os.Stat(fileName); err != nil {
		if _, err :=os.Create(fileName); err != nil{
			fmt.Println(err.Error())
		}
	}

	// 写入文件
	src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil{
		fmt.Println("err", err)
	}

	// 设置日志格式
	stdFormatter = &prefixed.TextFormatter{
		FullTimestamp:   true,
		TimestampFormat: "2006-01-02.15:04:05.000000",
		ForceFormatting: true,
		ForceColors:     true,
		DisableColors:   false,
	}
	fileFormatter = &prefixed.TextFormatter{
		FullTimestamp:   true,
		TimestampFormat: "2006-01-02.15:04:05.000000",
		ForceFormatting: true,
		ForceColors:     false,
		DisableColors:   true,
	}



	// 设置输出
	Llogger.Out = src

	// 设置日志级别
	Llogger.SetFormatter(stdFormatter)
	Llogger.SetLevel(log.DebugLevel)


	// 设置 rotatelogs
	logWriter, err := rotatelogs.New(
		// 分割后的文件名称
		fileName + ".%Y%m%d.log",

		// 生成软链,指向最新日志文件
		rotatelogs.WithLinkName(fileName),

		// 设置最大保存时间(7天)
		//rotatelogs.WithMaxAge(7*24*time.Hour),

		// 设置日志切割时间间隔(1天)
		//rotatelogs.WithRotationTime(7*24*time.Hour),

		// 设置日志的切割大小
		rotatelogs.WithRotationSize(20*1024*1024),

		// 设置日志的保存个数
		rotatelogs.WithRotationCount(10),

	)

	writeMap := lfshook.WriterMap{
		log.InfoLevel:  logWriter,
		log.FatalLevel: logWriter,
		log.DebugLevel: logWriter,
		log.WarnLevel:  logWriter,
		log.ErrorLevel: logWriter,
		log.PanicLevel: logWriter,
	}

	lfHook := lfshook.NewHook(writeMap, fileFormatter)
	Llogger.SetOutput(os.Stdout)
	Llogger.AddHook(lfHook)

	return Llogger
}

func LoggerToFile() gin.HandlerFunc {
	logger := Logger()
	return func(c *gin.Context) {
		// 开始时间
		startTime := time.Now()
		//处理请求
		c.Next()
		//结束时间
		endTime := time.Now()
		//执行时间
		latencyTime := endTime.Sub(startTime)
		//请求方式
		reqMethod :=c.Request.Method
		//请求路由
		reqUri := c.Request.RequestURI
		//状态码
		statusCode := c.Writer.Status()
		//请求IP
		clientIP := c.ClientIP()

		// 日志格式
		logger.WithFields(log.Fields{
			"status_code"  : statusCode,
			"latency_time" : latencyTime,
			"client_ip"    : clientIP,
			"req_method"   : reqMethod,
			"req_uri"      : reqUri,
		}).Info()
	}
}


myGin/routers

router.go

package routers

import (
	"github.com/gin-gonic/gin"
	"myGin/middleware"
	"myGin/utils"
)

type Option func(engine *gin.Engine)

var options = []Option{}

//注册app的路由配置
func Include(opts ...Option)  {
	options = append(options, opts...)
}

func Init() *gin.Engine {
	r := gin.New()
	r.Use(utils.LoggerToFile())
	r.Use(middleware.MiddleWare())
	for _, opt := range options{
		opt(r)
	}
	return r
}

myGin/middleware
middleware.go

package middleware

import (
	"github.com/gin-gonic/gin"
	"myGin/utils"
	"time"
)

func MiddleWare() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()
		utils.Llogger.Info("中国件开始执行了")
		// 设置变量到Context的key中,可以通过Get()获取
		c.Set("request", "中间件")
		status := c.Writer.Status()
		utils.Llogger.Info("中间件执行完毕", status)
		t2 := time.Since(t)
		utils.Llogger.Info("执行中间件耗时", t2)
	}
}

myGin/app

myGin/app/blog

handler.go

package blogHandler

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func postHandler(c *gin.Context)  {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello www.tiger.com",
	})
}

func commentHandler(c *gin.Context)  {
	c.String(http.StatusOK, "你是猩红收割者弗拉基米尔吗")
}

router.go

package blogHandler

import (
	"github.com/gin-gonic/gin"
)


func Routers(e *gin.Engine) {
	e.GET("/post", postHandler)
	e.GET("/comment", commentHandler)
}


myGin/app/shop
handler.go
package shopHandler

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

func goodsHandler(c *gin.Context)  {
	name := c.DefaultQuery("name", "法外狂徒")
	c.JSON(http.StatusOK, gin.H{"messsage": fmt.Sprintf("这是一个%s的英雄", name)})
}

func checkoutHandler(c *gin.Context)  {
	name := c.DefaultQuery("name", "弗拉基米尔")
	c.JSON(http.StatusOK, gin.H{"messsage": fmt.Sprintf("这是一个%s的英雄", name)})
}

router.go

package shopHandler

import "github.com/gin-gonic/gin"

func Routers(e *gin.Engine) {
	e.GET("/goods", goodsHandler)
	e.GET("/checkout", checkoutHandler)
}


myGin/app/show
handler.go
package show

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"myGin/utils"
	"net/http"
	"time"
)

func asyncHandler(c *gin.Context)  {
	go func() {
		time.Sleep(3 * time.Second)
		utils.Llogger.Infof("异步执行%s", "这是一个异步执行的接口")
	}()
	c.JSON(http.StatusOK, gin.H{"messsage": fmt.Sprintf("这是一个%s的接口 async", "异步")})
}

func syncHandler(c *gin.Context)  {
	time.Sleep(3 * time.Second)
	c.JSON(http.StatusOK, gin.H{"messsage": fmt.Sprintf("这是一个%s的接口 sync", "同步")})
}

router.go

package show

import "github.com/gin-gonic/gin"

func Routers(e *gin.Engine) {
	e.GET("/async", asyncHandler)
	e.GET("/sync", syncHandler)
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/994490.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存