Java、Go主流框架在快速编写小型web项目对比

73 阅读2分钟

哈哈,水一篇文章

最近在写学校的数据库课设,因为要写两个的原因,我一个用java写,一个用go写,对比一下。

本文仅考虑超小型web项目搭建

用Java写的是航空售票管理

  • spring boot
  • mybatis-plus
  • lombok
  • sa-token

用go写的是学校考勤系统

  • gin
  • gorm
  • viper

因为是简单的数据库课设,没有写业务层,直接控制层调用持久层。

结构如下

image.png

image.png

给我的体会就是虽然spring boot十分重量级,但是在写这种“课设”级别的web项目时是吊打其他框架

对比gin优势如下

  • 更简单的接口路由声明,更简单的参数绑定
  • 成熟的配置文件管理
  • 自动配置简直无敌
  • gin性能更好一点

mybatis-plus对比gorm

  • 个人感觉注解比tag可读性和灵活性更好
  • gorm联表比mybatis更好写一点

遇到的问题

  1. 因为前端是我朋友写的,他告诉我go项目某个接口无法调用,我发现是因为他传的json参数的类型不对。看下面的例子

    func main() {
        jsonStr := `{"a":1,"b":"2"}`
        data := &struct {
           A int `json:"a"`
           B int `json:"b"`
        }{}
        err := json.Unmarshal([]byte(jsonStr), data)
        if err != nil {
           panic(err)
        }
        fmt.Println(data)
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class A {
        Integer a;
        Integer b;
    }
    public static void main(String[] args) throws JsonProcessingException {
        String json = "{\"a\":1,\"b\":\"2\"}";
        ObjectMapper mapper = new ObjectMapper();
        A a = mapper.readValue(json, A.class);
        System.out.println(a);
    }
    

    上面的Java和Go解析同一个字符串,但是Java遇到"b":"2"的情况会类型转换,而go会报错。

  2. 统一时间json序列化格式,go格式修改还是比较复杂的 package util

    import (
        "database/sql/driver"
        "fmt"
        "strings"
        "time"
    )
    
    type JsonTime time.Time
    
    // MarshalJSON 自定义时间格式
    func (t *JsonTime) MarshalJSON() ([]byte, error) {
        formatted := fmt.Sprintf(""%v"", time.Time(*t).Format("2006-01-02 15:04:05"))
        return []byte(formatted), nil
    }
    
    // UnmarshalJSON 解析前端传来的时间字符串
    func (t *JsonTime) UnmarshalJSON(data []byte) (err error) {
        //前端接收的时间字符串
        str := string(data)
        //去除接收的str收尾多余的"
        timeStr := strings.Trim(str, """)
        t1, err := time.Parse("2006-01-02 15:04:05", timeStr)
        *t = JsonTime(t1)
        return err
    }
    
    // Value 实现 database/sql 的驱动接口
    func (t *JsonTime) Value() (driver.Value, error) {
        tTime := time.Time(*t)
        if tTime.IsZero() {
           return nil, nil
        }
        return tTime, nil
    }
    
    // Scan 从数据库读取时间值
    func (t *JsonTime) Scan(v interface{}) error {
        value, ok := v.(time.Time)
        if ok {
           *t = JsonTime(value)
           return nil
        }
        return fmt.Errorf("cannot convert %v to timestamp", v)
    }
    
    func (t *JsonTime) String() string {
        tTime := time.Time(*t)
        return tTime.String()
    }
    

    对比Java

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")