English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In diesem Kapitel erläutern wir, wie Sie mit Ruby auf Datenbanken zugreifen.Ruby DBI Das Modul bietet Ruby-Skripten eine Datenbankunabhängige Schnittstelle, ähnlich wie das Perl DBI-Modul.
DBI, das Datenbankunabhängige Schnittstelle bedeutet, repräsentiert die unabhängige Datenbank-Schnittstelle von Ruby. DBI bietet eine Abstraktionsschicht zwischen Ruby-Code und der zugrunde liegenden Datenbank, die es Ihnen ermöglicht, einfach zwischen Datenbanken zu wechseln. Es definiert eine Reihe von Methoden, Variablen und Normen und bietet eine konsistente Datenbank-Schnittstelle, die unabhängig von der Datenbank ist.
DBI kann mit folgendem interagieren:
ADO (ActiveX Data Objects)
DB2
Frontbase
mSQL
MySQL
ODBC
Oracle
OCI8 (Oracle)
PostgreSQL
Proxy/Server
SQLite
SQLRelay
DBI 独立于任何在后台中可用的数据库。无论您使用的是 Oracle、MySQL、Informix,您都可以使用 DBI。下面的架构图清晰地说明了这点。
Ruby DBI 一般的架构使用两个层:
数据库接口(DBI)层。该层是独立于数据库,并提供了一系列公共访问方法,方法的使用不分数据库服务器类型。
数据库驱动(DBD)层。该层是依赖于数据库,不同的驱动提供了对不同的数据库引擎的访问。MySQL、PostgreSQL、InterBase、Oracle 等分别使用不同的驱动。每个驱动都负责解释来自 DBI 层的请求,并把这些请求映射为适用于给定类型的数据库服务器的请求。
如果您想要编写 Ruby 脚本来访问 MySQL 数据库,您需要先安装 Ruby MySQL 模块。
# Ubuntu sudo apt-get install mysql-client sudo apt-get install libmysqlclient15-dev # Centos yum install mysql-devel
Mac OS 系统需要修改 ~/.bash_profile 或 ~/.profile 文件,添加如下代码:
MYSQL=/usr/local/mysql/bin export PATH=$PATH:$MYSQL export DYLD_LIBRARY_PATH=/usr/local/mysql/lib:$DYLD_LIBRARY_PATH
或者使用软连接:
sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib
RubyGems大约创建于2003年11月,从Ruby 1.9版起成为Ruby标准库的一部分。更多详情可以查看:RubyRubyGems
使用 gem 安装 dbi 与 dbd-mysql:
sudo gem install dbi sudo gem install mysql sudo gem install dbd-mysql
Dieses Modul ist ein DBD und kann von http://tmtm.org/downloads/mysql/ruby/ Herunterladen.
Laden Sie nach dem Herunterladen des neuesten Pakets in das Verzeichnis aus und führen Sie die folgenden Befehle aus, um zu installieren:
ruby extconf.rb oder ruby extconf.rb --with-mysql-dir=/usr/local/mysql oder ruby extconf.rb --with-mysql-config
und kompilieren Sie dann:
make
Erhalten und installieren Sie Ruby/DBI
Sie können das Ruby DBI-Modul von den folgenden Links herunterladen und installieren:
https://github.com/erikh/ruby-dbi
Stellen Sie sicher, dass Sie Root-Rechte haben, bevor Sie mit der Installation beginnen. Installieren Sie die folgenden Schritte:
Schritt 1
git clone https://github.com/erikh/ruby-dbi.git
oder extrahieren Sie direkt das zip-Paket und entpacken Sie es.
Schritt 2
Gehen Sie in das Verzeichnis ruby-dbi-masterVerwenden Sie setup.rb Skript zum Konfigurieren verwenden. Der häufigste Konfigurationsbefehl ist config, gefolgt von keinem Parameter. Dieser Befehl ist standardmäßig so konfiguriert, dass alle Treiber installiert werden.
ruby setup.rb config
Genauer gesagt, können Sie --Die mit Option listet die spezifischen Teile auf, die Sie verwenden möchten. Zum Beispiel, wenn Sie nur die Haupt-DBI-Module und die MySQL DBD-Schichttreiber konfigurieren möchten, geben Sie den folgenden Befehl ein:
ruby setup.rb config --with=dbi,dbd_mysql
Schritt 3
Der letzte Schritt ist die Erstellung des Treibers, führen Sie den folgenden Befehl aus, um zu installieren:
ruby setup.rb setup ruby setup.rb install
Angenommen, wir verwenden die MySQL-Datenbank, stellen Sie sicher, dass Sie dies vor der Verbindung zur Datenbank überprüfen:
Sie haben eine Datenbank TESTDB erstellt.
Sie haben die Tabelle EMPLOYEE in TESTDB erstellt.
Diese Tabelle enthält die Felder FIRST_NAME, LAST_NAME, AGE, SEX und INCOME.
Legen Sie den Benutzer-ID "testuser" und das Passwort "test" fest123", um auf TESTDB zuzugreifen
Das Ruby-Modul DBI wurde auf Ihrem Rechner korrekt installiert.
Sie haben den MySQL-Tutorial gelesen und die grundlegenden Operationen von MySQL verstanden.
Nachstehend ist ein Beispiel für die Verbindung zur MySQL-Datenbank "TESTDB":
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") # Ermitteln Sie die Server-Versionssitzung und zeigen Sie sie an row = dbh.select_one("SELECT VERSION()") puts "Server version: " + row[0] rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
Wenn dieses Skript ausgeführt wird, werden auf dem Linux-Rechner die folgenden Ergebnisse erzeugt.
Server version: 5.0.45
如果建立连接时带有数据源,则返回数据库句柄(Database Handle),并保存到 dbh 中以便后续使用,否则 dbh 将被设置为 nil 值,e.err und e::errstr 分别返回错误代码和错误字符串。
最后,在退出这段程序之前,请确保关闭数据库连接,释放资源。
当您想要在数据库表中创建记录时,需要用到 INSERT 操作。
一旦建立了数据库连接,我们就可以准备使用 do 方法或 prepare und execute 方法创建表或创建插入数据表中的记录。
不返回行的语句可通过调用 do 数据库处理方法。该方法带有一个语句字符串参数,并返回该语句所影响的行数。
dbh.do("DROP TABLE IF EXISTS EMPLOYEE") dbh.do("CREATE TABLE EMPLOYEE ( FIRST_NAME CHAR(20) NOT NULL, LAST_NAME CHAR(20), AGE INT, SEX CHAR(1, INCOME FLOAT )");
同样地,您可以执行 SQL INSERT 语句来创建记录插入 EMPLOYEE 表中。
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") dbh.do("INSERT INTO EMPLOYEE(FIRST_NAME," LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)") puts "Record has been created" dbh.commit rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" dbh.rollback ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
您可以使用 DBI 的 prepare und execute 方法来执行 Ruby 代码中的 SQL 语句。
创建记录的步骤如下:
准备带有 INSERT 语句的 SQL 语句。这将通过使用 prepare method to complete.
执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute method to complete.
Release the statement handle. This will be done by using finish API 来完成。
If everything goes well, then commit If this operation is not performed, you can rollback Complete the transaction.
下面是使用这两种方法的语法:
sth = dbh.prepare(statement) sth.execute ... zero or more SQL operations ... sth.finish
这两种方法可用于传 bind 值给 SQL 语句。有时候被输入的值可能未事先给出,在这种情况下,则会用到绑定值。使用问号(?)代替实际值,实际值通过 execute() API 来传递。
下面的示例在 EMPLOYEE 表中创建了两个记录:
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") sth = dbh.prepare("INSERT INTO EMPLOYEE(FIRST_NAME," LAST_NAME, AGE, SEX, INCOME) VALUES (?, ?, ?, ?, ?)" ) sth.execute('John', 'Poul', 25, 'M', 2300) sth.execute('Zara', 'Ali', 17, 'F', 1000) sth.finish dbh.commit puts "Record has been created" rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" dbh.rollback ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
如果同时使用多个 INSERT,那么先准备一个语句,然后在一个循环中多次执行它要比通过循环每次调用 do 有效率得多。
对任何数据库的 READ 操作是指从数据库中获取有用的信息。
一旦建立了数据库连接,我们就可以准备查询数据库。我们可以使用 do 方法或 prepare und execute 方法从数据库表中获取值。
获取记录的步骤如下:
Prepare SQL queries based on the required conditions. This will be done by using prepare method to complete.
执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute method to complete.
逐一获取结果,并输出这些结果。这将通过使用 fetch method to complete.
Release the statement handle. This will be done by using finish method to complete.
下面的示例从 EMPLOYEE 表中查询所有工资(salary)超过 1000 的记录。
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE INCOME > ?") sth.execute(1000) sth.fetch do |row| printf "First Name: %s, Last Name : %s\n", row[0], row[1] printf "Age: %d, Sex : %s\n", row[2], row[3] printf "Salary :%d \n\n", row[4] end sth.finish rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
DieserBefehlwirdfolgendesErgebnisverursachen:
First Name: Mac, Last Name : Mohan Age: 20, Sex : M Salary :2000 First Name: John, Last Name : Poul Age: 25, Sex : M Salary :2300
对任何数据库的 UPDATE 操作是指更新数据库中一个或多个已有的记录。下面的示例更新 SEX 为 'M' 的所有记录。在这里,我们将把所有男性的 AGE 增加一岁。这将分为三步:
Prepare SQL queries based on the required conditions. This will be done by using prepare method to complete.
执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute method to complete.
Release the statement handle. This will be done by using finish method to complete.
If everything goes well, then commit If this operation is not performed, you can rollback Complete the transaction.
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE" + 1 WHERE SEX = ?") sth.execute('M') sth.finish dbh.commit rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" dbh.rollback ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
When you want to delete records from the database, you need to use the DELETE operation. The following example deletes records from EMPLOYEE where AGE is over 20 records. The steps for this operation are as follows:
Prepare SQL queries based on the required conditions. This will be done by using prepare method to complete.
Execute SQL queries, delete the required records from the database. This will be done by using execute method to complete.
Release the statement handle. This will be done by using finish method to complete.
If everything goes well, then commit If this operation is not performed, you can rollback Complete the transaction.
#!/usr/bin/ruby -w require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") sth = dbh.prepare("DELETE FROM EMPLOYEE WHERE AGE > ?") sth.execute(20) sth.finish dbh.commit rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" dbh.rollback ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
A transaction is a mechanism to ensure the consistency of transactions. A transaction should have the following four properties:
Atomicity (Atomicity):The atomicity of a transaction means that the program contained in the transaction is the logical unit of work of the database, and the data modification operations it performs must either be executed entirely or not executed at all.
Consistency (Consistency):The consistency of a transaction means that the database must be in a consistent state before and after the execution of the transaction. If the state of the database satisfies all the integrity constraints, then the database is consistent.
Isolation (Isolation):The isolation of a transaction refers to the fact that concurrent transactions are isolated from each other, that is, the operations within a transaction and the data being operated on must be locked up and not visible to other transactions that attempt to modify them.
Durability (Durability):The durability of a transaction means that when a system or medium fails, it ensures that the updates of the committed transactions are not lost. That is, once a transaction is committed, the changes it makes to the data in the database should be permanent and withstand any database system failure. Durability is guaranteed through database backups and recovery.
DBI provides two methods for executing transactions. One is commit oder rollback A method for committing or rolling back transactions. There is also another transaction A method that can be used to implement transactions. Next, we will introduce these two simple methods for implementing transactions:
The first method uses DBI's commit und rollback A method to explicitly commit or cancel a transaction:
dbh['AutoCommit'] = false # Set automatic commit to false. begin dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'") dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'") dbh.commit rescue puts "transaction failed" dbh.rollback end dbh['AutoCommit'] = true
The second method uses transaction Method. This method is relatively simple because it requires a code block that constitutes the transaction statement.transaction Methode-Ausführungsbereich, dann wird automatisch aufgerufen, je nachdem, ob der Bereich erfolgreich ausgeführt wird oder nicht. commit oder rollback:
dbh['AutoCommit'] = false # Setzen Sie den automatischen Commit auf false dbh.transaction do |dbh| dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'") dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'") end dbh['AutoCommit'] = true
Commit ist eine Operation, die angibt, dass die Änderungen in der Datenbank abgeschlossen sind, nach dieser Operation sind alle Änderungen nicht rückgängig zu machen.
Hier ist ein Aufruf commit einfaches Beispiel.
dbh.commit
Wenn Sie mit einer oder mehreren Änderungen unzufrieden sind und diese vollständig rückgängig machen möchten, verwenden Sie rollback Methode.
Hier ist ein Aufruf rollback einfaches Beispiel.
dbh.rollback
Um die Datenbankverbindung zu trennen, verwenden Sie die disconnect API.
dbh.disconnect
Wenn der Benutzer die Datenbankverbindung durch das disconnect-Verfahren schließt, rollt DBI alle unvollständigen Transaktionen zurück. Aber es ist nicht erforderlich, sich auf die Implementierungsdetails von DBI zu verlassen, Ihr Programm kann gut explizit commit oder rollback aufrufen.
Es gibt viele verschiedene Fehlerquellen. Zum Beispiel Syntaxfehler beim Ausführen eines SQL-Befehls, eine fehlgeschlagene Verbindung oder der Aufruf der fetch-Methode auf einem bereits abgebrochenen oder abgeschlossenen Statement-Handle.
Wenn eine DBI-Methode fehlschlägt, wirft DBI eine Ausnahme. DBI-Methode wirft jede Art von Ausnahme, aber die wichtigsten beiden Ausnahmearten sind DBI::InterfaceError und DBI::DatabaseError.
Diese Exception-Objekte der Klasse haben err、errstr und state Drei Attribute, die den Fehlercode, eine beschreibende Fehlerzeichenkette und einen standardisierten Fehlercode darstellen. Die spezifische Erklärung wie folgt:
err:Rückgabe der Integer-Repräsentation des aufgetretenen Fehlers, wird nil zurückgegeben, wenn DBD nicht unterstützt. nil. Zum Beispiel, Oracle DBD gibt zurück ORA-XXXX Die numerische Teil des Fehlers.
errstr:Rückgabe der Zeichenkettenrepräsentation des aufgetretenen Fehlers.
state:Rückgabe des SQLSTATE-Codes des aufgetretenen Fehlers. SQLSTATE ist eine fünfstellige Zeichenkette. Die meisten DBD unterstützen es nicht, daher wird nil zurückgegeben.
Im obigen Beispiel haben Sie bereits den folgenden Code gesehen:
rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" dbh.rollback ensure # Verbindung zum Server trennen dbh.disconnectifdbh end
Um Debugging-Informationen über den Inhalt der Skriptausführung zu erhalten, können Sie das Tracing aktivieren. Dafür müssen Sie zunächst dbi/Das Trace-Modul und dann die Steuerung der Trace-Modi und der Ausgabeziele aufgerufen werden. trace Methode:
require \/trace" .............. trace(mode, destination)
Der Wert von mode kann 0(off) sein1、2 oder 3Der Wert von destination sollte ein IO-Objekt sein. Die Standardwerte sind 2 und STDERR.
Es gibt einige Methoden zur Erstellung von Handles. Diese Methoden rufen Codeblocks auf. Der Vorteil von Codeblocks mit Methoden ist, dass sie dem Codeblock Handles als Parameter übergeben und diese automatisch bereinigen, wenn der Block endet. Einige Beispiele können das Konzept veranschaulichen.
DBI.connect :Diese Methode generiert ein Datenbankhandle und wird empfohlen, am Ende des Blocks aufgerufen zu werden disconnect um die Datenbank zu trennen.
dbh.prepare :Diese Methode generiert ein Statement-Handle und wird empfohlen, am Ende des Blocks aufgerufen zu werden finish. Innerhalb des Blocks müssen Sie execute Methode, um Anweisungen auszuführen.
dbh.execute :Diese Methode ähnelt dbh.prepare, aber dbh.execute benötigt nicht, dass die execute-Methode im Block aufgerufen wird. Das Statement-Handle wird automatisch ausgeführt.
DBI.connect Sie können auch einen Codeblock haben, dem ein Datenbankhandle übergeben wird und der am Ende des Blocks automatisch abgeschlossen wird.
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") do |dbh|
dbh.prepare Sie können auch einen Codeblock haben, dem ein Statement-Handle übergeben wird und der am Ende des Blocks automatisch finish aufgerufen wird.
dbh.prepare(\ sth.execute puts \ + sth.fetch_all.join(", ") end
dbh.execute Sie können auch einen Codeblock haben, dem ein Statement-Handle übergeben wird und der am Ende des Blocks automatisch finish aufgerufen wird.
dbh.execute(\ puts \ + sth.fetch_all.join(", ") end
DBI transaction Die Methoden können auch einen Codeblock haben, was in den obigen Kapiteln bereits erläutert wurde.
DBI ermöglicht es den Datenbanktreibern, zusätzliche spezifische Datenbankfunktionen bereitzustellen, die durch Benutzer über jedes Handle-Objekt aufgerufen werden können func Methoden zum Aufrufen.
Verwenden []= oder [] Methoden können Eigenschaften spezifischer Treiber setzen oder abrufen.
DBD::Mysql implementiert die Funktionen der folgenden spezifischen Treiber:
Nummer | Funktion & Beschreibung |
---|---|
1 | dbh.func(:createdb, db_name) Erstellt eine neue Datenbank. |
2 | dbh.func(:dropdb, db_name) Löscht eine Datenbank. |
3 | dbh.func(:reload) Führt einen Neuladen aus. |
4 | dbh.func(:shutdown) Schließt den Server. |
5 | dbh.func(:insert_id) => Fixnum Gibt den letzten AUTO_INCREMENT-Wert der Verbindung zurück. |
6 | dbh.func(:client_info) => String Gibt die Clientinformationen des MySQL-Clients zurück, basierend auf der Version. |
7 | dbh.func(:client_version) => Fixnum Gibt die Clientinformationen zurück, basierend auf der Version. Dies ist ähnlich wie :client_info, aber es wird ein Fixnum zurückgegeben, anstatt einer Zeichenkette. |
8 | dbh.func(:host_info) => String Gibt die Hostinformationen zurück. |
9 | dbh.func(:proto_info) => Fixnum Gibt das Protokoll zurück, das für die Kommunikation verwendet wird. |
10 | dbh.func(:server_info) => String Gibt die Serverinformationen des MySQL-Servers zurück, basierend auf der Version. |
11 | dbh.func(:stat) => Stringb> Gibt den aktuellen Zustand der Datenbank zurück. |
12 | dbh.func(:thread_id) => Fixnum Gibt die ID der aktuellen Thread zurück. |
#!/usr/bin/ruby require "dbi" begin # 连接到 MySQL 服务器 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") puts dbh.func(:client_info) puts dbh.func(:client_version) puts dbh.func(:host_info) puts dbh.func(:proto_info) puts dbh.func(:server_info) puts dbh.func(:thread_id) puts dbh.func(:stat) rescueDBI::DatabaseError=>e puts"EinFehleristaufgetreten" puts"Fehlercode: #{e.err}" puts"Fehlermeldung: #{e.errstr}" ensure dbh.disconnectifdbh end
DieserBefehlwirdfolgendesErgebnisverursachen:
5.0.45 50045 LocalhostviaUNIXSocket 10 5.0.45 150621 Uptime: 384981 Fäden: 1 Fragen: 1101078 LangsameAnfragen: 4 \ Öffnungen: 324 LeereTabellen: 1 OffeneTabellen: 64 \ DurchschnitteAnfragenproSekunde: 2.860