English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
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
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.
Se você quiser escrever scripts Ruby para acessar o banco de dados MySQL, você precisa instalar o módulo Ruby MySQL primeiro.
# 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
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
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
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":
#!/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 操作。
一旦建立了数据库连接,我们就可以准备使用 do 方法或 prepare e 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 # 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
您可以使用 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.
下面是使用这两种方法的语法:
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 # 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 操作是指从数据库中获取有用的信息。
一旦建立了数据库连接,我们就可以准备查询数据库。我们可以使用 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 的记录。
#!/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
对任何数据库的 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.
#!/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
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.
#!/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
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:
O primeiro método usa o DBI commit e rollback Método para explicitamente submeter ou cancelar a transação:
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
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
+1 +1 WHERE FIRST_NAME = 'Zara' end dbh['AutoCommit'] = true
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
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
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.
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 err、errstr 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.
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.
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|
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
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.
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úmero | Função & Descrição |
---|---|
1 | dbh.func(:createdb, db_name) Criar um novo banco de dados. |
2 | dbh.func(:dropdb, db_name) Excluir um banco de dados. |
3 | dbh.func(:reload) Executar operação de recarregamento. |
4 | dbh.func(:shutdown) Fechar o servidor. |
5 | dbh.func(:insert_id) => Fixnum Retorna o último valor AUTO_INCREMENT da conexão. |
6 | dbh.func(:client_info) => String Retorna informações do cliente MySQL baseado na versão. |
7 | dbh.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. |
8 | dbh.func(:host_info) => String Retorna informações do host. |
9 | dbh.func(:proto_info) => Fixnum Retorna o protocolo utilizado para comunicação. |
10 | dbh.func(:server_info) => String Retorna informações do servidor MySQL baseado na versão. |
11 | dbh.func(:stat) => Stringb> Retorna o estado atual do banco de dados. |
12 | dbh.func(:thread_id) => Fixnum Retorna o ID da thread atual. |
#!/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