1. gorm主页

2. 代码

import (
  "gorm.io/gorm"
  "gorm.io/driver/sqlite"
)

/* 存储结构 - 表结构 */
type Product struct {
  gorm.Model
  Code  string
  Price uint
}

type RecorderLogger struct {
	logger.Interface
	Statements []string // 记录多条SQL
}

/* 重写Trace, 最终会回调此处 */
func (r *RecorderLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
	sql, _ := fc()
	r.Statements = append(r.Statements, sql)
}

/* 使用 */
func ExecAutoMigrate(tx *gorm.DB, dat []Product) {
	recorder := RecorderLogger{Interface: logger.Default.LogMode(logger.Info), Statements: make([]string, 0, 1024)} 
    
     /* 创建会话,通过调用此会话会回调Trace */
	session := tx.Session(&gorm.Session{
		Logger: &recorder,
	})

	for i := range dat {
		session.AutoMigrate(dat[i])
	}
	for i := range recorder.Statements {
		fmt.Println("执行的语句: ", recorder.Statements[i])
	}
}

func main() {
    var dat = make([]Product, 10, 10)
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    ExecAutoMigrate(db, dat)
    var realDB *sql.DB
    realDB, err = db.DB()
    realDB.Close()
}

3. 另外, map转struct结构

/* 转化成结构体类型, 将Map解析之后字段加入到结构体内, 但此结构体没有名称 */
func madeModel(dat map[string]interface{}) reflect.Type {
	var fields = make([]reflect.StructField, 0 , 100)
	for name, value := range dat {
		if !unicode.IsUpper([]rune(name)[0]) {
			name = string(unicode.ToUpper([]rune(name)[0])) + name[1:]
		}
		fields = append(fields, reflect.StructField{
			Name: name,
			Type: reflect.TypeOf(value),
		})
	}
	return reflect.StructOf(fields)
}

/*  实例化一个结构体对象, 返回改对象的Interface */
func toStructInterface(model reflect.Type) interface{} {
	return reflect.New(model).Elem().Interface()
}

func main() {
    var tmap = map[string]interface{} {
        "n" : "w",
        "int32" : int32(1)
    }
    var interf = toStructInterface(madeModel(tmap)) // 结构体对象
    //Gorm 使用
    //db.AutoMigrate(interf) 
}