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 注入:使用 prepareexecute 参数绑定,避免直接拼接 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 连接数据库,结合 doprepare/execute 执行 CRUD 操作。事务通过 transaction 或手动 commit/rollback 管理。异常处理和参数绑定确保安全性和健壮性。尽管功能强大,DBI 在现代 Ruby 生态中逐渐被更高级的 ORM 替代,但仍适合需要跨数据库兼容的场景。

如果你需要更深入的示例(如特定数据库操作、复杂查询)或有其他问题,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注