天涯海角异孤星
sql中的连接查询有inner join(内连接)、left join(左连接)、right join(右连接)、full join(全连接)四种方式,它们之间其实并没有太大区别,仅仅是查询出来的结果有所不同。
1.inner join,在两张表进行连接查询时,只保留两张表中完全匹配的结果集。
2.left join,在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。
3.right join,在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。
4.full join,在两张表进行连接查询时,返回左表和右表中所有没有匹配的行。
rand.Intn()
函数是个伪随机函数,不管运行多少次都只会返回同样的随机数,因为它默认的资源就是单一值,所以必须调用 rand.Seed()
, 并且传入一个变化的值作为参数,如 time.Now().UnixNano()
, 就是可以生成时刻变化的值。rand.Intn(n)
返回值为 [0,n)
之间的整数。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
// 初始化随机数的资源库, 如果不执行这行, 不管运行多少次都返回同样的值
rand.Seed(time.Now().UnixNano())
// rand.Intn(100) 返回随机值为 0-99
fmt.Println("A number from 1-100:", 1+rand.Intn(100))
}
你可以使用 go-assets 将静态资源打包到可执行文件中。
其实,是使用 go-assets-builder 命令将目录下的资源文件打包到一个 assets.go 文件里,然后就可以只引用 assets.go 实现文件访问,不再依赖于原先的静态资源目录。
直接看官网的例子吧:https://github.com/gin-gonic/examples/tree/master/assets-in-binary
示例代码:
func main() {
router := gin.Default()
router.Static("/assets", "./assets")
router.StaticFS("/more_static", http.Dir("my_file_system"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
// 监听并在 0.0.0.0:8080 上启动服务
router.Run(":8080")
}
其中
router.Static
指定某个目录为静态资源目录,可直接访问这个目录下的资源,url 要具体到资源名称。router.StaticFS
比前面一个多了个功能,当目录下不存 index.html 文件时,会列出该目录下的所有文件。router.StaticFile
指定某个具体的文件作为静态资源访问。HTTP 重定向很容易。 内部、外部重定向均支持。
外部重定向使用 Redirct
,路由重定向使用 HandleContext
:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "https://www.yangdx.com/")
})
r.GET("/test1", func(c *gin.Context) {
c.Request.URL.Path = "/test2"
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"hello": "world"})
})
r.Run(":8080")
}
请参阅 issues 并尝试以下示例:
package main
import (
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"golang.org/x/sync/errgroup"
)
var (
g errgroup.Group
)
func router01() http.Handler {
e := gin.New()
e.Use(gin.Recovery())
e.GET("/", func(c *gin.Context) {
c.JSON(
http.StatusOK,
gin.H{
"code": http.StatusOK,
"error": "Welcome server 01",
},
)
})
return e
}
func router02() http.Handler {
e := gin.New()
e.Use(gin.Recovery())
e.GET("/", func(c *gin.Context) {
c.JSON(
http.StatusOK,
gin.H{
"code": http.StatusOK,
"error": "Welcome server 02",
},
)
})
return e
}
func main() {
server01 := &http.Server{
Addr: ":8080",
Handler: router01(),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
server02 := &http.Server{
Addr: ":8081",
Handler: router02(),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
g.Go(func() error {
return server01.ListenAndServe()
})
g.Go(func() error {
return server02.ListenAndServe()
})
if err := g.Wait(); err != nil {
log.Fatal(err)
}
}