Golang连接MySQL数据库的方法与实践

Golang连接MySQL数据库的方法与实践 我创建了 MySQL DB 并尝试从我的 go 应用程序连接到它。

以下是代码:

package users_db

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

var (
	Client *sql.DB
)

func init() {
	dataSourceName := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf-8",
		"root",
		"root",
		"127.0.0.1",
		"users_db",
	)
	var err error

	Client, err = sql.Open("mysql", dataSourceName)
	if err != nil {
		panic(err)
	}

	if err = Client.Ping(); err != nil {
		panic(err)
	}

	log.Println("Database successfully configured")
}

当我运行 go run main.go 时,终端打印出以下信息: panic: Error 1045: Access denied for user ‘root’@‘localhost’ (using password: YES)

goroutine 1 [running]: github.com/arammikayelyan/bookstore_users-api/datasources/mysql/users_db.init.0() /home/aram/go/src/github.com/arammikayelyan/bookstore_users-api/datasources/mysql/users_db/users_db.go:30 +0x1d7 exit status 2

如何连接到需要密码的数据库?


更多关于Golang连接MySQL数据库的方法与实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

请确保用户对模式拥有权限,请不要使用 root 作为登录账户。这里有一个很好的操作指南:https://dev.mysql.com/doc/workbench/en/wb-mysql-connections-navigator-management-users-and-privileges.html

更多关于Golang连接MySQL数据库的方法与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


根据错误信息,用户 ‘root’@‘localhost’ 的访问被拒绝。这通常是由于密码不匹配或权限问题导致的。以下是几种解决方案:

1. 验证数据库连接参数

确保连接字符串中的用户名和密码与MySQL数据库中的配置一致:

func init() {
    // 检查MySQL root用户的实际密码
    dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=true",
        "root",           // 用户名
        "your_password",  // 确保这是正确的密码
        "127.0.0.1",      // 或 "localhost"
        3306,             // MySQL默认端口
        "users_db",       // 数据库名
    )
    
    // 或者使用环境变量更安全
    // dataSourceName := fmt.Sprintf("%s:%s@tcp(%s)/%s",
    //     os.Getenv("DB_USER"),
    //     os.Getenv("DB_PASSWORD"),
    //     os.Getenv("DB_HOST"),
    //     os.Getenv("DB_NAME"),
    // )
    
    var err error
    Client, err = sql.Open("mysql", dataSourceName)
    if err != nil {
        log.Fatal("Failed to open database:", err)
    }
    
    // 设置连接池参数
    Client.SetMaxOpenConns(25)
    Client.SetMaxIdleConns(25)
    Client.SetConnMaxLifetime(5 * time.Minute)
    
    if err = Client.Ping(); err != nil {
        log.Fatal("Failed to ping database:", err)
    }
    
    log.Println("Database successfully configured")
}

2. 检查MySQL用户权限

登录MySQL命令行,验证root用户的权限和密码:

-- 登录MySQL
mysql -u root -p

-- 查看用户权限
SELECT user, host FROM mysql.user;

-- 修改root密码(如果需要)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

-- 或者创建新用户
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON users_db.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;

3. 使用配置文件管理连接信息

创建配置文件 config.yaml

database:
  host: "127.0.0.1"
  port: 3306
  user: "root"
  password: "your_password"
  name: "users_db"

然后在Go代码中读取配置:

package users_db

import (
    "database/sql"
    "fmt"
    "log"
    "os"
    "time"
    
    _ "github.com/go-sql-driver/mysql"
    "gopkg.in/yaml.v2"
)

var Client *sql.DB

type Config struct {
    Database struct {
        Host     string `yaml:"host"`
        Port     int    `yaml:"port"`
        User     string `yaml:"user"`
        Password string `yaml:"password"`
        Name     string `yaml:"name"`
    } `yaml:"database"`
}

func InitDB() {
    // 读取配置文件
    configFile, err := os.Open("config.yaml")
    if err != nil {
        log.Fatal("Failed to open config file:", err)
    }
    defer configFile.Close()
    
    var config Config
    decoder := yaml.NewDecoder(configFile)
    if err := decoder.Decode(&config); err != nil {
        log.Fatal("Failed to decode config:", err)
    }
    
    // 构建连接字符串
    dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local",
        config.Database.User,
        config.Database.Password,
        config.Database.Host,
        config.Database.Port,
        config.Database.Name,
    )
    
    Client, err = sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal("Failed to open database:", err)
    }
    
    // 测试连接
    if err := Client.Ping(); err != nil {
        log.Fatal("Failed to ping database:", err)
    }
    
    log.Println("Database connection established")
}

4. 使用连接参数调试

添加更多连接参数进行调试:

func init() {
    // 添加更多参数
    dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&timeout=30s&readTimeout=30s&writeTimeout=30s",
        "root",
        "root", // 确认密码是否正确
        "127.0.0.1",
        3306,
        "users_db",
    )
    
    Client, err := sql.Open("mysql", dataSourceName)
    if err != nil {
        log.Fatalf("Error opening database: %v", err)
    }
    
    // 尝试多次ping
    for i := 0; i < 5; i++ {
        if err := Client.Ping(); err != nil {
            log.Printf("Attempt %d failed: %v", i+1, err)
            time.Sleep(2 * time.Second)
        } else {
            log.Println("Database connected successfully")
            return
        }
    }
    log.Fatal("Failed to connect after multiple attempts")
}

5. 验证MySQL服务状态

确保MySQL服务正在运行:

# Linux/Mac
sudo systemctl status mysql
# 或
sudo service mysql status

# Windows
net start | findstr MySQL

# 检查端口
netstat -an | grep 3306

错误 Error 1045 明确表示认证失败。需要验证:

  1. MySQL root用户的正确密码
  2. 用户是否有从localhost连接的权限
  3. MySQL服务是否允许TCP连接(检查bind-address配置)
回到顶部