Ruby 连接 Mysql – MySql2
在 Ruby 中,Mysql2 是一个高效、现代的 Ruby 库,用于连接和操作 MySQL 数据库。相比 DBI,Mysql2 更轻量、性能更高,且与 Rails 等框架集成良好。以下是对 Ruby 使用 Mysql2 连接 MySQL 数据库的中文讲解,涵盖安装、连接、基本操作(增删改查)、事务处理及注意事项,力求简洁清晰。
1. Mysql2 简介
Mysql2 是一个 Ruby 的 MySQL 客户端库,直接与 MySQL C API 交互,提供快速、可靠的数据库访问。它是 Rails 默认的 MySQL 适配器,广泛用于 Web 开发。
优点:
- 高性能:基于 libmysqlclient,速度快。
- 支持现代 MySQL 特性:如异步查询、流式结果。
- 易于集成:与 ActiveRecord 等框架无缝配合。
2. 安装 Mysql2
先决条件
- 安装 MySQL 服务器并运行。
- 安装 MySQL 开发库(用于编译 Mysql2):
- Ubuntu:
bash sudo apt-get install mysql-client libmysqlclient-dev
- CentOS:
bash yum install mysql-devel
- macOS:
bash brew install mysql
安装 Mysql2 gem
使用 RubyGems 安装:
gem install mysql2
验证安装:
require 'mysql2'
puts Mysql2::VERSION # 输出:0.5.4(示例版本)
说明:确保 Ruby 和 MySQL 版本兼容,安装前检查 libmysqlclient
路径。
3. 连接 MySQL 数据库
使用 Mysql2::Client.new
创建连接。
基本语法
require 'mysql2'
client = Mysql2::Client.new(
host: "localhost",
username: "testuser",
password: "test123",
database: "TESTDB"
)
示例:连接并测试
假设数据库 TESTDB
已存在,用户为 testuser
,密码为 test123
。
require 'mysql2'
begin
client = Mysql2::Client.new(
host: "localhost",
username: "testuser",
password: "test123",
database: "TESTDB"
)
result = client.query("SELECT VERSION()")
puts "MySQL 版本: #{result.first['VERSION()']}"
rescue Mysql2::Error => e
puts "错误: #{e.message}"
ensure
client.close if client
end
输出(示例):
MySQL 版本: 8.0.27
说明:
- 连接参数:
host
,username
,password
,database
是必需的。 - 可选参数:
port
(默认 3306)、encoding
(默认 UTF-8)、ssl
等。 - 使用
rescue
捕获Mysql2::Error
,ensure
确保连接关闭。
4. 基本操作(CRUD)
假设 EMPLOYEE
表结构:FIRST_NAME
, LAST_NAME
, AGE
, SEX
, INCOME
。
插入(Create)
client.query("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Alice', 'Smith', 30, 'F', 3000)")
puts "记录已插入,影响行数: #{client.affected_rows}"
参数绑定(防止 SQL 注入):
client.prepare("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES (?, ?, ?, ?, ?)")
.execute('Bob', 'Jones', 25, 'M', 2500)
puts "记录已插入"
查询(Read)
- 查询单行:
result = client.query("SELECT * FROM EMPLOYEE WHERE FIRST_NAME = 'Alice'")
result.each do |row|
puts "姓名: #{row['FIRST_NAME']} #{row['LAST_NAME']}, 收入: #{row['INCOME']}"
end
输出(示例):
姓名: Alice Smith, 收入: 3000
- 查询多行(流式处理):
result = client.query("SELECT * FROM EMPLOYEE WHERE INCOME > 2000", stream: true)
result.each do |row|
puts "姓名: #{row['FIRST_NAME']} #{row['LAST_NAME']}, 收入: #{row['INCOME']}"
end
说明:stream: true
适合处理大结果集,减少内存占用。
更新(Update)
client.query("UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = 'M'")
puts "记录已更新,影响行数: #{client.affected_rows}"
删除(Delete)
client.query("DELETE FROM EMPLOYEE WHERE AGE > 30")
puts "记录已删除,影响行数: #{client.affected_rows}"
5. 事务处理
Mysql2 支持事务操作,确保数据一致性。
client.query("START TRANSACTION")
begin
client.query("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Zara', 'Ali', 20, 'F', 1500)")
client.query("UPDATE EMPLOYEE SET INCOME = INCOME + 100 WHERE FIRST_NAME = 'Zara'")
client.query("COMMIT")
rescue Mysql2::Error => e
puts "错误: #{e.message}"
client.query("ROLLBACK")
end
说明:
- 使用
START TRANSACTION
,COMMIT
,ROLLBACK
手动管理事务。 - Mysql2 没有内置
transaction
块,需手动处理。
6. 错误处理
捕获 Mysql2::Error
处理数据库错误:
begin
client = Mysql2::Client.new(
host: "localhost",
username: "testuser",
password: "wrongpass",
database: "TESTDB"
)
rescue Mysql2::Error => e
puts "错误: #{e.message} (代码: #{e.errno})"
end
输出(示例):
错误: Access denied for user 'testuser'@'localhost' (using password: YES) (代码: 1045)
7. 高级功能
- 异步查询:
client.query("SELECT * FROM EMPLOYEE", async: true)
# 异步处理其他任务
result = client.async_result
result.each { |row| puts row['FIRST_NAME'] }
- 结果处理选项:
as: :hash
(默认,返回哈希)。as: :array
(返回数组)。
result = client.query("SELECT FIRST_NAME, AGE FROM EMPLOYEE", as: :array)
result.each { |row| puts "姓名: #{row[0]}, 年龄: #{row[1]}" }
- 连接池(Rails 中常见):
client = Mysql2::Client.new(
host: "localhost",
username: "testuser",
password: "test123",
database: "TESTDB",
pool: 5 # 最大连接数
)
8. 注意事项
- 资源管理:始终关闭连接(
client.close
),或使用连接池管理。 - SQL 注入:使用
prepare
和execute
参数绑定,防止注入。
# 不安全
client.query("SELECT * FROM EMPLOYEE WHERE FIRST_NAME = '#{name}'")
# 安全
stmt = client.prepare("SELECT * FROM EMPLOYEE WHERE FIRST_NAME = ?")
stmt.execute(name)
- 编码:确保数据库和 Ruby 编码一致(如 UTF-8)。
client = Mysql2::Client.new(..., encoding: 'utf8mb4')
- 性能:大结果集使用
stream: true
或分页查询。 - 现代替代:Rails 项目中,Mysql2 通常与 ActiveRecord 结合,简化操作。
- 错误调试:检查
e.errno
和e.message
获取详细错误信息。
9. 综合示例
require 'mysql2'
module EmployeeManager
def self.list_high_earners(host, user, pass, db, min_income)
client = Mysql2::Client.new(
host: host,
username: user,
password: pass,
database: db
)
stmt = client.prepare("SELECT FIRST_NAME, LAST_NAME, INCOME FROM EMPLOYEE WHERE INCOME > ?")
result = stmt.execute(min_income)
result.map { |row| "#{row['FIRST_NAME']} #{row['LAST_NAME']}: #{row['INCOME']}" }
rescue Mysql2::Error => e
["错误: #{e.message}"]
ensure
client.close if client
end
end
puts EmployeeManager.list_high_earners("localhost", "testuser", "test123", "TESTDB", 2000)
# 输出(示例):
# Alice Smith: 3000
# Bob Jones: 2500
10. 总结
Mysql2 是 Ruby 中连接 MySQL 数据库的高效工具,通过 Mysql2::Client
提供快速连接和操作。支持 CRUD、事务、异步查询和流式处理,结合参数绑定确保安全性。相比 DBI,Mysql2 更现代、性能更高,尤其适合 Rails 应用。注意资源管理、编码一致性和 SQL 注入防护,以确保代码健壮。
如果你需要更深入的示例(如复杂查询、连接池配置)或有其他问题,请告诉我!