前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go系列 go-admin-core

go系列 go-admin-core

作者头像
六个核弹
发布2023-10-06 18:43:21
1810
发布2023-10-06 18:43:21
举报

这一章节主要学习通过go-admin-core 快速开发一个简单的web项目并做好三层模型分层。

gin

gin 是一个web框架,我们通过 go mod 来使用gin框架进行http接口的开发:

代码语言:javascript
复制
go mod init go-test
go get -u github.com/gin-gonic/gin

我们写一个main方法启动一个http接口。在go 中main 方法必须在main包之下,不同于java中的包必须是物理包,go中的包可以是逻辑包:

代码语言:javascript
复制
package main

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

func main() {
 r := gin.Default()
 r.GET("/", func(c *gin.Context) {
  c.JSON(200, gin.H{
   "message": "TEST",
  })
 })
 r.Run() // listen and serve on 0.0.0.0:8080
}

运行 go mod tidy 更新依赖,启动main方法,访问8080接口:

gorm

接下来我们学习gorm的基本使用,安装gorm 和驱动包:

代码语言:javascript
复制
go get -u github.com/jinzhu/gorm
go get -u gorm.io/driver/mysql

测试连接数据库:

代码语言:javascript
复制
username := "root"              // 账号
password := "123456" // 密码
host := "127.0.0.1"             // 地址
port := 3306                    // 端口
DBname := "test"               // 数据库名称
timeout := "10s"                // 连接超时,10秒
str := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local&timeout=%s", username, password, host, port, DBname, timeout)
db, err := gorm.Open(mysql.Open(str), &gorm.Config{})
if err != nil {
    panic("failed to connect mysql.")
}

至于gorm的查询api用法在后续的web开发中介绍。

go-admin-core

基本了解了上面两大框架,我们直接进入实战,前文说说过,关于go的一些语法细节我们边开发边学习,不必太担心。go-admin-core 是集成并封装了 log,gorm,gin,简化了我们的开发难度,感兴趣的同学可以去阅读一下源码。这里我展示一下这个框架的怎么去使用。main.go源码:

代码语言:javascript
复制
package main

import (
 "poseidon-go/app/admin/router"
)

func main() {
 router.InitRouter()
}


router.go源码:

代码语言:javascript
复制
package router

import (
 "github.com/gin-gonic/gin"
 _ "github.com/gin-gonic/gin"
 log "github.com/go-admin-team/go-admin-core/logger"
 "github.com/go-admin-team/go-admin-core/sdk"
 "gorm.io/driver/mysql"
 "gorm.io/gorm"
 "os"
 "poseidon-go/app/admin/config"
)

var RouterList = make([]func(*gin.RouterGroup), 0)

// InitRouter 路由初始化,不要怀疑,这里用到了
func InitRouter() {
 var r *gin.Engine
 h := sdk.Runtime.GetEngine()
 if h == nil {
  h = gin.New()
  sdk.Runtime.SetEngine(h)
 }
 switch h.(type) {
 case *gin.Engine:
  r = h.(*gin.Engine)
 default:
  log.Fatal("not support other engine")
  os.Exit(-1)
 }
 db, err := gorm.Open(mysql.Open("root:root@tcp/vcp_saas?charset=utf8&parseTime=True&loc=Local"), &gorm.Config{})
 if err != nil {
  log.Error(err)
 }
 sdk.Runtime.SetDb("*", db)
 // 这个必须在路由组之前设置,否则无效
 config.InitMiddleware(r)
 // 可根据业务需求来设置接口版本
 v1 := r.Group("/api/v1")
 for _, f := range RouterList {
  f(v1)
 }
 r.Run(":8080")
}

在这里有几个知识点

  1. p,p,&p 的区别:不同于java ,go 中内存和内存指针是分开的。p 代表当前的内存,p代表当前内存的指针,&p代表当前内存的地址也就是指针的值。

举例:

代码语言:javascript
复制
func main() {
 var p *int
 p = new(int)
 *p = 1
 fmt.Println(p, &p, *p)
}
 
输出
0xc04204a080  0xc042068018  1

扩展一下,如果我再设置一个 *p=2,它的内存地址是变还不变?我们知道,go也是有垃圾回收器的,对比java,我们给一个对象变量赋新值,它是新开辟内存还是覆盖原来的内存,小伙伴们可以思考一下go和java在这个语法上的差别。

  1. 类型, .()被称为类型断言,可以将一个interface{}类型的变量转换成其它类型 ,type 关键字是类型关键字,用于定义类型和结构体。示例:
代码语言:javascript
复制
 var i interface{}
 i="sss"
 fmt.Println(i.(string))
 router.InitRouter()
  1. go 中的包,包是通过import导入的,可以给包起别名,可以直接通过包名调用包中的大写字母开头的所有方法,示例:
代码语言:javascript
复制
package main

import (
 v1 "poseidon-go/app/admin/router"
)

func main() {
 v1.InitRouter()
 v1.Test()
}


InitRouter 方法和Test方法并不在同一个go文件中,但是同包。语法介绍完了,我们写一个三层分层的接口:先注册路由器

代码语言:javascript
复制
package router

import (
 "github.com/gin-gonic/gin"
 "poseidon-go/app/admin/apis"
)

func init() {
 RouterList = append(RouterList, registerTestRouter)
}

func registerTestRouter(v1 *gin.RouterGroup) {
 api := apis.Test{}
 r := v1.Group("/test")
 {
  r.GET("/a", api.GetPage)

 }
}

然后写一个controller,实现数据绑定和调service

代码语言:javascript
复制
package apis

import (
 "github.com/gin-gonic/gin"
 "github.com/gin-gonic/gin/binding"
 "github.com/go-admin-team/go-admin-core/sdk/api"
 "poseidon-go/app/admin/model/dto"
 "poseidon-go/app/admin/service"
)

type Test struct {
 api.Api
}

// 函数名称前面的括号是Go定义这些函数将在其上运行的对象的方式
func (e Test) GetPage(c *gin.Context) {
 req := dto.TestReq{}
 // 结构体初始化
 s := service.Test{}
 // IOC 手动挡
 err := e.MakeContext(c).
  MakeOrm().
  Bind(&req, binding.Form).
  MakeService(&s.Service).
  Errors
 if err != nil {
  e.Logger.Error(err)
  e.Error(500, err, err.Error())
  return
 }
 err = s.Message(&req).Error
 e.OK(">>>>", "xxxxxxxxxxxxx")
}

再实现service:

代码语言:javascript
复制
package service

import (
 "errors"
 "github.com/go-admin-team/go-admin-core/sdk"
 "gorm.io/gorm"
 "poseidon-go/app/admin/model/dto"

 "github.com/go-admin-team/go-admin-core/sdk/service"
)

type Test struct {
 service.Service
}

// GetPage 获取SysApi列表
func (e *Test) Message(req *dto.TestReq) *Test {
 db := sdk.Runtime.GetDbByKey("*")
 var str, model string
 err := db.Model(&str).Scopes().
  First(model, req.GetType()).Error
 if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
  err = errors.New("查看对象不存在或无权查看")
  e.Log.Errorf("Service GetSysApi error:%s", err)
  _ = e.AddError(err)
  return e
 }
 if err != nil {
  e.Log.Errorf("db error:%s", err)
  _ = e.AddError(err)
  return e
 }
 return e
}

这里的知识点主要是方法和结构体的绑定 func (e *Test) Message。方法前面的括号就是将该方法和结构体绑定在一起。

小结

上面代码介绍了基于go-admin-core 实现的三层分层的web代码,下一章节我们接着讲在gin中使用 gorm。

祝大家国庆快乐

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-10-02 07:00,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 六个核弹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • gin
  • gorm
  • go-admin-core
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档