Golang中如何从结构体插入数据库记录
Golang中如何从结构体插入数据库记录 你好,
我需要帮助,如何将一个与数据库表结构相似的Struct中的数据插入到表中。 我不想写冗长的插入脚本,比如: insert into <表名> values (?,?,?,?..) 然后从struct的每个字段中传递值。
我强烈推荐 GORM:https://gorm.io/
基本上,你就不再需要编写任何 SQL 语句了 😊 我已经在好几个项目中使用了它,对于我那些(规模相当小的)项目来说,它运行得很好。
更多关于Golang中如何从结构体插入数据库记录的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我不想像这样写冗长的插入脚本。
ORM 是一种选择。我不喜欢它,因为所有的“魔法”会带来限制,而且你必须学习一个由较小群体支持的“新语言”。获取纯 SQL 问题的帮助比获取 ORM 问题的帮助更容易。
话虽如此,我也不喜欢编写看起来重复的代码。所以我使用 sqlx 的 .StructScan。不过,插入操作仍然很乏味。
似乎有一个工具——sqlc——可以自动生成所有乏味的东西。纯 SQL。https://www.youtube.com/watch?v=prh0hTyI1sU
在Golang中,可以使用结构体标签和反射来简化数据库插入操作。以下是使用database/sql包和结构体标签的示例:
package main
import (
"database/sql"
"fmt"
"reflect"
"strings"
_ "github.com/go-sql-driver/mysql"
)
// 定义结构体标签
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Email string `db:"email"`
Age int `db:"age"`
Created string `db:"created_at"`
}
// 插入记录的通用函数
func InsertRecord(db *sql.DB, table string, data interface{}) (sql.Result, error) {
v := reflect.ValueOf(data).Elem()
t := v.Type()
var columns []string
var placeholders []string
var values []interface{}
for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
dbTag := field.Tag.Get("db")
if dbTag != "" && dbTag != "id" && !strings.Contains(dbTag, "created_at") {
columns = append(columns, dbTag)
placeholders = append(placeholders, "?")
values = append(values, v.Field(i).Interface())
}
}
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
table,
strings.Join(columns, ", "),
strings.Join(placeholders, ", "))
return db.Exec(query, values...)
}
func main() {
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
panic(err)
}
defer db.Close()
user := &User{
Name: "张三",
Email: "zhangsan@example.com",
Age: 25,
Created: "2023-10-01",
}
result, err := InsertRecord(db, "users", user)
if err != nil {
panic(err)
}
id, _ := result.LastInsertId()
fmt.Printf("插入成功,ID: %d\n", id)
}
对于更复杂的场景,可以使用ORM库如GORM:
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"time"
)
type Product struct {
gorm.Model
Code string
Price uint
}
func main() {
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
// 自动迁移
db.AutoMigrate(&Product{})
// 插入记录
product := Product{Code: "D42", Price: 100}
result := db.Create(&product)
if result.Error != nil {
panic(result.Error)
}
fmt.Printf("插入成功,ID: %d\n", product.ID)
}
使用sqlx库的示例:
package main
import (
"github.com/jmoiron/sqlx"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Email string `db:"email"`
}
func main() {
db, err := sqlx.Connect("mysql", "user:password@/dbname")
if err != nil {
panic(err)
}
defer db.Close()
user := User{
Name: "李四",
Email: "lisi@example.com",
}
query := `INSERT INTO users (name, email) VALUES (:name, :email)`
result, err := db.NamedExec(query, user)
if err != nil {
panic(err)
}
id, _ := result.LastInsertId()
fmt.Printf("插入成功,ID: %d\n", id)
}
这些方法都能避免手动编写冗长的插入语句,通过结构体自动生成SQL并绑定参数。

