引言
本文将详细介绍如何使用Go语言结合SQLx库将CSV数据保存到数据库。我们将通过易于理解的代码示例,为从初学者到高级开发者提供实用的技术解析。
读取CSV数据并保存到数据库
首先,我们将探讨如何读取CSV文件并将数据保存到数据库的方法。
package main
import (
"encoding/csv"
"log"
"os"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
)
type Person struct {
Name string `db:"name"`
Age int `db:"age"`
}
func main() {
db, err := sqlx.Connect("sqlite3", "example.db")
if err != nil {
log.Fatalln(err)
}
file, err := os.Open("people.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := csv.NewReader(file)
var people []Person
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
var age int
age, err = strconv.Atoi(record[1])
if err != nil {
panic(err)
}
person := Person{
Name: record[0],
Age: age,
}
people = append(people, person)
}
for _, person := range people {
_, err = db.NamedExec(`INSERT INTO people (name, age) VALUES (:name, :age)`, person)
if err != nil {
panic(err)
}
}
}
此代码段展示了如何读取CSV文件并将数据保存到SQLite数据库。
数据库批量插入
接下来,我们将探讨如何高效地将大量数据通过批量处理保存到数据库。
package main
import (
"encoding/csv"
"log"
"os"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"database/sql"
"fmt"
)
type Person struct {
Name string `db:"name"`
Age int `db:"age"`
}
func batchInsertPeople(db *sqlx.DB, people []Person) error {
transaction, err := db.Begin()
if err != nil {
return err
}
stmt, err := transaction.Prepare("INSERT INTO people (name, age) VALUES (?, ?)")
if err != nil {
_ = transaction.Rollback()
return err
}
defer stmt.Close()
for _, person := range people {
_, err := stmt.Exec(person.Name, person.Age)
if err != nil {
_ = transaction.Rollback()
return err
}
}
return transaction.Commit()
}
func main() {
db, err := sqlx.Connect("sqlite3", "example.db")
if err != nil {
log.Fatalln(err)
}
file, err := os.Open("people.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := csv.NewReader(file)
var people []Person
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
var age int
age, err = strconv.Atoi(record[1])
if err != nil {
panic(err)
}
people = append(people, Person{
Name: record[0],
Age: age,
})
}
if err := batchInsertPeople(db, people); err != nil {
log.Fatalln(err)
}
fmt.Println("Data batch inserted successfully")
}package main
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"log"
)
func updatePerson(db *sqlx.DB, name string, newAge int) error {
_, err := db.Exec("UPDATE people SET age = ? WHERE name = ?", newAge, name)
return err
}
func main() {
db, err := sqlx.Connect("sqlite3", "example.db")
if err != nil {
log.Fatalln(err)
}
// 更新特定名字的人的年龄
err = updatePerson(db, "张三", 35)
if err != nil {
log.Fatalf("更新失败: %v", err)
}
log.Println("数据更新成功")
}
数据更新和错误处理
本节将介绍如何更新数据库中的现有数据以及如何实现错误处理。
package main
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"log"
)
func updatePerson(db *sqlx.DB, name string, newAge int) error {
_, err := db.Exec("UPDATE people SET age = ? WHERE name = ?", newAge, name)
return err
}
func main() {
db, err := sqlx.Connect("sqlite3", "example.db")
if err != nil {
log.Fatalln(err)
}
// 更新特定名字的人的年龄
err = updatePerson(db, "张三", 35)
if err != nil {
log.Fatalf("更新失败: %v", err)
}
log.Println("数据更新成功")
}
使用事务
为了确保数据操作的安全性,我们将讲解如何使用事务。
package main
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"log"
)
func executeTransaction(db *sqlx.DB) error {
// 开始事务
tx, err := db.Begin()
if err != nil {
return err
}
// 执行多个数据操作
_, err = tx.Exec("UPDATE people SET age = ? WHERE name = ?", 40, "张三")
if err != nil {
tx.Rollback() // 回滚事务
return err
}
_, err = tx.Exec("INSERT INTO people (name, age) VALUES (?, ?)", "李四", 30)
if err != nil {
tx.Rollback() // 回滚事务
return err
}
// 提交事务
return tx.Commit()
}
func main() {
db, err := sqlx.Connect("sqlite3", "example.db")
if err != nil {
log.Fatalln(err)
}
// 执行事务
err = executeTransaction(db)
if err != nil {
log.Fatalf("事务执行失败: %v", err)
}
log.Println("事务执行成功")
}
总结
本文从基础到高级应用全面介绍了使用Go语言和SQLx保存CSV数据到数据库的方法。运用这些技巧可以使数据库操作更加高效和安全。