关注掘金有些时日了,这是个好地方,这里的人民虽然摸鱼搞虾,可是一点都不鱼龙混杂更不会瞎搞;这是个好地方,这里的人民虽然T恤短衫,但不是衣冠禽兽;这是个好地方,这里的人民虽然光头秃顶,可是个个都精神饱满,无怨无悔的996,甚至007.java
无能否认,上述的排比实在不咋地,甚至不大通顺,原谅我是个掘金新手,一个刚从某csdn某园删库跑路过来的新手,也请原谅我是个少数民族,在博大精深的汉语面前甚是卑微,可是阻挡不了我对掘金的热情,我向新神和旧神起誓,无论前面是地雷阵仍是万丈深渊,我将为掘金的崛起鞠躬尽瘁死然后已,哎这话说的我都信了,我是确实是个新手,请各位大佬多多关照吧,写博客嘛实话实说一个是为了本身作个笔记,二个嘛也是作个所谓的分享,分享的东西不免是有些不足的地方,if有错误或是不当的地方还请指正.mysql
切入正题:git
一.项目解构github
conf // 配置相关spring
dao // 数据库sql
log // 日志数据库
router // 路由相关,至关于java springMVC中controllerjson
app.go // main函数入口,启动类api
conf.tomf // 配置文件bash
2、部分代码说明
项目入口:
app.go
package main
import (
"fmt"
"github.com/labstack/echo"
"go-learning/conf"
"go-learning/log"
"go-learning/router"
"go-learning/router/response"
"net/http"
)
func main() {
e := echo.New()
e.HTTPErrorHandler = customHTTPErrorHandler
router.RouterInit(e)
e.Logger.Info(e.Start(conf.Conf.Server.Port))
}
//路由错误页面配置
func customHTTPErrorHandler(err error, c echo.Context) {
var (
code = http.StatusInternalServerError
msg interface{}
)
if he, ok := err.(*echo.HTTPError); ok {
code = he.Code
msg = he.Message
if he.Internal != nil {
msg = fmt.Sprintf("%v, %v", err, he.Internal)
}
} else if c.Echo().Debug {
msg = err.Error()
} else {
msg = fmt.Sprintf("%s : %v", http.StatusText(code), err)
}
if _, ok := msg.(string); ok {
msg = c.JSON(http.StatusInternalServerError, response.Error(&response.GlobalErrorCode{ErrorCode: code, Error: fmt.Sprint(msg)}))
}
// Send response
if !c.Response().Committed {
// Issue #608
if c.Request().Method == "HEAD" {
err = c.NoContent(code)
} else {
err = c.JSON(code, msg)
}
if err != nil {
log.Error(err)
}
}
}
复制代码
主函数启动以后加载配置的路由:
主函数中router.RouterInit(e) ->init.go中方法RouterInit->api_router.go中ApiRouters(e *echo.Echo)最终加载路由:
package packet
import (
"github.com/labstack/echo"
)
// 路由器
func ProductRouter(e *echo.Echo) {
// 增
e.POST("/v1/go/learn/add", Add)
// 删
e.POST("/v1/go/learn/del", Del)
// 改
e.POST("/v1/go/learn/update", Update)
// 查
e.GET("/v1/go/learn/get/list", GetList)
}
复制代码
3、实现一个具体的请求
从上述的路由中加载路由,例如:e.POST("/v1/go/learn/add", Add)
Add是指定的实现方法,以下:
packet_product_handler.go中
// 新增商品
func Add(c echo.Context) (err error) {
product := new(service.ProductBO)
if err = c.Bind(product); err != nil{
return c.JSONBlob(http.StatusBadRequest, nil)
}
// 保存
service.Save(product)
return c.JSON(http.StatusOK, response.OK())
}
复制代码
packet_product_handler.go中的service.Save(product)是调用service方法这个是模拟java分层来写的以下:
product_service.go中
func Save(bo *ProductBO) {
do := new(mapper.T_product)
do.Product_name = bo.ProductName
do.Product_url = bo.ProductUrl
do.Created_at = time.Now().Format("2006-01-02 15:04:05")
do.Created_by = "sys"
do.Updated_at = time.Now().Format("2006-01-02 15:04:05")
mapper.Save(do)
}
复制代码
其中ProductBO是一个结构体,以下:
// 成员变量首字母要大写
type (
ProductBO struct {
Id int `json:"id"`
ProductName string `json:"productName"`
ProductUrl string `json:"productUrl"`
}
)
复制代码
最后调用dao与数据库作交互,这里天然是落库了,以下:
func Save(product *T_product) {
db = dao.GetDb()
db.Create(product)
}
复制代码
其中数据库的链接信息是经过db.go的方法获取,以下:
func dbConn(MyUser, Password, Host, Db string, Port int) *gorm.DB {
connArgs := fmt.Sprintf("%s:%s@(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", MyUser,Password, Host, Port, Db )
db, err := gorm.Open("mysql", connArgs)
if err != nil {
log.Fatal(err)
}
db.SingularTable(true)
return db
}
func GetDb() *gorm.DB {
return dbConn("root", "root", "127.0.0.1", "spring_jpa", 3306);
}
复制代码
其中一些数据库的配置能够写到配置文件中,这里就直接放到代码里边了,以上就是一大体的从获取http请求到落库的过程.具体增删改查的代码能够参考github仓库,仓库地址以下:
毕竟是个新手写到东西,刚从java转战过来的,不免会有些不足的地方,但愿多多包含,若是有些误导的地方还请多多去找找度娘或者Google.或者请教掘金的各位大佬.