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)
}