在Golang项目中,如何使用Gorm快速生成模型与常用方法

885 阅读2分钟

个人项目或者是小型项目中,经常会涉及到许多无需经常维护的表,而且这些业务几乎都是一样的,每个都编写一遍实在是太过浪费时间了,于是根据数据表快速生成结构体与CRUD是一个非常实用的功能

  1. 首先,需要借助Gorm库与Gorm的Gen库,文档中提供了多种生成方案,但是我在使用的过程中,好像并不友好,于是我总结了一下自己使用的方案。

go get -u gorm.io/gorm

go get -u gorm.io/gen

  1. 项目结构与目录创建

image.png

  1. 创建数据库、数据表,并在业务代码中创建一个数据库连接(这个过程很简单,我不再演示),下图是一张新闻表
CREATE TABLE `news_info` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键编号',
  `title` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '标题',
  `brief` varchar(300) COLLATE utf8mb4_general_ci NOT NULL COMMENT '新闻导语',
  `keywords` varchar(300) COLLATE utf8mb4_general_ci NOT NULL COMMENT '关键词',
  `content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '新闻内容',
  `status` tinyint NOT NULL DEFAULT '2' COMMENT '状态 1-启用 2-禁用',
  `origin` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '来源',
  `origin_link` varchar(300) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '来源链接',
  `created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `updated_at` timestamp NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='新闻信息'

4. 由于Golang对时间格式处理并不友好,所以我们需要自定义一个时间格式的处理函数,于是我有了一个WrapTime类型作为时间类型

// project/pkg/formatTime/wrap_time.go

package formatTime  
  
import (  
    "database/sql"  
    "database/sql/driver"  
    "time"  
)  
  
const (  
    YYYY_MM_DD = "2006-01-02"  
    YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05"  
)  
  
type WrapTime sql.NullTime  
  
func (t *WrapTime) UnmarshalJSON(data []byte) (err error) {  
    if string(data) == "null" {  
    t.Valid = false  
    return nil  
    }  

    var now time.Time  
    if len(string(data)) == len(YYYY_MM_DD)+2 {  
    now, err = time.ParseInLocation(`"`+YYYY_MM_DD+`"`, string(data), time.Local)  
    t.Valid = true  
    t.Time = now  
    } else {  
    now, err = time.ParseInLocation(`"`+YYYY_MM_DD_HH_MM_SS+`"`, string(data), time.Local)  
    t.Valid = true  
    t.Time = now  
    }  
    return  
}  
  
func (t WrapTime) MarshalJSON() ([]byte, error) {  
    if !t.Valid {  
    return []byte("null"), nil  
    }  
    b := make([]byte, 0, len(YYYY_MM_DD_HH_MM_SS)+2)  
    b = append(b, '"')  
    b = t.Time.AppendFormat(b, YYYY_MM_DD_HH_MM_SS)  
    b = append(b, '"')  
    return b, nil  
}  
  
func (t WrapTime) String() string {  
    if !t.Valid {  
    return "null"  
    }  
    return t.Time.Format(YYYY_MM_DD_HH_MM_SS)  
}  
  
// Value insert timestamp into mysql need this function.  
func (t WrapTime) Value() (driver.Value, error) {  
    if !t.Valid {  
    return nil, nil  
    }  
    return t.Time, nil  
}  
  
// Scan value time.Time  
func (t *WrapTime) Scan(v interface{}) error {  
    return (*sql.NullTime)(t).Scan(v)  
}  
  
func NewWrapTime(t time.Time) WrapTime {  
    if t.IsZero() {  
    return WrapTime{Valid: false}  
    }  
    return WrapTime{Valid: true, Time: t}  
}

5. 自定义一个生成函数的入口,例如main.go,其实可以给一个启用的选项

g := gen.NewGenerator(gen.Config{  
    OutPath: "./internal/dal/query",
    OutFile: "",  
    Mode: gen.WithDefaultQuery | gen.WithQueryInterface | gen.WithoutContext,  
    FieldNullable: true,  
})

  1. 让我们看一下生成的文件结构

image.png

  1. 再来看一下生成的query文件,可以说是非常全面了,几乎涵盖了一切常用的方法

image.png

image.png

image.png

image.png

image.png

  1. 接下来,我们只需要在业务中使用即可,我的实现并不一定是好的,新手可以参考一下,不要被我的方案限制思维

image.png

  1. 到此,关于如何在golang的web项目中使用gorm快速生成增删改查的方案就写完了,希望对你能有所帮助,有好的实现与方案可以在评论区提出,感谢!