Ruby 访问数据库
-
DBI教程
本章教您如何使用Ruby访问数据库。Ruby DBI模块提供类似于Perl DBI模块的Ruby脚本独立于数据库的接口。DBI代表Ruby的数据库独立接口,这意味着DBI在Ruby代码和基础数据库之间提供了一个抽象层,使您可以真正轻松地切换数据库实现。它定义了一组方法,变量和约定,它们提供了一致的数据库接口,而与所使用的实际数据库无关。DBI可以与以下接口:- ADO (ActiveX Data Objects)
- DB2
- Frontbase
- mSQL
- MySQL
- ODBC
- Oracle
- OCI8 (Oracle)
- PostgreSQL
- Proxy/Server
- SQLite
- SQLRelay
-
DBI应用程序的体系结构
DBI独立于后端中可用的任何数据库。无论您是使用Oracle,MySQL还是Informix等,都可以使用DBI。从以下体系结构图中可以清楚地看出这一点。Ruby DBI的通用架构使用两层-- 数据库接口(DBI)层。该层是独立于数据库的,并且提供了一组常用访问方法,无论您要与之通信的数据库服务器的类型如何,都以相同的方式使用它们。
- 数据库驱动程序(DBD)层。该层取决于数据库;不同的驱动程序提供对不同数据库引擎的访问。有一个用于MySQL的驱动程序,另一个用于PostgreSQL的驱动程序,另一个用于InterBase的驱动程序,另一个用于Oracle的驱动程序,依此类推。每个驱动程序解释来自DBI层的请求,并将它们映射到适合给定类型的数据库服务器的请求。
首先下载gem-::https://rubygems.org/pages/download来管理各种依赖和API(这里安装gem我们把gem的可执行目录bin添加到了环境变量PATH以便于使用gem命令)。安装完成后我们进行依赖安装,和DBI和MySQL驱动的安装。 -
数据库连接
假设我们要使用MySQL数据库,在连接数据库之前,请确保以下内容-- 假设您已经创建了数据库test。
- 您已经在TESTDB中创建了EMPLOYEE。
- 该表具有字段FIRST_NAME,LAST_NAME,AGE,SEX和INCOME。
- 用户ID“root”和密码“123465”设置为访问test数据库。
- Ruby Module DBI已正确安装在您的机器上。
- 您已经阅读了MySQL教程,以了解MySQL基础。
以下是连接MySQL数据库“test”的示例运行上面的代码,如果您能正确连接数据库,应该返回类型下面的消息:如果与数据源建立了连接,则将数据库句柄返回并保存到dbh中以供进一步使用,否则dbh设置为nil值,并且e.err和e :: errstr分别返回错误代码和错误字符串。最后,请确保关闭数据库连接并释放资源。 -
插入操作
要在数据库表中创建记录时需要INSERT操作。建立数据库连接后,我们准备使用do方法或prepare和execute方法在数据库表中创建表或记录。使用do语句您可以执行SQL INSERT语句在EMPLOYEE表中创建一条记录。使用prepare和execute您可以使用DBI类的prepare和execute方法通过Ruby代码执行SQL语句。记录创建采取以下步骤-- 用INSERT语句准备SQL语句。这将使用prepare方法完成。
- 执行SQL查询以从数据库中选择所有结果。这将使用execute方法完成。
- 释放语句句柄。这将使用finish API 完成
- 如果一切正常,请执行此操作,否则您可以回滚整个事务。
以下是使用这两种方法的语法-这两种方法可用于将绑定值传递给SQL语句。在某些情况下,可能不会事先给出要输入的值。在这种情况下,将使用绑定值。使用问号(?)代替实际值,然后实际值通过execute() API传递。以下是在EMPLOYEE表中创建两个记录的示例-如果一次有多个INSERT,则首先准备一条语句,然后在循环中多次执行它比每次在循环中调用都更有效。 -
读操作
任何数据库上的读操作都意味着从数据库中获取一些有用的信息。建立数据库连接后,就可以对这个数据库进行查询了。我们可以使用do方法,也可以使用prepare和execute方法从数据库表中获取值。记录获取采取以下步骤-- 根据所需条件准备SQL查询。这将使用prepare方法完成。
- 执行SQL查询以从数据库中选择所有结果。这将使用execute方法完成。
- 一张一张地获取所有结果并打印这些结果。这将使用fetch方法完成。
- 释放语句句柄。这将使用finish方法完成。
以下是从薪水超过1000的EMPLOYEE表中查询所有记录的过程。这将产生以下结果-还有更多捷径可以从数据库中获取记录。如果您有兴趣,请查看DBI方法。 -
更新操作
UPDATE对任何数据库的操作意味着更新一个或多个记录,这些记录已在数据库中可用。以下是更新所有SEX为'M'的记录的过程。在这里,我们将所有男性的年龄提高一年。这将采取三个步骤-- 根据所需条件准备SQL查询。这将使用prepare方法完成。
- 执行SQL查询以从数据库中选择所有结果。这将使用execute方法完成。
- 释放语句句柄。这将使用finish方法完成。
- 如果一切正常,请执行此操作,否则您可以回滚整个事务。
如果一切正常,将产生以下结果- -
删除操作
要从数据库中删除某些记录时,需要执行DELETE操作。以下是从AGE大于20的EMPLOYEE删除所有记录的过程。此操作将执行以下步骤。- 根据所需条件准备SQL查询。这将使用prepare方法完成。
- 执行SQL查询以从数据库中删除所需的记录。这将使用execute方法完成。
- 释放语句句柄。这将使用finish方法完成。
- 如果一切正常,请执行此操作,否则您可以回滚整个事务。
如果一切正常,将产生以下结果- -
执行事务
事务是一种确保数据一致性的机制。事务应具有以下四个属性--
原子性 -交易完成或什么都没有发生。 一致性 -事务必须以一致状态开始,而使系统处于一致状态。 隔离性 -交易的中间结果在当前交易之外不可见。 持久性 -提交事务后,即使在系统故障后,效果也将持续存在。
DBI提供了两种方法来提交或回滚事务。还有另一种称为事务的方法,可用于实现事务。有两种简单的方法来实现事务-方法一第一种方法使用DBI的commit和rollback方法显式提交或取消事务-方法二第二种方法使用事务处理方法。这比较简单,因为它需要一个包含构成事务的语句的代码块。的交易方法执行块,然后调用提交或回滚自动,这取决于该块是否成功或失败-提交操作Commit是一项操作,它向数据库发出绿色信号以完成更改,并且在执行此操作后,将无法还原任何更改。这是一个调用commit方法的简单示例。回滚操作如果您对一项或多项更改不满意,并且想要完全还原这些更改,请使用回滚方法。这是调用rollback方法的简单示例。断开数据库要断开数据库连接,请使用断开连接API。如果用户使用断开连接方法关闭了与数据库的连接,则DBI将回滚所有未完成的事务。但是,最好不要显式调用提交或回滚,而不必依赖于DBI的任何实现细节。 -
处理错误
错误的来源很多。一些示例是已执行的SQL语句中的语法错误,连接失败或为已取消或完成的语句句柄调用fetch方法。如果DBI方法失败,则DBI引发异常。DBI方法可以引发几种类型的异常中的任何一种,但是两个最重要的异常类是DBI::InterfaceError和DBI::DatabaseError。这些类的异常对象具有名为err,errstr和state的三个属性,分别表示错误编号,描述性错误字符串和标准错误代码。属性说明如下-- err - 返回发生的错误的整数表示形式; 如果DBD不支持,则返回nil。例如,Oracle DBD返回ORA-XXXX错误消息的数字部分。
- errstr - 返回所发生错误的字符串表示形式。
- state - 返回的发生和error.The SQLSTATE的SQLSTATE代码是一个五字符的长字符串。大多数DBD不支持此功能,而是返回nil。
您已经在大多数示例中看到了以下代码-要获取有关脚本执行时的操作的调试信息,可以启用跟踪。为此,必须首先加载dbi/trace模块,然后调用控制跟踪模式和输出目标的trace方法-模式值可以是0(关闭),1、2或3,并且目标应该是IO对象。默认值分别为2和STDERR。 -
带方法的代码块
有一些创建句柄的方法。可以使用代码块来调用这些方法。将代码块与方法一起使用的优点是,它们将代码块的句柄作为其参数提供,并在代码块终止时自动清除该句柄。很少有例子可以理解这个概念。- DBI.connect - 此方法生成数据库句柄,建议在块末尾调用断开连接以断开数据库连接。
- dbh.prepare - 此方法生成一个语句句柄,建议在代码块末尾完成。在该块中,您必须调用execute方法来执行该语句。
- dbh.execute - 此方法类似,只不过我们不需要在块内调用execute。语句句柄将自动执行。
例子1DBI.connect可以获取一个代码块,将数据库句柄传递给它,然后按如下所示自动断开该块末尾的句柄。-例子2dbh.prepare可以获取一个代码块,将语句句柄传递给它,然后按如下所示在该块的末尾自动调用finish。例子3dbh.execute可以获取一个代码块,将语句句柄传递给它,并在该块的末尾自动调用finish,如下所示:DBI 事务方法还采用了上面已描述的代码块。 -
驱动程序特定的功能和属性
DBI使数据库驱动程序提供附加的特定于数据库的功能,用户可以通过任何Handle对象的func方法调用这些功能。支持特定于驱动程序的属性,可以使用[]=或[]方法进行设置或获取。