GORM Migrate & GORMGen

126 阅读4分钟

定义GROM struct

SQL

  • DECIMAL(12,6);精度12;即总计12位「整数+小数点」;小数点6位;整数6位
    • 1382249.1168 会报错,因为整数部分超限
  • 各字段长度不要过长,否则创建联合索引时,跟所选字段长度总和有关;总计超长字段会报错
    • Error 1071 (42000): Specified key was too long; max key length is 3072 bytes
  • not null;对应数据库 NOT NULL
  • 联合索引;对应
UNIQUE KEY `idx_all_column` (`app_name`,`function_name`,`unit_price`,`price_unit`,`price`,`date`,`product`,`count`,`unit`),
  KEY `idx_x_bill_daily_statements_deleted_at` (`deleted_at`)
type XBillMonthlyStatement struct {
	gorm.Model
	Name          string  `json:"name" gorm:"type:varchar(32)"`                                             // 公司简称
	FullName      string  `json:"fullName" gorm:"type:varchar(64)"`                                         // 公司全称
	TotalPrice    float64 `json:"totalPrice" gorm:"type:decimal(12,4)"`                                     // 总⾦额 精度为⼩数点后2位
	WriteOffPrice float64 `json:"writeOffPrice" gorm:"type:decimal(12,4)"`                                  // 核销⾦额 精度为⼩数点后2位
	CouponPrice   float64 `json:"couponPrice" gorm:"type:decimal(12,4)"`                                    // 优惠券⾦额 精度为⼩数点后2位
	CashPrice     float64 `json:"cashPrice" gorm:"type:decimal(12,4)"`                                      // 现⾦⾦额 精度为⼩数点后2位
	Date          string  `json:"date" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`         // ⽇期:年-⽉
	Product       string  `json:"product" gorm:"type:varchar(128);not null;uniqueIndex:idx_all_column"`     // 产品
	AppName       string  `json:"appName" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`      // 应⽤名称
	UnitPrice     float64 `json:"unitPrice" gorm:"type:decimal(12,6);not null;uniqueIndex:idx_all_column"`  // 单价 精度为⼩数点后6位
	PriceUnit     string  `json:"priceUnit" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`    // 计费单位
	Count         float64 `json:"count" gorm:"type:decimal(24,6);not null;uniqueIndex:idx_all_column"`      // 调⽤量 精度为⼩数点后4位
	Unit          string  `json:"unit" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`         // 调⽤量单位
	Price         float64 `json:"price" gorm:"type:decimal(12,4);not null;uniqueIndex:idx_all_column"`      // ⾦额 精度为⼩数点后2位
	FunctionName  string  `json:"functionName" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"` // 功能
}

type XBillDailyStatement struct {
	gorm.Model
	AppName      string  `json:"appName" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`      // 应⽤名称
	FunctionName string  `json:"functionName" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"` // 功能
	UnitPrice    float64 `json:"unitPrice" gorm:"type:decimal(12,6);not null;uniqueIndex:idx_all_column"`  // 单价 精度为⼩数点后6位
	PriceUnit    string  `json:"priceUnit" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`    // 计费单位
	Price        float64 `json:"price" gorm:"type:decimal(12,4);not null;uniqueIndex:idx_all_column"`      // ⾦额 精度为⼩数点后2位
	Date         string  `json:"date" gorm:"type:varchar(128);not null;uniqueIndex:idx_all_column"`        // ⽇期:年-⽉-⽇
	Product      string  `json:"product" gorm:"type:varchar(128);not null;uniqueIndex:idx_all_column"`     // 产品
	Count        float64 `json:"count" gorm:"type:decimal(24,6);not null;uniqueIndex:idx_all_column"`      // 调⽤量 精度为⼩数点后4位
	Unit         string  `json:"unit" gorm:"type:varchar(64);not null;uniqueIndex:idx_all_column"`         // 调⽤量单位
}

生成的数据库表结构

image.png

生成的数据库DDL

CREATE TABLE `x_bill_daily_statements` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
  `deleted_at` datetime(3) DEFAULT NULL,
  `app_name` varchar(64) NOT NULL,
  `function_name` varchar(64) NOT NULL,
  `unit_price` decimal(12,6) NOT NULL,
  `price_unit` varchar(64) NOT NULL,
  `price` decimal(12,4) NOT NULL,
  `date` varchar(128) NOT NULL,
  `product` varchar(128) NOT NULL,
  `count` decimal(24,6) NOT NULL,
  `unit` varchar(64) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_all_column` (`app_name`,`function_name`,`unit_price`,`price_unit`,`price`,`date`,`product`,`count`,`unit`),
  KEY `idx_x_bill_daily_statements_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=361 DEFAULT CHARSET=utf8mb3;

CREATE TABLE `x_bill_monthly_statements` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
  `deleted_at` datetime(3) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL,
  `full_name` varchar(64) DEFAULT NULL,
  `total_price` decimal(12,4) DEFAULT NULL,
  `write_off_price` decimal(12,4) DEFAULT NULL,
  `coupon_price` decimal(12,4) DEFAULT NULL,
  `cash_price` decimal(12,4) DEFAULT NULL,
  `date` varchar(64) NOT NULL,
  `product` varchar(128) NOT NULL,
  `app_name` varchar(64) NOT NULL,
  `unit_price` decimal(12,6) NOT NULL,
  `price_unit` varchar(64) NOT NULL,
  `count` decimal(24,6) NOT NULL,
  `unit` varchar(64) NOT NULL,
  `price` decimal(12,4) NOT NULL,
  `function_name` varchar(64) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_all_column` (`date`,`product`,`app_name`,`unit_price`,`price_unit`,`count`,`unit`,`price`,`function_name`),
  KEY `idx_x_bill_monthly_statements_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb3;

GROM使用

初始化DB


// InitDB initialize DB
func InitDB() {
	c := conf.GetInspectionRDSConf()
	addr := c.Host + ":" + strconv.Itoa(c.Port)
	db, err := g.Create(addr, c.Database, c.User, c.Password,
		g.Timeout(1000*time.Millisecond))
	if err != nil {
		fmt.Println("db init err:", err)
	}
	DBInstance = db
}

Migrate 表结构


func MigrateXBillMonthlyStatement() 

	DBInstance.AutoMigrate(&XBillMonthlyStatement{})
	
}

func MigrateXBillDailyStatement() {

	DBInstance.AutoMigrate(&XBillDailyStatement{})

}

调用实现

	InitDB()
	MigrateXBillMonthlyStatement()
	MigrateXBillDailyStatement()

执行Migrate

image.png

image.png

image.png

GORM GEN使用

初始化DB


const XMysqlConfig = "x:x@(rm-x:3306)/x?charset=utf8mb4&parseTime=True&loc=Local"

func ConnectXDB() (conn *gorm.DB) {

	db, err := gorm.Open(mysql.Open(XMysqlConfig))
	if err != nil {
		panic(fmt.Errorf("cannot establish db connection: %w", err))
	}
	return db
}

执行生成GEN


func XGen() {

	g := gen.NewGenerator(gen.Config{
		OutPath: "model/query",
		Mode: gen.WithDefaultQuery | gen.WithQueryInterface,
	})

	g.UseDB(dal.ConnectXDB())

	XMonthlyStatement := g.GenerateModel("x_bill_monthly_statements")
	XBillDailyStatement := g.GenerateModel("x_bill_daily_statements")

	g.ApplyBasic(XBillMonthlyStatement)
	g.ApplyBasic(XBillDailyStatement)
	
	g.Execute()
}

生成过程

image.png

生成结果

image.png

注意事项

  • 务必确保,GEN生成 g.ApplyBasic 包括之前已生成的models对象
image.png