能连上goland不代表go代码能连通,因goland用jdbc驱动走tcp,而go程序用go-sql-driver/mysql驱动,二者认证方式、时区、ssl、dsn格式均不同,需分别配置。

能连上,不代表配置就对了;能点“Test Connection”成功,也不代表你的 Go 代码能用同一套参数连通。 GoLand 的数据库连接是独立于 Go 运行时的 JDBC 连接,它不复用 sql.Open 的 DSN 格式,也不走 Go 驱动,所以填错端口、漏掉时区、用错驱动版本,都可能让你在 IDE 里看着绿灯亮,但 db.Ping() 一直超时。
GoLand 填 MySQL 连接信息时必须核对的 4 个字段
IDE 右侧 Database 面板点击 + → MySQL 后,关键字段不是“Database name”或“User”,而是这四个:
-
Host:别写localhost—— 它在某些系统(尤其是 Docker 或远程部署)下会走 Unix socket,而 GoLand 默认走 TCP。统一填127.0.0.1更稳 -
Port:MySQL 默认是3306,但如果你改过配置(比如用宝塔或 Docker 映射到3307),这里必须同步;填错端口,telnet 127.0.0.1 3307会直接失败 -
User和Password:注意权限。GoLand 不需要 SUPER 权限,但至少要有SELECT(查库)、SHOW DATABASES(列库名)权限。用SHOW GRANTS FOR 'your_user'@'%';确认 -
Database(可选但建议填):留空时 GoLand 只能连上服务器,看不到具体表;填了之后右侧能展开表结构、右键执行 SQL,调试时省一半时间
“Test Connection” 成功但 Go 代码连不上?检查驱动和时区
GoLand 底层用的是 JDBC 驱动(如 mysql-connector-java),而你的 Go 程序用的是 github.com/go-sql-driver/mysql,两者行为不完全一致。常见断连原因:
- 驱动版本不匹配:GoLand 用的是较新 JDBC 驱动(比如 8.0.x),但 MySQL 5.7 服务端默认不支持
caching_sha2_password认证插件。Go 代码会卡在auth plugin 'caching_sha2_password' cannot be loaded。解决方法是在 DSN 后加&parseTime=true&loc=Local,并确保用户用mysql_native_password方式创建:ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pass'; - 时区没对齐:MySQL 服务端时区是
+08:00,但 GoLand 或 Go 代码没显式指定,parseTime=true会把时间解析成 UTC,导致查询结果时间偏移。DSN 中必须加&loc=Asia%2FShanghai(URL 编码后) - SSL 默认开启:新版 JDBC 驱动默认要求 SSL,而本地开发 MySQL 往往没配证书。GoLand 设置里要勾掉
Use SSL;Go 代码 DSN 则加&tls=false
Go 代码里复用 GoLand 的连接参数?别直接抄
GoLand 界面填的参数 ≠ Go 的 DSN。最常踩的坑是照抄 Host/Port/User/Password,却漏掉协议头、参数拼接和 URL 编码:
- Go 的 DSN 格式固定为:
user:password@tcp(host:port)/dbname?param1=value1¶m2=value2—— 注意@tcp(...)是强制语法,不能省 - 密码含特殊字符(如
@、/、:)必须 URL 编码,否则解析失败。用url.QueryEscape(password)处理 - GoLand 里写的
Database名,在 Go DSN 中是斜杠后的路径部分,不是独立字段;如果留空,DSN 就写成user:pass@tcp(127.0.0.1:3306)/(末尾斜杠不能少) - 推荐把 DSN 拆成变量组装,方便调试:
host := "127.0.0.1" port := "3306" user := "root" pass := url.QueryEscape("mypass@123") dbname := "test" dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true&loc=Asia%%2FShanghai&tls=false", user, pass, host, port, dbname)
真正麻烦的从来不是“怎么填”,而是填完之后——你不知道 GoLand 的连接池、JDBC 驱动、MySQL 服务端、Go 驱动这四层中间哪一层悄悄改了默认行为。每次连不上,先 telnet 127.0.0.1 3306 看端口通不通,再 db.Ping() 看 Go 层报什么错,最后比对 GoLand 的日志(Help → Show Log in Explorer)里 JDBC 报的异常。四层链路,断在哪一环,得一层层剥。











