Golang开发X功能包的实现方案求反馈
Golang开发X功能包的实现方案求反馈 你好,
我正在开发一个用于X的Go包。有人可以审查一下我的代码吗?
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(database-server:3306)/database-name")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var (
id int
name string
age int
)
rows, err := db.Query("SELECT id, name, age FROM users WHERE age > ?", 18)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&id, &name, &age)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
提前感谢。
更多关于Golang开发X功能包的实现方案求反馈的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
嘿 @tonnytg,
感谢你的回复。非常感谢你的支持。
更多关于Golang开发X功能包的实现方案求反馈的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
不要在Go文件中硬编码连接信息。 将连接参数放在文件中并读取该文件。 大多数程序都需要配置参数,因此您可以将连接字符串作为参数放入此类文件中。
这是一个典型的Go语言数据库查询实现,代码结构基本正确,但有几个可以改进的地方:
1. 连接池配置
建议显式配置连接池参数,避免使用默认值:
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)
2. 错误处理优化
rows.Err()应该在循环后检查,但你的代码已经正确实现了这一点。不过可以更明确地处理不同类型的错误:
if err := rows.Err(); err != nil {
log.Printf("Error iterating rows: %v", err)
return
}
3. 使用结构体映射
对于查询结果,使用结构体可以提高代码可读性:
type User struct {
ID int
Name string
Age int
}
func queryUsers(db *sql.DB, minAge int) ([]User, error) {
rows, err := db.Query("SELECT id, name, age FROM users WHERE age > ?", minAge)
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var u User
if err := rows.Scan(&u.ID, &u.Name, &u.Age); err != nil {
return nil, err
}
users = append(users, u)
}
if err := rows.Err(); err != nil {
return nil, err
}
return users, nil
}
4. 连接字符串提取
建议将数据库连接字符串提取为配置:
type Config struct {
DBUser string
DBPassword string
DBHost string
DBPort string
DBName string
}
func (c *Config) DSN() string {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true",
c.DBUser, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
}
5. 完整的改进示例
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
type Database struct {
*sql.DB
}
func NewDatabase(dsn string) (*Database, error) {
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, fmt.Errorf("failed to open database: %w", err)
}
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("failed to ping database: %w", err)
}
return &Database{db}, nil
}
func (db *Database) GetUsersByMinAge(minAge int) ([]User, error) {
const query = "SELECT id, name, age FROM users WHERE age > ?"
rows, err := db.Query(query, minAge)
if err != nil {
return nil, fmt.Errorf("query failed: %w", err)
}
defer rows.Close()
var users []User
for rows.Next() {
var u User
if err := rows.Scan(&u.ID, &u.Name, &u.Age); err != nil {
return nil, fmt.Errorf("scan failed: %w", err)
}
users = append(users, u)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("rows iteration error: %w", err)
}
return users, nil
}
func main() {
dsn := "user:password@tcp(database-server:3306)/database-name?parseTime=true"
db, err := NewDatabase(dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
users, err := db.GetUsersByMinAge(18)
if err != nil {
log.Fatal(err)
}
for _, user := range users {
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
}
主要改进点:
- 封装数据库操作到结构体方法中
- 添加连接池配置
- 使用结构体映射查询结果
- 更详细的错误包装
- 添加
parseTime=true参数支持时间类型

