Ruby 数据库访问 – DBI 教程
感谢你再次询问关于 Ruby DBI 的内容!由于你之前已经收到了一份关于 Ruby DBI 的详细中文讲解,我会提供一个更简洁的版本,聚焦于核心概念、关键操作和一些补充示例,避免重复冗长的内容。如果需要特定部分的深入讲解或新内容,请告诉我!以下是 Ruby DBI 数据库访问的简洁教程,涵盖安装、连接、CRUD 操作、事务及注意事项。
1. DBI 简介
Ruby DBI(Database Interface) 是一个跨数据库的接口模块,允许通过统一的 API 访问不同数据库(如 MySQL、PostgreSQL、SQLite 等)。它由 DBI 层(通用接口)和 DBD 层(数据库驱动)组成,适合需要数据库无关性的应用。
2. 安装 DBI
先决条件
- 确保目标数据库(如 MySQL)已安装并运行。
- 安装数据库开发库(如 MySQL 的
libmysqlclient-dev
)。
通过 RubyGems 安装
gem install dbi
gem install dbd-mysql # 以 MySQL 为例
注意:根据目标数据库安装对应的 DBD(如 dbd-pg
用于 PostgreSQL)。
3. 连接数据库
使用 DBI.connect
连接数据库,格式:
require 'dbi'
dbh = DBI.connect("DBI:数据库类型:数据库名:主机", "用户名", "密码")
示例:连接 MySQL
假设数据库为 TESTDB
,用户 testuser
,密码 test123
。
require 'dbi'
begin
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
puts "连接成功: #{dbh.select_one('SELECT VERSION()')[0]}"
rescue DBI::DatabaseError => e
puts "错误: #{e.errstr}"
ensure
dbh.disconnect if dbh
end
输出(示例):
连接成功: 8.0.27
说明:
- 使用块方式(
DBI.connect ... do |dbh|
)可自动关闭连接。 rescue
处理数据库错误,ensure
确保连接关闭。
4. 基本操作(CRUD)
假设 EMPLOYEE
表结构:FIRST_NAME
, LAST_NAME
, AGE
, SEX
, INCOME
。
插入(Create)
dbh.do("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Alice', 'Smith', 30, 'F', 3000)")
dbh.commit
puts "记录已插入"
参数绑定(更安全):
sth = dbh.prepare("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES (?, ?, ?, ?, ?)")
sth.execute('Bob', 'Jones', 25, 'M', 2500)
sth.finish
dbh.commit
查询(Read)
sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE INCOME > ?")
sth.execute(2000)
sth.fetch do |row|
printf "姓名: %s %s, 收入: %d\n", row[0], row[1], row[4]
end
sth.finish
输出(示例):
姓名: Alice Smith, 收入: 3000
姓名: Bob Jones, 收入: 2500
更新(Update)
dbh.do("UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = 'M'")
dbh.commit
puts "记录已更新"
删除(Delete)
sth = dbh.prepare("DELETE FROM EMPLOYEE WHERE AGE > ?")
sth.execute(30)
sth.finish
dbh.commit
puts "记录已删除"
5. 事务处理
事务确保操作的原子性。使用 transaction
方法简化提交/回滚:
dbh['AutoCommit'] = false
dbh.transaction do |dbh|
dbh.do("INSERT INTO EMPLOYEE (FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Zara', 'Ali', 20, 'F', 1500)")
dbh.do("UPDATE EMPLOYEE SET INCOME = INCOME + 100 WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true
说明:transaction
块成功则提交,失败则回滚。
6. 错误处理
捕获 DBI::DatabaseError
处理数据库错误:
begin
dbh = DBI.connect("DBI:Mysql:WRONGDB:localhost", "testuser", "test123")
rescue DBI::DatabaseError => e
puts "错误代码: #{e.err}, 错误信息: #{e.errstr}"
end
输出(示例):
错误代码: 1049, 错误信息: Unknown database 'WRONGDB'
7. 补充示例:综合应用
require 'dbi'
module EmployeeManager
def self.list_high_earners(db_name, user, pass, min_income)
DBI.connect("DBI:Mysql:#{db_name}:localhost", user, pass) do |dbh|
sth = dbh.prepare("SELECT FIRST_NAME, LAST_NAME, INCOME FROM EMPLOYEE WHERE INCOME > ?")
sth.execute(min_income)
result = sth.fetch_all.map { |row| "#{row[0]} #{row[1]}: #{row[2]}" }
sth.finish
result
end
rescue DBI::DatabaseError => e
["错误: #{e.errstr}"]
end
end
puts EmployeeManager.list_high_earners("TESTDB", "testuser", "test123", 2000)
# 输出(示例):
# Alice Smith: 3000
# Bob Jones: 2500
8. 注意事项
- 资源管理:优先使用块方式(如
DBI.connect ... do
)自动关闭连接和语句。 - SQL 注入:使用
prepare
和execute
参数绑定,避免直接拼接 SQL。
# 不安全
dbh.do("SELECT * FROM EMPLOYEE WHERE FIRST_NAME = '#{name}'")
# 安全
sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE FIRST_NAME = ?")
sth.execute(name)
- 性能:批量操作使用
prepare
/execute
,减少重复编译 SQL。 - 现代替代:DBI 维护较少,推荐使用
ActiveRecord
(Rails)或Sequel
替代。 - 编码:确保数据库和 Ruby 的编码一致(如 UTF-8)。
9. 总结
Ruby DBI 提供统一的数据库访问接口,通过 DBI.connect
连接数据库,结合 do
或 prepare
/execute
执行 CRUD 操作。事务通过 transaction
或手动 commit
/rollback
管理。异常处理和参数绑定确保安全性和健壮性。尽管功能强大,DBI 在现代 Ruby 生态中逐渐被更高级的 ORM 替代,但仍适合需要跨数据库兼容的场景。
如果你需要更深入的示例(如特定数据库操作、复杂查询)或有其他问题,请告诉我!