go数据库-标准库-框架
go的数据操作
- 数据库操作
- mysql
- 增删改查
- redis
- string的get和set
- string的批量MGet和MSet操作
- list操作
- Hash表
- 操作kafka
- gorm
- 常用标准库
- time
- 格式化时间 time.Format()
- 时间戳
- 时间戳转时间
- log
- 普通log
- 配置logger
- 反射reflect
- reflect.TypeOf反射类型
- reflect.ValueOf反射值信息
- 修改值信息
- 框架
- gin
- 目录结构
- code
数据库操作
mysql
增删改查
增加数据add
package mainimport ("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.DBfunc 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 mainimport ("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.DBfunc 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 []Person1err := 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 mainimport ("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.DBfunc 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 mainimport ("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.DBfunc 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 mainimport ("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 mainimport ("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 mainimport ("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 mainimport ("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 mainimport ("fmt""github.com/Shopify/sarama"
)func main() {config := sarama.NewConfig()config.Producer.RequiredAcks = sarama.WaitForAllconfig.Producer.Partitioner = sarama.NewRandomPartitionerconfig.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 mainimport ("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 mainimport ("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 []Userdb.Find(&users)fmt.Println(users)
}type User struct {gorm.ModelId uint `gorm:"AUTO_INCREMENT"`Name string `gorm:"size:50"`Age int `gorm:"size:3"`Birthday time.TimeEmail 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 <nil>} 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 <nil>} 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 <nil>} 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 <nil>} 0 诺克萨斯之手 25 2021-11-12 15:00:10 +0T ritanuoke@qq.com okmjjad}]*/
常用标准库
time
格式化时间 time.Format()
package mainimport ("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 mainimport ("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 mainimport ("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 mainimport "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: messageLdate = 1 << iota // 日期:2009/01/23Ltime // 时间:01:23:23Lmicroseconds // 微秒级别的时间:01:23:23.123123(用于增强Ltime位)Llongfile // 文件全路径名+行号: /a/b/c/d.go:23Lshortfile // 文件名+行号:d.go:23(会覆盖掉Llongfile)LUTC // 使用UTC时间LstdFlags = Ldate | Ltime // 标准logger的初始值
)
package mainimport ("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 mainimport ("fmt""reflect"
)func main() {x := 3.4t := reflect.TypeOf(x) // 查看类型fmt.Println(t)k := t.Kind() // kind可以获取具体类型fmt.Println(k)}/*
float64
float64
*/
reflect.ValueOf反射值信息
package mainimport ("fmt""reflect"
)func main() {x := 3.4t := reflect.ValueOf(x) // 查看值信息fmt.Println(t)k := t.Kind() // kind可以获取具体类型fmt.Println(k)
}/*
3.4
float64
*/
修改值信息
package mainimport ("fmt""reflect"
)func main() {x := 3.4t := 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 mainimport ("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 myGingo 1.17require (github.com/cosmtrek/air v1.27.3 // indirectgithub.com/creack/pty v1.1.17 // indirectgithub.com/fatih/color v1.13.0 // indirectgithub.com/fsnotify/fsnotify v1.5.1 // indirectgithub.com/gin-contrib/sse v0.1.0 // indirectgithub.com/gin-gonic/gin v1.7.4 // indirectgithub.com/go-playground/locales v0.14.0 // indirectgithub.com/go-playground/universal-translator v0.18.0 // indirectgithub.com/go-playground/validator/v10 v10.9.0 // indirectgithub.com/golang/protobuf v1.5.2 // indirectgithub.com/imdario/mergo v0.3.12 // indirectgithub.com/json-iterator/go v1.1.12 // indirectgithub.com/leodido/go-urn v1.2.1 // indirectgithub.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirectgithub.com/lestrrat-go/strftime v1.0.5 // indirectgithub.com/mattn/go-colorable v0.1.11 // indirectgithub.com/mattn/go-isatty v0.0.14 // indirectgithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirectgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirectgithub.com/modern-go/reflect2 v1.0.2 // indirectgithub.com/pelletier/go-toml v1.9.4 // indirectgithub.com/pkg/errors v0.9.1 // indirectgithub.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirectgithub.com/sirupsen/logrus v1.8.1 // indirectgithub.com/ugorji/go/codec v1.2.6 // indirectgithub.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirectgolang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirectgolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirectgolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirectgolang.org/x/text v0.3.6 // indirectgoogle.golang.org/protobuf v1.27.1 // indirectgopkg.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 utilsimport ("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)// 设置 rotatelogslogWriter, 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()//请求IPclientIP := 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 routersimport ("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 middlewareimport ("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 blogHandlerimport ("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 blogHandlerimport ("github.com/gin-gonic/gin"
)func Routers(e *gin.Engine) {e.GET("/post", postHandler)e.GET("/comment", commentHandler)
}
- myGin/app/shop
handler.go
package shopHandlerimport ("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 shopHandlerimport "github.com/gin-gonic/gin"func Routers(e *gin.Engine) {e.GET("/goods", goodsHandler)e.GET("/checkout", checkoutHandler)
}
- myGin/app/show
handler.go
package showimport ("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 showimport "github.com/gin-gonic/gin"func Routers(e *gin.Engine) {e.GET("/async", asyncHandler)e.GET("/sync", syncHandler)
}
go数据库-标准库-框架相关推荐
- C++标准库,框架等资源大汇总!
C++标准库,框架等资源大汇总! C++ 资源大全 关于 C++ 框架.库和资源的一些汇总列表,内容包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C+ ...
- [转载] JAVA从菜鸟【入门】到新手【实习】一一一一Python 内置函数,标准库与第三方库(拓展库),常用框架
参考链接: copyreg -注册pickle支持的函数 掌握了python的基本语法和面向对象的设计思想后是学习了程序设计的"使用"规则, 具体实现和调用要依赖"标准库 ...
- 标准库:DB 数据库
数据库设计思想 数据库设计是很典型的案例,通常我们用它作为学习的样本,在设计中有些模式也会被鉴戒或者被引入其他的领域.首先数据库本身是非常庞大而复杂的概念,跟数据库相关的东西很多,如何在不同类型数据库 ...
- Go 学习笔记(55)— Go 标准库 sql (初始化数据库、插入、更新、删除数据库表、单行查询、多行查询、事务处理)
1. 标准库说明 Go 的标准库中是没有数据库驱动,只提供了驱动接口,有很多第三方实现了驱动,我们这里选择 go-sql-driver 这个实现是目前使用最多的.github 地址是:https:// ...
- Python 标准库之单元测试框架 -- unittest
用Python搭建自动化测试框架,我们需要组织用例以及测试执行,这里博主推荐Python的标准库--unittest. unittest是xUnit系列框架中的一员,如果你了解xUnit的其他成员,那 ...
- ORM映射框架总结--数据库操作库(精修版)
1. ORM数据库操作原理 前面已经介绍过了个人ORM映射框架中的三个核心库: 实体-数据库 映射特性关系: http://www.cnblogs.com/qingyuan/archive ...
- Python标准库介绍
1. 关于Python标准库 众所周知,Python是一个依赖强大的组件库完成对应功能的语言,为了便捷实现各项功能,前辈大牛们打造了多种多样的工具库公开提供给大众使用,而越来越多的库已经因为使用的广泛 ...
- python第三方库排行-140种Python标准库、第三方库和外部工具
导读:Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具. 这些库可用于文件读写.网络抓取和解析.数据连 ...
- python第三方库大全win-Python标准库、第三方库和外部工具汇总
导读:Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具. 这些库可用于文件读写.网络抓取和解析.数据连 ...
最新文章
- matlab中patch命令_matlab 放大平移图形是超出边界问题的处理
- linux es连接mysql_LINUX下使用elasticsearch-jdbc工具实现MySQL同步到ElasticSearch 以及linux 64位centos系统安装jdk1.8...
- 【Python-ML】神经网络-Theano张量库(GPU版的Numpy)
- 【OpenCV】函数imread的使用之通道数变化
- 简易计算器里的小数点在程序中怎么表示_财管普通计算器(内有彬哥经验)
- 横向全屏滑动插件_【案例】JQuery横向手风琴图片轮播切换代码
- php的类图怎么生成_PHP网站怎么划UML类图?
- HR:不录用她,是因为她“太傻白甜了……”
- Redis - 在电商购物车场景下的实战分析
- 今年最值得期待的JavaScript传奇绿皮书登场!
- 请求header_Flutter 基于网络请求框架Dio的二次封装
- Weblogic配置和部署
- xshell以及xftp免费版
- mysql数据库查询总条数
- 2018中南大学 计算机考研分数,2018中南大学考研分数线多少分?
- 谷仓创造区块链+电商消费新模式
- 宿主机无法访问docker容器的坑
- 互联网时代,知识付费行业发展空间巨大
- 电子商务商城系统开发方案:中大型交易类电商网站架构设计
- java switch 条件_Java ——if条件语句 switch语句