gorm批量插入解決方案

我有一個朋友, 最近用gorm發現官方不支持批量插入, 看官方issue 2014年就有人提過這個問題了, 不過現在還不支持
在這裏插入圖片描述
但是問題不大, 官方留出來一個執行原生SQL(db.Exec)的方法來解決這個問題, 而且官方現在在開發v2版本, 在v2版本中就會支持這個功能了
在這裏插入圖片描述

但是生活還得繼續, bug還是得繼續寫, 本來想在網上找一個公用方法來維持一下生活, 結果竟然沒找見!
此處加震驚
都是指定單個結構體去插入的
在這裏插入圖片描述
這當然不行了, 寫代碼的意義不就是爲了減輕重複的工作嘛, 既然這樣, 就只能自己動手豐衣足食了
在這裏插入圖片描述

下面爲生成語句的方法


// GetBranchInsertSql 獲取批量添加數據sql語句
func GetBranchInsertSql(objs []interface{}, tableName string) string {
	if len(objs) == 0 {
		return ""
	}
	filedName := ""
	var valueTypeList []string
	filedNum := reflect.TypeOf(objs[0]).NumField()
	filedT := reflect.TypeOf(objs[0])
	for a := 0; a < filedNum; a++ {
		name := GetColumnName(filedT.Field(a).Tag.Get("gorm"))
		// 添加字段名
		if a == filedNum-1 {
			filedName += fmt.Sprintf("`%s`", name)
		} else {
			filedName += fmt.Sprintf("`%s`,", name)
		}
		// 獲取字段類型
		if filedT.Field(a).Type.Name() == "string" {
			valueTypeList = append(valueTypeList, "string")
		} else if strings.Index(filedT.Field(a).Type.Name(), "uint") != -1 {
			valueTypeList = append(valueTypeList, "uint")
		} else if strings.Index(filedT.Field(a).Type.Name(), "int") != -1 {
			valueTypeList = append(valueTypeList, "int")
		}
	}
	var valueList []string
	for _, obj := range objs {
		objV := reflect.ValueOf(obj)
		v := "("
		for index, i := range valueTypeList {
			if index == filedNum-1 {
				v += GetFormatFeild(objV, index, i, "")
			} else {
				v += GetFormatFeild(objV, index, i, ",")
			}
		}
		v += ")"
		valueList = append(valueList, v)
	}
	insertSql := fmt.Sprintf("insert into `%s` (%s) values %s", tableName, filedName, strings.Join(valueList, ",")+";")
	return insertSql
}

// GetFormatFeild 獲取字段類型值轉爲字符串
func GetFormatFeild(objV reflect.Value, index int, t string, sep string) string {
	v := ""
	if t == "string" {
		v += fmt.Sprintf("'%s'%s", objV.Field(index).String(), sep)
	} else if t == "uint" {
		v += fmt.Sprintf("%d%s", objV.Field(index).Uint(), sep)
	} else if t == "int" {
		v += fmt.Sprintf("%d%s", objV.Field(index).Int(), sep)
	}
	return v

}
// GetColumnName 獲取字段名
func GetColumnName(jsonName string) string {
	for _, name := range strings.Split(jsonName, ";") {
		if strings.Index(name, "column") == -1 {
			continue
		}
		return strings.Replace(name, "column:", "", 1)
	}
	return ""
}

最後會返回批量插入的sql語句, 這樣一來就舒服多了
因爲我的朋友 現在類型主要用到了string, int和uint, 如果有其他類型需要加的話在 獲取字段類型和GetFormatFeild裏面加就行了

如果各位大佬有更好的解決方案希望可以拿出來分享學習一下

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章