gorm_dao_generator

command module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2026 License: MIT Imports: 14 Imported by: 0

README

gorm_dao_generator

中文文档

1.Introduction

gorm_dao_generator is a tool for automatically generating Mysql Data Access Object.

2.Advantage
  • Provides a unified generation scheme for database fields, avoiding the problem of database fields that can be seen everywhere in business codes.

  • Provides various database operation interfaces including Insert, Delete, Update, Count, Sum, Avg, First, Last, FindOne, FindMany, etc.

  • Provides the ability to expand the database operation interface.

  • Provides two package solutions: subcontracting and non-subcontracting.

  • Supports customization of directory and file name styles.

3.Requirements
  • Go 1.20+
  • MySQL 8.0+
4.Download and install
go env -w GOSUMDB=off
go install github.com/dawnsgo/gorm_dao_generator@latest
go env -w GOSUMDB=on
5.Usage
Usage of gorm_dao_generator:
        gorm_dao_generator [flags] -model-dir=. -model-names=M[:t],M[:t] -dao-dir=./dao
For more information, see:
        https://github.com/dawnsgo/gorm_dao_generator
Flags:
  -dao-dir string
        specify the output directory of dao files; must be set
  -dao-pkg-path string
        specify the package path corresponding to the output directory of the dao files; automatically generated by default
  -file-style string
        specify the generation style for file; options: kebab | underscore | lower | camel | pascal; default is underscore (default "underscore")
  -model-dir string
        specify the model directory; must be set
  -model-names string
		specify one or more modelName[:tableName] pairs; must be set
  -model-pkg-alias string
        specify a model package alias; default no alias
  -model-pkg-path string
        specify the package path corresponding to the model directory; automatically calculated by default
  -sub-pkg-enable
        specify whether to enable sub-pkg; default disable
  -sub-pkg-style string
        specify the generation style for sub-pkg; options: kebab | underscore | lower | camel | pascal; default is kebab (default "kebab")
6.Example
6-1.Create model

File Location: example/model/mail.go

package model

import (
	"time"
)

//go:generate gorm_dao_generator -model-dir=. -model-names=Mail -dao-dir=../dao/
type Mail struct {
	ID       int       `gorm:"column:id"`        // 邮件ID
	Title    string    `gorm:"column:title"`     // 邮件标题
	Content  string    `gorm:"column:content"`   // 邮件内容
	Sender   int64     `gorm:"column:sender"`    // 邮件发送者
	Receiver int64     `gorm:"column:receiver"`  // 邮件接受者
	Status   int       `gorm:"column:status"`    // 邮件状态
	SendTime time.Time `gorm:"column:send_time"` // 发送时间
}
6-2.Generate dao files
go generate ./...
6-3.Generated dao file example

File Location: example/dao/internal/mail.go

// --------------------------------------------------------------------------------------------
// The following code is automatically generated by the gorm_dao_generator tool.
// Please do not modify this code manually to avoid being overwritten in the next generation.
// For more tool details, please click the link to view https://github.com/dawnsgo/gorm_dao_generator
// --------------------------------------------------------------------------------------------

package internal

import (
	"context"
	"errors"
	"fmt"
	modelpkg "github.com/dawnsgo/gorm_dao_generator/example/model"
	"gorm.io/gorm"
	"strconv"
	"strings"
)

type MailOrderBy struct {
	Column string
	Order  string
}

type MailFilterFunc func(cols *MailColumns) interface{}
type MailUpdateFunc func(cols *MailColumns) interface{}
type MailColumnFunc func(cols *MailColumns) []string
type MailOrderFunc func(cols *MailColumns) []MailOrderBy

type Mail struct {
	Columns   *MailColumns
	Database  *gorm.DB
	TableName string
}

type MailColumns struct {
	ID       string // 邮件ID
	Title    string // 邮件标题
	Content  string // 邮件内容
	Sender   string // 邮件发送者
	Receiver string // 邮件接受者
	Status   string // 邮件状态
	SendTime string // 发送时间
}

var mailColumns = &MailColumns{
	ID:       "id",        // 邮件ID
	Title:    "title",     // 邮件标题
	Content:  "content",   // 邮件内容
	Sender:   "sender",    // 邮件发送者
	Receiver: "receiver",  // 邮件接受者
	Status:   "status",    // 邮件状态
	SendTime: "send_time", // 发送时间
}

func NewMail(db *gorm.DB) *Mail {
	dao := &Mail{}
	dao.Columns = mailColumns
	dao.TableName = "mail"
	dao.Database = db

	return dao
}

// New create a new instance and return
func (dao *Mail) New(tx *gorm.DB) *Mail {
	d := &Mail{}
	d.Columns = dao.Columns
	d.TableName = dao.TableName
	d.Database = tx

	return d
}

// Table create a new table db instance
func (dao *Mail) Table(ctx context.Context) *gorm.DB {
	return dao.Database.Model(&modelpkg.Mail{}).Table(dao.TableName).WithContext(ctx)
}

// Insert executes an insert command to insert multiple documents into the collection.
func (dao *Mail) Insert(ctx context.Context, models ...*modelpkg.Mail) (int64, error) {
	if len(models) == 0 {
		return 0, errors.New("models is empty")
	}

	var rst *gorm.DB

	if len(models) == 1 {
		rst = dao.Table(ctx).Create(models[0])
	} else {
		rst = dao.Table(ctx).Create(models)
	}

	return rst.RowsAffected, rst.Error
}

// Delete executes a delete command to delete at most one document from the collection.
func (dao *Mail) Delete(ctx context.Context, filterFunc ...MailFilterFunc) (int64, error) {
	db := dao.Table(ctx)

	if len(filterFunc) > 0 && filterFunc[0] != nil {
		db = db.Where(filterFunc[0](dao.Columns))
	}

	rst := db.Delete(&modelpkg.Mail{})

	return rst.RowsAffected, rst.Error
}

// Update executes an update command to update documents in the collection.
func (dao *Mail) Update(ctx context.Context, filterFunc MailFilterFunc, updateFunc MailUpdateFunc, columnFunc ...MailColumnFunc) (int64, error) {
	db := dao.Table(ctx)

	if filterFunc != nil {
		db = db.Where(filterFunc(dao.Columns))
	}

	if len(columnFunc) > 0 && columnFunc[0] != nil {
		db = db.Select(columnFunc[0](dao.Columns))
	}

	if updateFunc != nil {
		rst := db.Updates(updateFunc(dao.Columns))

		return rst.RowsAffected, rst.Error
	}

	return 0, nil
}

// Count returns the number of documents in the collection.
func (dao *Mail) Count(ctx context.Context, filterFunc ...MailFilterFunc) (count int64, err error) {
    db := dao.Table(ctx)

	if len(filterFunc) > 0 && filterFunc[0] != nil {
		db = db.Where(filterFunc[0](dao.Columns))
	}

	err = db.Count(&count).Error

	return
}

// Sum returns the sum of the given field.
func (dao *Mail) Sum(ctx context.Context, columnFunc MailColumnFunc, filterFunc ...MailFilterFunc) (sums []float64, err error) {
	columns := columnFunc(dao.Columns)
	if len(columns) == 0 {
		return
	}

	fields := make([]string, len(columns))
	for i, column := range columns {
		fields[i] = fmt.Sprintf("COALESCE(SUM(%s), 0) as `sum_%d`", column, i)
	}

	db := dao.Table(ctx).Select(strings.Join(fields, ","))

	if len(filterFunc) > 0 && filterFunc[0] != nil {
		db = db.Where(filterFunc[0](dao.Columns))
	}

	rst := make(map[string]interface{}, len(columns))

	if err = db.Scan(&rst).Error; err != nil {
		return
	}

	for i := range columns {
		val, _ := rst[fmt.Sprintf("sum_%d", i)]
		sum, _ := strconv.ParseFloat(val.(string), 64)
		sums = append(sums, sum)
	}

	return
}

// Avg returns the avg of the given field.
func (dao *Mail) Avg(ctx context.Context, columnFunc MailColumnFunc, filterFunc ...MailFilterFunc) (avgs []float64, err error) {
	columns := columnFunc(dao.Columns)
	if len(columns) == 0 {
		return
	}

	fields := make([]string, len(columns))
	for i, column := range columns {
		fields[i] = fmt.Sprintf("COALESCE(AVG(%s), 0) as `avg_%d`", column, i)
	}

	db := dao.Table(ctx).Select(strings.Join(fields, ","))

	if len(filterFunc) > 0 && filterFunc[0] != nil {
		db = db.Where(filterFunc[0](dao.Columns))
	}

	rst := make(map[string]interface{}, len(columns))

	if err = db.Scan(&rst).Error; err != nil {
		return
	}

	for i := range columns {
		val, _ := rst[fmt.Sprintf("avg_%d", i)]
		avg, _ := strconv.ParseFloat(val.(string), 64)
		avgs = append(avgs, avg)
	}

	return
}

// First executes a first command and returns a model for one record in the table.
func (dao *Mail) First(ctx context.Context, filterFunc MailFilterFunc, columnFunc ...MailColumnFunc) (*modelpkg.Mail, error) {
	var (
		model = &modelpkg.Mail{}
		db    = dao.Table(ctx)
	)

	if filterFunc != nil {
		db = db.Where(filterFunc(dao.Columns))
	}

	if len(columnFunc) > 0 && columnFunc[0] != nil {
		columns := columnFunc[0](dao.Columns)

		if len(columns) > 0 {
			db = db.Select(columns)
		}
	}

	if rst := db.First(model); rst.Error != nil {
		if errors.Is(rst.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, rst.Error
	}

	return model, nil
}

// Last executes a last command and returns a model for one record in the table.
func (dao *Mail) Last(ctx context.Context, filterFunc MailFilterFunc, columnFunc ...MailColumnFunc) (*modelpkg.Mail, error) {
	var (
		model = &modelpkg.Mail{}
		db    = dao.Table(ctx)
	)

	if filterFunc != nil {
		db = db.Where(filterFunc(dao.Columns))
	}

	if len(columnFunc) > 0 && columnFunc[0] != nil {
		columns := columnFunc[0](dao.Columns)

		if len(columns) > 0 {
			db = db.Select(columns)
		}
	}

	if rst := db.Last(model); rst.Error != nil {
		if errors.Is(rst.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, rst.Error
	}

	return model, nil
}

// FindOne executes a take command and returns a model for one record in the table.
func (dao *Mail) FindOne(ctx context.Context, filterFunc MailFilterFunc, columnFunc ...MailColumnFunc) (*modelpkg.Mail, error) {
	var (
		model = &modelpkg.Mail{}
		db    = dao.Table(ctx)
	)

	if filterFunc != nil {
		db = db.Where(filterFunc(dao.Columns))
	}

	if len(columnFunc) > 0 && columnFunc[0] != nil {
		columns := columnFunc[0](dao.Columns)

		if len(columns) > 0 {
			db = db.Select(columns)
		}
	}

	if rst := db.Take(model); rst.Error != nil {
		if errors.Is(rst.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, rst.Error
	}

	return model, nil
}

// FindMany executes a find command and returns many models the matching documents in the collection.
func (dao *Mail) FindMany(ctx context.Context, filterFunc MailFilterFunc, columnFunc MailColumnFunc, orderFunc MailOrderFunc, limitAndOffset ...int) ([]*modelpkg.Mail, error) {
	var (
		models = make([]*modelpkg.Mail, 0)
		db     = dao.Table(ctx)
	)

	if filterFunc != nil {
		db = db.Where(filterFunc(dao.Columns))
	}

	if columnFunc != nil {
		columns := columnFunc(dao.Columns)

		if len(columns) > 0 {
			db = db.Select(columns)
		}
	}

	if orderFunc != nil {
		orders := orderFunc(dao.Columns)

		for _, order := range orders {
			db = db.Order(fmt.Sprintf("%s %s", order.Column, order.Order))
		}
	}

	if len(limitAndOffset) > 0 {
		db = db.Limit(limitAndOffset[0])
	}

	if len(limitAndOffset) > 1 {
		db = db.Offset(limitAndOffset[1])
	}

	rst := db.Scan(&models)

	if rst.Error != nil {
		if errors.Is(rst.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, rst.Error
	}

	return models, nil
}

File Location: example/dao/mail.go

package dao

import (
	"github.com/dawnsgo/gorm_dao_generator/example/dao/internal"
	"gorm.io/gorm"
)

type (
	MailColumns = internal.MailColumns
	MailOrderBy = internal.MailOrderBy
)

type Mail struct {
	*internal.Mail
}

func NewMail(db *gorm.DB) *Mail {
	return &Mail{Mail: internal.NewMail(db)}
}
6-4.Use the generated dao file

File Location: example/main.go

package main

import (
	"context"
	"github.com/dawnsgo/gorm_dao_generator/example/dao"
	"github.com/dawnsgo/gorm_dao_generator/example/model"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
	"time"
)

func main() {
	// MySQL 8.0+ DSN with allowNativePasswords for authentication compatibility
	dsn := "root:123456@tcp(127.0.0.1:3306)/game?charset=utf8mb4&parseTime=True&loc=Local&allowNativePasswords=true"

	db, err := gorm.Open(mysql.New(mysql.Config{
		DSN: dsn,
	}))
	if err != nil {
		log.Fatalf("connect mysql server failed: %v", err)
	}

	mailDao := dao.NewMail(db)
	baseCtx := context.Background()

	_, err = mailDao.Insert(baseCtx, &model.Mail{
		Title:    "gorm_dao_generator introduction",
		Content:  "The gorm_dao_generator is a tool for automatically generating Mysql Data Access Object.",
		Sender:   1,
		Receiver: 2,
		Status:   1,
		SendTime: time.Now(),
	})
	if err != nil {
		log.Fatalf("failed to insert into mysql database: %v", err)
	}

	mail, err := mailDao.FindOne(baseCtx, func(cols *dao.MailColumns) interface{} {
		return map[string]interface{}{
			cols.Receiver: 2,
		}
	})
	if err != nil {
		log.Fatalf("failed to find a row of data from mysql database: %v", err)
	}

	log.Printf("%+v", mail)
}
6-5.Run result:
$ go run main.go
$ 2025/05/14 20:28:41 &{ID:1 Title:gorm_dao_generator introduction Content:The gorm_dao_generator is a tool for automatically generating Mysql Data Access Object. Sender:1 Receiver:2 Status:1 SendTime:2025-05-14 20:28:42 +0800 CST}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL