1.安装和导入
首先需要安装数据库驱动:
shell
go get -u github.com/go-sql-driver/mysql
go get -u github.com/lib/pq
导入需要的包
go
import (
"databse/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
2.连接数据库
go
func main(){
db,err :=sql.Open("msyql","username:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
lgo.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatel(err)
}
fmt.Println("数据库连接成功")
}
3.基础CRUD操作
1. 创建表
go
func createTable(db *sql.DB)error{
query := `
CREATE TABLE IF NOT EXSTS users(
id INT AUTO_INCREAMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCAHR(100) UNIQUE NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`_,err db.Exec(query)
return err
}
2. 插入数据
go
func insertUser(db *sql.DB, name, email string, age int) (int64, error) {
result, err := db.Exec(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)",
name, email, age,
)
if err != nil {
return 0, err
}
id, err := result.LastInsertId()
return id, err
}
3. 查询数据
go
type User struct {
ID int
Name string
Email string
Age int
CreatedAt string
}
// 查询单个用户
func getUser(db *sql.DB, id int) (*User, error) {
var user User
err := db.QueryRow(
"SELECT id, name, email, age, created_at FROM users WHERE id = ?",
id,
).Scan(&user.ID, &user.Name, &user.Email, &user.Age, &user.CreatedAt)
if err != nil {
return nil, err
}
return &user, nil
}
// 查询多个用户
func getUsers(db *sql.DB) ([]User, error) {
rows, err := db.Query("SELECT id, name, email, age, created_at FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.Age, &user.CreatedAt)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
4. 更新数据
go
func updateUser(db *sql.DB, id int, name, email string, age int) error {
_, err := db.Exec(
"UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?",
name, email, age, id,
)
return err
}
5.删除数据
go
func deleteUser(db *sql.DB, id int) error {
_, err := db.Exec("DELETE FROM users WHERE id = ?", id)
return err
}
4.预处理语句
go
func batchInsertUsers(db *sql.DB,users []User)error{
stmt,err :=db.Prepare("INSERT INTO users (name, email, age) VALUES (?, ?, ?)")
if err != nil {
return err
}
defer stmt.Close()
for _, user := range users {
_, err := stmt.Exec(user.Name, user.Email, user.Age)
if err != nil {
return err
}
}
return nil
}
5.事务处理
go
func transferMoney(db *sql.DB, fromID, toID int, amount float64) error {
tx, err := db.Begin()
if err != nil {
return err
}
// 执行转账操作
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, fromID)
if err != nil {
tx.Rollback()
return err
}
_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, toID)
if err != nil {
tx.Rollback()
return err
}
return tx.Commit()
}
6.连接吃配置
go
func initDB() *sql.DB {
db, err := sql.Open("mysql", "user:pass@tcp(localhost:3306)/dbname")
if err != nil {
log.Fatal(err)
}
// 配置连接池
db.SetMaxOpenConns(25) // 最大打开连接数
db.SetMaxIdleConns(10) // 最大空闲连接数
db.SetConnMaxLifetime(5 * time.Minute) // 连接最大生存时间
return db
}
总结
-
sql.Open() 只创建连接对象,不实际连接数据库
-
db.Ping() 用于验证连接
-
db.Exec() 用于执行不返回行的操作
-
db.Query() 用于查询多行数据
-
db.QueryRow() 用于查询单行数据
-
使用 预处理语句 提高性能和安全性
-
记得 defer rows.Close() 和 defer stmt.Close()
-
使用 事务 保证数据一致性
-
合理配置 连接池 参数