mysql Ruby连接数据库用什么_mysql Ruby类库说明

来源:这里教程网 时间:2026-02-28 20:35:48 作者:

现在 Ruby 连接 MySQL 的主流、推荐、维护活跃的类库是

mysql2
,不是过时的
mysql
(已多年未更新)或历史更久的
dbi + dbd-mysql
组合。

为什么必须用
mysql2
而不是
mysql

mysql
gem 依赖旧版 C API,不支持 MySQL 5.7+ 的认证协议(如
caching_sha2_password
),在 macOS 13+/Ubuntu 22.04+ 或新版 MySQL Server 上直接报错:
Access denied for user
Client does not support authentication protocol
。而
mysql2
持续更新,原生支持现代认证、SSL、prepared statement、异步查询等特性,且是 Rails 默认适配器。

mysql2
是纯 C 扩展,性能比纯 Ruby 实现高数倍
Rails 6+、Hanami、Sinatra 生态默认绑定
mysql2
,社区文档和错误排查资源丰富
mysql
gem 最后发布是 2013 年(v2.9.1),早已停止维护

mysql2
安装常见失败原因与解法

安装

gem install mysql2
报错,90% 是因为找不到 MySQL 客户端开发库(
libmysqlclient
)或路径不对,不是 Ruby 本身问题。

Ubuntu/Debian:缺
libmysqlclient-dev
→ 运行
sudo apt-get install libmysqlclient-dev
CentOS/RHEL:缺
mysql-devel
→ 运行
sudo yum install mysql-devel
(或
dnf install mysql-devel
macOS(Homebrew):MySQL 已安装但
mysql_config
不在 PATH → 先确认
which mysql_config
,若为空则运行
brew install mysql-client
,再用
gem install mysql2 -- --with-mysql-config=$(brew --prefix mysql-client)/bin/mysql_config
Windows:默认会下载预编译二进制,但若本地装了 MySQL Connector/C,可用
gem install mysql2 -- --with-mysql-dir="C:/mysql-connector-c-6.1"

Mysql2::Client.new
必填参数与安全陷阱

最简连接能跑通,不代表生产可用。漏掉关键选项会导致乱码、超时中断、连接泄漏或认证失败。

require 'mysql2'
<p>client = Mysql2::Client.new(
host:     '127.0.0.1',
username: 'root',
password: 'your_pass',
database: 'myapp_development',
encoding: 'utf8mb4',     # ← 必须设!否则存 emoji 或中文可能变 ??
reconnect: true,        # ← 建议开启,避免连接空闲断开后 query 报 "MySQL server has gone away"
read_timeout: 10,
write_timeout: 10,
connect_timeout: 5
)</p>
encoding: 'utf8mb4'
是 MySQL 5.5.3+ 正确支持完整 Unicode 的编码,
utf8
在 MySQL 里其实是阉割版(最多 3 字节)
不设
reconnect: true
,长连接空闲超时(MySQL 默认
wait_timeout=28800
秒)后首次 query 会抛
Mysql2::Error: MySQL server has gone away
不要把密码硬编码在代码里,应通过环境变量(如
ENV['MYSQL_PASSWORD']
)或配置文件注入

查、插、改、删基础操作与防 SQL 注入

mysql2
支持两种执行方式:字符串拼接(危险)和参数化查询(安全)。永远优先用后者。

# ✅ 安全:参数化查询(自动转义)
result = client.query("SELECT * FROM users WHERE name = ? AND age > ?", "Alice", 18)
<h1>❌ 危险:字符串插值(易被注入)</h1><p>name = "Alice'; DROP TABLE users; --"
client.query("SELECT * FROM users WHERE name = '#{name}'") # ← 直接崩库</p><h1>插入示例(返回影响行数)</h1><p>client.query("INSERT INTO posts (title, body) VALUES (?, ?)", "Hello", "World")</p><h1>批量插入(效率更高)</h1><p>client.query("INSERT INTO logs (msg, level) VALUES (?, ?), (?, ?)", "start", "info", "end", "warn")</p>
query
方法只用于 SELECT;INSERT/UPDATE/DELETE 推荐也用
query
(它统一返回
Mysql2::Result
或影响行数),无需区分
想获取自增 ID?用
client.last_id
(刚执行 INSERT 后立即读)
事务用
client.query('START TRANSACTION')
+
client.query('COMMIT')
,但更建议用 ActiveRecord 或自己封装 begin/rescue/rollback

真正容易出问题的不是“连不上”,而是连上了却因编码、超时、认证方式、SQL 拼接等细节导致数据错乱或服务偶发崩溃。这些点没有报错提示,但上线后会静默毁数据。

相关推荐