V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Joker123456789
V2EX  ›  Go 编程语言

Beerus 上线啦,用 Go 开发的 web 解决方案

  •  
  •   Joker123456789 · 2021-12-13 22:38:26 +08:00 · 1805 次点击
    这是一个创建于 872 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Beerus 是一个用 Go 开发的 web 解决方案,包含一个 web 框架,一个数据库操作框架,一个正在规划中的 RPC 框架,目前( web 框架,数据库操作框架 已经发布了第一个版本)

    Web 框架

    因为他是牵头的框架,说到 web 大家想到的肯定是接口管理,所以他的名字就直接沿用了 Beerus ,也就是这一套项目的品牌名称,它是以 net/http 为基础,在此基础上扩展了路由的管理方式,并增加了拦截器,会话管理,用 struct 接收参数,参数验证等功能,还提供了 WebSocket 支持,可以将 http 协议升级到 WebSocket 并实现通信

    数据库操作框架

    名字叫 Beerus-DB ,用到了[go-sql-driver/mysql]来做数据库连接与基础操作,在此基础上做了很多扩展,比如:连接池管理,多数据源,事务管理,单表无 sql 操作,多表以及复杂操作可以自己写 sql ,sql 支持{}占位符,可以用 struct 作为参数来操作数据库等

    示例

    HTTP 示例

    创建一个函数管理路由

    func CreateRoute() {
    	// post route example
        route.POST("/example/post", func (req *commons.BeeRequest, res *commons.BeeResponse) {
            
            res.SendJson(`{"msg":"SUCCESS"}`)
        })
    
        // get route example
        route.GET("/example/get", func (req *commons.BeeRequest, res *commons.BeeResponse) {
        
            res.SendJson(`{"msg":"SUCCESS"}`)
        })
    }
    

    启动服务

    func main() {
        // Interceptors, routes, etc. Loading of data requires its own calls
        routes.CreateRoute()
        
        // Listen the service and listen to port 8080
        beerus.ListenHTTP(8080)
    }
    

    如果你想用实体接收参数,可以这么做

    func CreateRoute() {
        // Example of parameter conversion to struct and parameter checksum
        route.POST("/example/post", func (req *commons.BeeRequest, res *commons.BeeResponse) {
            
            // 首先需要建一个实体的实例
            param := DemoParam{}
            
            // 调用这个函数,将请求的参数全部提取到实体中,支持任意请求方式
            params.ToStruct(req, &param, param)
            
            // 对参数进行验证,如果没通过就返回 提示信息
            var result = params.Validation(req, &param, param)
            if result != params.SUCCESS {
                res.SendErrorMsg(1128, result)
                return
            }
            
            // 如果你觉得上面的麻烦,那么也可以这样,直接采用一步到位的方式:参数提取 + 验证
            var result = params.ToStructAndValidation(req, &param, param)
            if result != params.SUCCESS {
                res.SendErrorMsg(1128, result)
                return
            }
            
            
            res.SendJson(`{"msg":"SUCCESS"}`)
        })
    }
    
    // DemoParam If you have a struct like this, and you want to put all the parameters from the request into this struct
    type DemoParam struct {
        TestStringReception  string  `notnull:"true" msg:"TestStringReception Cannot be empty" routes:"/example/put"`
        TestIntReception     int     `max:"123" min:"32" msg:"TestIntReception The value range must be between 32 - 123" routes:"/example/post"`
        TestUintReception    uint    `max:"123" min:"32" msg:"TestUintReception The value range must be between 32 - 123"`
        TestFloatReception   float32 `max:"123" min:"32" msg:"TestFloatReception The value range must be between 32 - 123"`
        TestBoolReception    bool
        TestStringRegReception string `reg:"^[a-z]+$" msg:"TestStringRegReception Does not meet the regular"`
        TestBeeFileReception commons.BeeFile
        
        TestJsonReception []string
    }
    
    

    WebSocket 示例

    创建一个函数来管理 WebSocket 路由

    func CreateWebSocketRoute() {
    	wroute.AddWebSocketRoute("/ws/test", onConnection, onMessage, onClose)
    	wroute.AddWebSocketRoute("/ws/test2", onConnection, onMessage, onClose)
    }
    
    // In order to save time, only three functions are used below. In practice, you can configure a set of functions for each wroute
    
    func onConnection(session *wparams.WebSocketSession, msg string) {
    	session.SendString("connection success")
    }
    
    func onMessage(session *wparams.WebSocketSession, msg string) {
    	session.SendString("I got the message.")
    }
    
    func onClose(session *wparams.WebSocketSession, msg string) {
        println(msg + "-------------------------------")
    }
    

    启动服务

    func main() {
        // Interceptors, routes, etc. Loading of data requires its own calls
        routes.CreateRoute()
        routes.CreateWebSocketRoute()
        
        // Listen the service and listen to port 8080
        beerus.ListenHTTP(8080)
    }
    
    

    单表操作

    根据条件查询单表数据

    conditions := make([]*entity.Condition,0)
    conditions = append(conditions, &entity.Condition{Key:"id > ?", Val: 10})
    conditions = append(conditions, &entity.Condition{Key:"and user_name = ?", Val: "bee"})
    conditions = append(conditions, &entity.Condition{Key: "order by create_time desc", Val: entity.NotWhere})
    
    resultMap, err := operation.GetDBTemplate("Data source name").Select("table name", conditions)
    

    根据条件修改单表数据

    // 条件设定
    conditions := make([]*entity.Condition,0)
    conditions = append(conditions, &entity.Condition{Key:"id = ?", Val: 1})
    
    // 要修改的数据设定
    data := ResultStruct{UserName: "TestNoSqlUpdate"}
    
    // 执行修改操作
    result, err := operation.GetDBTemplate("Data source name").Update("table name", dbutil.StructToMapIgnore(&data, data, true),conditions)
    

    根据条件删除单表数据

    // 设定删除条件
    conditions := make([]*entity.Condition,0)
    conditions = append(conditions, &entity.Condition{Key:"id = ?", Val: 2})
    
    // 执行删除操作
    _, err := operation.GetDBTemplate("Data source name").Delete("table name", conditions)
    

    插入一条数据

    data := ResultStruct{
        UserName: "TestNoSqlInsert",
        UserEmail: "[email protected]",
        UpdateTime: "2021-12-09 13:50:00",
    }
    
    result, err := operation.GetDBTemplate("Data source name").Insert("table name", dbutil.StructToMapIgnore(&data, data, true))
    

    自定义 sql

    查询

    // struct 参数
    res := ResultStruct{Id: 1}
    
    // 查多条, 注:这里需要用到占位符
    resultMap, err := operation.GetDBTemplate("Data source name").SelectListByMap("select * from xt_message_board where id < {id}", dbutil.StructToMap(&res, res))
    
    // 查一条, 注:这里需要用到占位符
    resultMap, err := operation.GetDBTemplate("Data source name").SelectOneByMap("select * from xt_message_board where id < {id}", dbutil.StructToMap(&res, res))
    

    增删改

    res := ResultStruct{Id: 1, UserName: "TestUpdateByMap"}
    
    // 无论是增删改,都是调用 ExecByMap 函数,将 sql 和参数传入即可,注:这里需要用到占位符
    operation.GetDBTemplate("Data source name").ExecByMap("update xt_message_board set user_name = {user_name} where id = {id}", dbutil.StructToMap(&res, res))
    

    分页查询

    data := ResultStruct{
        UserName: "TestNoSqlInsert",
        UserEmail: "[email protected]",
    }
    
    // 创建分页参数
    param := entity.PageParam{
        CurrentPage: 1,  // 第几页
        PageSize: 20,  // 每页多少条
        Params: dbutil.StructToMap(&data, data), // 查询参数
    }
    
    // 执行查询操作
    result, err := operation.GetDBTemplate("Data source name").SelectPage("select * from xt_message_board where user_name = {user_name} and user_email = {user_email}", param)
    

    事务管理

    // 开启事务
    id, err := db.Transaction()
    if err != nil {
        t.Error("TestUpdateTx: " + err.Error())
        return
    }
    
    res := ResultStruct{Id: 1, UserName: "TestUpdateTx"}
    
    // 注:这里使用的不是 GetDBTemplate ,ExecByMap ,而是 GetDBTemplateTx 和 ExecByTxMap
    // 使用事务和不使用事务,在调用的函数上,区别就是多了个 Tx
    ss, err := operation.GetDBTemplateTx(id, "dbPoolTest").ExecByTxMap("update xt_message_board set user_name = {user_name} where id = {id}", dbutil.StructToMap(&res, res))
    
    if err != nil {
        // 如果有问题就回滚事务
        db.Rollback(id)
        t.Error("TestUpdateTx: " + err.Error())
        return
    }
    
    // 提交事务
    db.Commit(id)
    

    想了解更多的话,可以查阅我们的文档哦

    https://beeruscc.com

    yanzhiling2001
        1
    yanzhiling2001  
       2021-12-13 23:08:36 +08:00
    好像看懂了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   996 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:55 · PVG 07:55 · LAX 16:55 · JFK 19:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.