English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Acesso a Banco de Dados DBI Tutorial Ruby

Esta seção explicará como usar Ruby para acessar o banco de dados.Ruby DBI O módulo fornece uma interface independente de banco de dados semelhante ao módulo DBI do Perl para scripts Ruby.

DBI, ou Database independent interface, representa a interface independente de banco de dados do Ruby. O DBI fornece uma camada abstrata entre o código Ruby e o banco de dados subjacente, permitindo que você realize a troca de banco de dados de maneira simples. Ele define uma série de métodos, variáveis e padrões, fornecendo uma interface de banco de dados consistente e independente de banco de dados.

DBI pode interagir com o seguinte:

  • ADO (ActiveX Data Objects)

  • DB2

  • Frontbase

  • mSQL

  • MySQL

  • ODBC

  • Oracle

  • OCI8 (Oracle)

  • PostgreSQL

  • Proxy/Server

  • SQLite

  • SQLRelay

Arquitetura de aplicativo DBI

DBI é independente de qualquer banco de dados disponível em segundo plano. Independentemente de você usar Oracle, MySQL, Informix, você pode usar DBI. O diagrama de arquitetura a seguir ilustra claramente isso.

A arquitetura geral do Ruby DBI usa duas camadas:

  • Camada de interface de banco de dados (DBI). Esta camada é independente do banco de dados e fornece uma série de métodos de acesso públicos, independentemente do tipo do servidor do banco de dados. Você pode usar DBI independentemente de usar Oracle, MySQL, Informix, etc. A seguinte diagrama de arquitetura ilustra claramente isso.

  • Camada de driver de banco de dados (DBD). Esta camada depende do banco de dados e diferentes drivers fornecem acesso a diferentes motores de banco de dados. MySQL, PostgreSQL, InterBase, Oracle, etc., usam drivers diferentes. Cada driver é responsável por interpretar as solicitações da camada DBI e mapeá-las para solicitações adequadas para o servidor do banco de dados do tipo específico.

Instale

Se você quiser escrever scripts Ruby para acessar o banco de dados MySQL, você precisa instalar o módulo Ruby MySQL primeiro.

Instale o pacote de desenvolvimento do Mysql

# Ubuntu
sudo apt-get install mysql-client
sudo apt-get install libmysqlclient15-dev
 
# Centos
yum install mysql-devel

No sistema Mac OS, é necessário modificar ~/.bash_profile ou ~/Adicione o seguinte código ao arquivo .profile:

MYSQL=/usr/local/mysql/bin
export PATH=$PATH:$MYSQL
export DYLD_LIBRARY_PATH=/usr/local/mysql/lib:$DYLD_LIBRARY_PATH

ou use um link simbólico:

sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

Instale DBI usando RubyGems (recomendado)

RubyGems foi aproximadamente criado em2003ano11De 1.9A partir da versão, tornou-se parte da biblioteca padrão do Ruby. Mais detalhes podem ser encontrados em:RubyGems Ruby

Instale dbi e dbd usando gem-mysql:

sudo gem install dbi
sudo gem install mysql
sudo gem install dbd-mysql

Instale usando código-fonte (versão Ruby menor1.9usando este método)

Este módulo é um DBD e pode ser obtido a partir de http://tmtm.org/downloads/mysql/ruby/ para baixar.

Descompacte o pacote mais recente, acesse o diretório e execute os seguintes comandos para instalar:

ruby extconf.rb
 
ou
 
ruby extconf.rb --with-mysql-dir=/usr/local/mysql
 
ou
 
ruby extconf.rb --with-mysql-config

E então compile:

make

Obtenha e instale o Ruby/DBI

Você pode baixar e instalar o módulo Ruby DBI a partir dos seguintes links:

https://github.com/erikh/ruby-dbi

Antes de começar a instalação, certifique-se de que você possui permissões de root. Agora, siga os seguintes passos para instalar:

Passo 1

git clone https://github.com/erikh/ruby-dbi.git

ou descompacte diretamente o pacote zip.

Passo 2

para entrar no diretório ruby-dbi-masterno diretório, use setup.rb script para configurar. O comando mais usado é config, sem parâmetros após o parâmetro. O comando padrão configura a instalação de todos os drivers.

ruby setup.rb config

Mais especificamente, você pode usar --A opção with lista a parte específica que você deseja usar. Por exemplo, se você quiser configurar apenas o módulo DBI principal e o driver de camada DBD MySQL, digite o seguinte comando:

ruby setup.rb config --with=dbi,dbd_mysql

Passo 3

O último passo é criar o driver, use a seguinte comando para instalar:

ruby setup.rb setup
ruby setup.rb install

Conexão do banco de dados

Supondo que estejamos usando o banco de dados MySQL, certifique-se de que, antes de conectar ao banco de dados:

  • Você já criou um banco de dados TESTDB.

  • Você já criou a tabela EMPLOYEE no TESTDB.

  • A tabela possui os campos FIRST_NAME, LAST_NAME, AGE, SEX e INCOME.

  • Defina o ID de usuário "testuser" e a senha "test123" para acessar TESTDB

  • O módulo Ruby DBI foi instalado corretamente no seu computador.

  • Você já viu o tutorial MySQL e compreendeu as operações básicas do MySQL.

A seguir está um exemplo de conexão com o banco de dados MySQL "TESTDB":

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor MySQL
     dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", 
                       "testuser", "test123")
     # Obtém a string da versão do servidor e exibe
     row = dbh.select_one("SELECT VERSION()")
     puts "Versão do servidor: " + row[0]
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Quando executar este script, será gerado o seguinte resultado no computador Linux.

Server version: 5.0.45

如果建立连接时带有数据源,则返回数据库句柄(Database Handle),并保存到 dbh 中以便后续使用,否则 dbh 将被设置为 nil 值,e.err e e::errstr 分别返回错误代码和错误字符串。

最后,在退出这段程序之前,请确保关闭数据库连接,释放资源。

INSERT 操作

当您想要在数据库表中创建记录时,需要用到 INSERT 操作。

一旦建立了数据库连接,我们就可以准备使用 do 方法或 prepare e execute 方法创建表或创建插入数据表中的记录。

使用 do 语句

不返回行的语句可通过调用 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 表中。

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor 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
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
     dbh.rollback
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Usar prepare e execute

您可以使用 DBI 的 prepare e execute 方法来执行 Ruby 代码中的 SQL 语句。

创建记录的步骤如下:

  • 准备带有 INSERT 语句的 SQL 语句。这将通过使用 prepare Método para concluir.

  • 执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute Método para concluir.

  • Liberar o manipulador de instrução. Isso pode ser feito usando finish API 来完成。

  • Se tudo der certo, então commit Essa operação, senão você pode rollback Concluir transação.

下面是使用这两种方法的语法:

Exemplo Online

sth = dbh.prepare(statement)
sth.execute
   ... zero or more SQL operations ...
sth.finish

这两种方法可用于传 bind 值给 SQL 语句。有时候被输入的值可能未事先给出,在这种情况下,则会用到绑定值。使用问号(?)代替实际值,实际值通过 execute() API 来传递。

下面的示例在 EMPLOYEE 表中创建了两个记录:

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor 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"
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
     dbh.rollback
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

如果同时使用多个 INSERT,那么先准备一个语句,然后在一个循环中多次执行它要比通过循环每次调用 do 有效率得多。

READ 操作

对任何数据库的 READ 操作是指从数据库中获取有用的信息。

一旦建立了数据库连接,我们就可以准备查询数据库。我们可以使用 do 方法或 prepare e execute 方法从数据库表中获取值。

获取记录的步骤如下:

  • Preparar consulta SQL com base nas condições necessárias. Isso pode ser feito usando prepare Método para concluir.

  • 执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute Método para concluir.

  • 逐一获取结果,并输出这些结果。这将通过使用 fetch Método para concluir.

  • Liberar o manipulador de instrução. Isso pode ser feito usando finish Método para concluir.

下面的示例从 EMPLOYEE 表中查询所有工资(salary)超过 1000 的记录。

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor 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
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Isso produzirá o seguinte resultado:

First Name: Mac, Last Name:Mohan
Age: 20, Sex:M
Salary:2000
First Name: John, Last Name:Poul
Age: 25,Sex:M
Salary:2300

还有很多从数据库获取记录的方法,如果您感兴趣,可以查看 Operação de Leitura DBI Ruby

Update 操作

对任何数据库的 UPDATE 操作是指更新数据库中一个或多个已有的记录。下面的示例更新 SEX 为 'M' 的所有记录。在这里,我们将把所有男性的 AGE 增加一岁。这将分为三步:

  • Preparar consulta SQL com base nas condições necessárias. Isso pode ser feito usando prepare Método para concluir.

  • 执行 SQL 查询,从数据库中选择所有结果。这将通过使用 execute Método para concluir.

  • Liberar o manipulador de instrução. Isso pode ser feito usando finish Método para concluir.

  • Se tudo der certo, então commit Essa operação, senão você pode rollback Concluir transação.

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor 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
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
     dbh.rollback
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Operação DELETE

Quando você deseja excluir registros do banco de dados, você precisa usar a operação DELETE. O exemplo a seguir remove registros do EMPLOYEE onde AGE é maior que 20 registros. Os passos dessa operação são os seguintes:

  • Preparar consulta SQL com base nas condições necessárias. Isso pode ser feito usando prepare Método para concluir.

  • Executar consulta SQL, excluir os registros necessários do banco de dados. Isso pode ser feito usando execute Método para concluir.

  • Liberar o manipulador de instrução. Isso pode ser feito usando finish Método para concluir.

  • Se tudo der certo, então commit Essa operação, senão você pode rollback Concluir transação.

Exemplo Online

#!/usr/bin/ruby -w
 
require "dbi"
 
begin
     # Conectar ao servidor 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
rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
     dbh.rollback
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Executar transação

A transação é um mecanismo que garante a consistência das transações. A transação deve ter os seguintes quatro atributos:

  • Atomicidade (Atomicity):A atomicidade da transação se reflete no programa contido na transação, que é a unidade de trabalho lógica do banco de dados, onde as operações de modificação de dados devem ser executadas integralmente ou não serem executadas de todo.

  • Consistência (Consistency):A consistência da transação se reflete no estado consistente do banco de dados antes e após a execução da transação. Se o estado do banco de dados atender a todas as restrições de integridade, diz-se que o banco de dados é consistente.

  • Isolação (Isolation):A isolação da transação se reflete na interação de transações que são isoladas, ou seja, as operações internas de uma transação e os dados que estão sendo operados devem ser bloqueados, não sendo vistos por outras transações que tentam fazer alterações.

  • Persistência (Durability):A persistência da transação significa que, em caso de falha do sistema ou do meio, garantem que as atualizações da transação submetida não sejam perdidas. Isto é, uma vez que uma transação for submetida, as mudanças feitas no banco de dados devem ser permanentes, suportando qualquer falha do sistema do banco de dados. A persistência é garantida através de cópias de segurança e recuperação do banco de dados.

O DBI oferece dois métodos para executar transações. Um é commit ou rollback Método, usado para submeter ou reverter a transação. Há também uma outra transaction Método, que pode ser usado para implementar transações. Vamos introduzir agora esses dois métodos simples de implementação de transações:

Método I

O primeiro método usa o DBI commit e rollback Método para explicitamente submeter ou cancelar a transação:

Exemplo Online

dbh['AutoCommit'] = false # Define o commit automático como false.
   begin
     +1 
             
     +1 
             WHERE FIRST_NAME = 'Zara'
     dbh.commit
   rescue
     puts "transaction failed"
     dbh.rollback
   end
   dbh['AutoCommit'] = true

Método II

O segundo método usa transaction Método. Este método é relativamente simples, pois precisa de um bloco de código que constitui a declaração da transação.transaction bloco de execução do método, então, com base no sucesso ou falha do bloco, chama automaticamente commit ou rollback

Exemplo Online

   
     +1 
             
     +1 
             WHERE FIRST_NAME = 'Zara'
   end
   dbh['AutoCommit'] = true

Operação COMMIT

Commit é uma operação que identifica que as mudanças no banco de dados foram concluídas, após essa operação, todas as mudanças não podem ser revertidas.

A seguir é um chamada commit Um exemplo simples do método.

dbh.commit

operação ROLLBACK

Se você não estiver satisfeito com algumas ou algumas mudanças, deseja restaurar completamente essas mudanças, use rollback método.

A seguir é um chamada rollback Um exemplo simples do método.

dbh.rollback

Desconectar banco de dados

Para desconectar a conexão de banco de dados, use a API disconnect.

dbh.disconnect

Se o usuário fechar a conexão de banco de dados através do método disconnect, o DBI reverterá todas as transações não concluídas. No entanto, você não precisa depender de detalhes de implementação do DBI, seu aplicativo pode bem chamar explicitamente commit ou rollback.

Tratar erros

Há muitos tipos diferentes de fontes de erro. Por exemplo, erros de sintaxe ao executar uma instrução SQL, falha na conexão, ou chamada do método fetch em um handle de instrução cancelado ou concluído.

Se um método DBI falhar, o DBI lança exceções. Os métodos DBI podem lançar qualquer tipo de exceção, mas os dois tipos mais importantes de exceções são DBI::InterfaceError e DBI::DatabaseError

Os objetos Exception dessa classe têm errerrstr e state Três atributos, respectivamente representam o número de erro, uma string descritiva do erro e um código de erro padrão. A descrição específica dos atributos é como segue:

  • err:Retorna a representação inteira do erro ocorrido, se o DBD não suportar, retorna nilPor exemplo, o DBD do Oracle retorna ORA-XXXX A parte numérica da mensagem de erro.

  • errstr:Retorna a representação de string do erro ocorrido.

  • state:Retorna o código SQLSTATE do erro ocorrido. O SQLSTATE é uma string de cinco caracteres. A maioria dos DBD não suporta isso, então retorna nil.

No exemplo anterior, você já viu o seguinte código:

rescue DBI::DatabaseError => e
     puts "Ocorreu um erro"
     puts "Código de erro: #{e.err}"
     puts "Mensagem de erro: #{e.errstr}"
     dbh.rollback
garantir
     # Desconectar a conexão com o servidor
     dbh.disconnect if dbh
end

Para obter informações de depuração sobre o conteúdo da execução do script, você pode ativar o rastreamento. Para isso, você deve primeiro baixar o dbi/O módulo trace, em seguida, chama o modo de rastreamento de controle e o destino de saída. trace método:

require \/trace"
..............
 
trace(mode, destination)

O valor de mode pode ser 0(off),1、2 ou 3O valor de destination deve ser um objeto IO. Os valores padrão são 2 e STDERR.

o bloco de código do método

Existem várias maneiras de criar handles. Esses métodos são chamados por meio de blocos de código. A vantagem de usar blocos de código com métodos é que eles fornecem handles como parâmetros para o bloco de código, que são automaticamente removidos quando o bloco termina. Abaixo estão alguns exemplos que ajudam a entender esse conceito.

  • DBI.connect :Este método gera um handle do banco de dados, recomendado chamar disconnect no final do bloco. disconnect para desconectar o banco de dados.

  • dbh.prepare :Este método gera um handle da sentença, recomendado chamar finish no final do bloco. finish. Dentro do bloco, você deve chamar execute método para executar a sentença.

  • dbh.execute :Este método é semelhante ao dbh.prepare, mas o dbh.execute não precisa chamar o método execute dentro do bloco. O handle da sentença executará automaticamente.

Exemplo 1

DBI.connect Pode conter um bloco de código, passando o handle do banco de dados para ele e desconectando automaticamente o handle no final do bloco.

dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", 
                  "testuser", "test123") do |dbh|

Exemplo 2

dbh.prepare Pode conter um bloco de código, passando o handle da sentença para ele e chamando automaticamente finish no final do bloco.

dbh.prepare(\
       sth.execute
       puts \ + sth.fetch_all.join(", ")
end

Exemplo 3

dbh.execute Pode conter um bloco de código, passando o handle da sentença para ele e chamando automaticamente finish no final do bloco.

dbh.execute(\
   puts \ + sth.fetch_all.join(", ")
end

DBI transaction Os métodos também podem conter um bloco de código, o que foi explicado no capítulo anterior.

funções e atributos do driver específico

DBI permite que os drivers de banco de dados forneçam funções específicas para o banco de dados, que podem ser usadas pelo usuário por meio de qualquer objeto Handle func métodos para chamadas.

Usar []= ou [] Métodos podem configurar ou obter propriedades específicas do driver.

DBD::Mysql implementa as funções específicas do driver a seguir:

NúmeroFunção & Descrição
1dbh.func(:createdb, db_name)
Criar um novo banco de dados.
2dbh.func(:dropdb, db_name)
Excluir um banco de dados.
3dbh.func(:reload)
Executar operação de recarregamento.
4dbh.func(:shutdown)
Fechar o servidor.
5dbh.func(:insert_id) => Fixnum
Retorna o último valor AUTO_INCREMENT da conexão.
6dbh.func(:client_info) => String
Retorna informações do cliente MySQL baseado na versão.
7dbh.func(:client_version) => Fixnum
Retorna informações do cliente baseado na versão. Isso é semelhante a :client_info, mas retorna um fixnum em vez de uma string.
8dbh.func(:host_info) => String
Retorna informações do host.
9dbh.func(:proto_info) => Fixnum
Retorna o protocolo utilizado para comunicação.
10dbh.func(:server_info) => String
Retorna informações do servidor MySQL baseado na versão.
11dbh.func(:stat) => Stringb>
Retorna o estado atual do banco de dados.
12dbh.func(:thread_id) => Fixnum
Retorna o ID da thread atual.

Exemplo Online

#!/usr/bin/ruby
 
require "dbi"
begin
   # Conectar ao servidor 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)
rescue DBI::DatabaseError => e
   puts "Ocorreu um erro"
   puts "Código de erro: #{e.err}"
   puts "Mensagem de erro: #{e.errstr}"
garantir
   dbh.disconnect if dbh
end

Isso produzirá o seguinte resultado:

5.0.45
50045
Localhost via Socket UNIX
10
5.0.45
150621
Uptime: 384981  Fios: 1  Perguntas: 1101078  Consultas Lentas: 4 \
Aberturas: 324  Limpas de Tábuas: 1  Abas Abertas: 64  \
Médias de Consultas por Segundo: 2.860