Files
interview/questions/13-Golang语言/数据库操作.md
yasinshaw 7f3ab362b3 feat: rename Golang files to Chinese and supplement root files
Changes:
- Renamed all 10 Golang files from English to Chinese names
- Created 00-项目概述/项目概述.md with comprehensive project overview
- Created 08-算法与数据结构/算法与数据结构学习指南.md with detailed learning guide
- Created 12-面试技巧/面试准备进度.md with progress tracking
- Added .obsidian configuration for better markdown editing
- Updated Claude.MD with Chinese filename rule

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:33:32 +08:00

226 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Golang 数据库操作
## 问题
1. Go 如何连接 MySQL 数据库?
2. database/sql 的使用方法是什么?
3. 如何使用 ORM如 GORM
4. 如何处理数据库事务?
5. 如何处理 SQL 注入?
---
## 标准答案
### 1. 连接 MySQL
#### **使用 database/sql**
```go
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 连接数据库
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?parseTime=true"
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close()
// 测试连接
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Connected!")
}
```
---
### 2. database/sql 使用
#### **查询**
```go
func queryUser(db *sql.DB, id int) (string, error) {
var name string
err := db.QueryRow("SELECT name FROM users WHERE id = ?", id).Scan(&name)
if err != nil {
return "", err
}
return name, nil
}
```
---
#### **查询多行**
```go
func queryUsers(db *sql.DB) ([]string, error) {
rows, err := db.Query("SELECT name FROM users WHERE age > ?", 18)
if err != nil {
return nil, err
}
defer rows.Close()
var names []string
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
names = append(names, name)
}
return names, nil
}
```
---
### 3. 使用 GORM
#### **安装**
```bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
```
---
#### **基本使用**
```go
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"column:name"`
Age int `gorm:"column:age"`
}
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)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&User{})
// 创建
user := User{Name: "Alice", Age: 25}
db.Create(&user)
// 查询
var users []User
db.Where("age > ?", 18).Find(&users)
}
```
---
### 4. 事务处理
#### **database/sql 事务**
```go
func transfer(db *sql.DB, from, to int, amount int) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
// 1. 扣款
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, from)
if err != nil {
return err
}
// 2. 存款
_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, to)
if err != nil {
return err
}
return nil
}
```
---
#### **GORM 事务**
```go
func transfer(db *gorm.DB, from, to int, amount int) error {
return db.Transaction(func(tx *gorm.DB) error {
// 扣款
if err := tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, from).Error; err != nil {
return err
}
// 存款
if err := tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, to).Error; err != nil {
return err
}
return nil
})
}
```
---
### 5. SQL 注入防护
#### ✅ 使用参数化查询
```go
// ✅ 安全(参数化查询)
db.Query("SELECT * FROM users WHERE id = ?", id)
// ❌ 不安全(字符串拼接)
db.Query(fmt.Sprintf("SELECT * FROM users WHERE id = %d", id))
```
---
### 6. 阿里 P7 加分项
**深度理解**
- 理解 database/sql 的连接池机制
- 理解 GORM 的底层实现(基于 database/sql
- 理解数据库事务的隔离级别
**实战经验**
- 有处理数据库连接池的经验
- 有优化数据库查询的经验(索引、批量操作)
- 有处理分布式事务的经验
**性能优化**
- 理解如何优化数据库查询(预编译语句、批量操作)
- 理解如何优化连接池配置
- 理解如何处理慢查询