个人项目或者是小型项目中,经常会涉及到许多无需经常维护的表,而且这些业务几乎都是一样的,每个都编写一遍实在是太过浪费时间了,于是根据数据表快速生成结构体与CRUD是一个非常实用的功能
go get -u gorm.io/gorm
go get -u gorm.io/gen
- 项目结构与目录创建
- 创建数据库、数据表,并在业务代码中创建一个数据库连接(这个过程很简单,我不再演示),下图是一张
新闻表
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,
})
- 让我们看一下生成的文件结构
- 再来看一下生成的
query文件,可以说是非常全面了,几乎涵盖了一切常用的方法
- 接下来,我们只需要在业务中使用即可,我的实现并不一定是好的,新手可以参考一下,不要被我的方案限制思维
- 到此,关于如何在golang的web项目中使用gorm快速生成增删改查的方案就写完了,希望对你能有所帮助,有好的实现与方案可以在评论区提出,感谢!