Latest web development tutorials

Rubi acesso ao banco - DBI Tutorial

Este capítulo irá mostrar-lhe como usar Ruby para acessar o banco de dados. módulode Ruby DBIfornece uma interface independente de banco de dados é semelhante ao módulo Perl DBI para scripts Ruby.

DBI ou seja, base de dados de interface independente, em nome da interface independente de banco de dados Ruby. DBI entre código Ruby com o banco de dados subjacente fornece uma camada de abstração que permite que você facilmente implementar uma alternância de banco de dados. Ele define um conjunto de métodos, variáveis ​​e normas, fornece uma interface de banco de dados consistente independente de banco de dados.

DBI pode interagir com os seguintes:

  • ADO (ActiveX Data Objects)
  • DB2
  • FrontBase
  • mSQL
  • MySQL
  • ODBC
  • oráculo
  • OCI8 (Oracle)
  • PostgreSQL
  • Proxy / Servidor
  • SQLite
  • SQLRelay

arquitetura de aplicação DBI

DBI independente de qualquer base de dados disponíveis no fundo. Se você estiver usando Oracle, MySQL, Informix, você pode usar o DBI. O gráfico a seguir ilustra claramente este ponto.

arquitetura de Ruby DBI

Ruby DBI arquitectura geral usa duas camadas:

  • Interface de banco de dados (DBI) camada. Esta camada é independente do banco de dados e fornece uma série de método de acesso público, utilizando um servidor de dados, independentemente do tipo de abordagem.
  • motorista de banco de dados (DBD) camada. Esta camada está dependente da base de dados, uma unidade diferente fornece acesso a diferentes bancos de dados. MySQL, PostgreSQL, Interbase, Oracle, respectivamente, utilizando uma unidade diferente. Cada piloto é responsável por interpretar os pedidos da camada DBI, e essas solicitações são mapeados para aplicar a um pedido de um determinado tipo de servidor de banco de dados.

instalar

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

Instale Development Kit Mysql

# Ubuntu
sudo apt-get install mysql-client
sudo apt-get install libmysqlclient15-dev

# Centos
yum install mysql-devel

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

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

Ou usar a conexão suave:

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

Use RubyGems instalar DBI (recomendado)

RubyGems sobre fundada em novembro de 2003, tornou-se parte da biblioteca padrão do Ruby a partir de Ruby 1.9 versão. Mais detalhes podem ser visto: Ruby RubyGems

Use gem install DBI e DBD-mysql:

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

instalação Use cupom (versão do Ruby menos de 1.9 para usar este método)

O módulo é uma DBD, de http://tmtm.org/downloads/mysql/ruby/ download.

Depois de baixar o pacote mais recente, descompacte no diretório, execute o seguinte comando para instalar:

% ruby extconf.rb

或者

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

或者

% ruby extconf.rb --with-mysql-config

Em seguida, compilar:

% make

Obter e instalar o Ruby / DBI

Você pode baixar e instalar o módulo de Ruby DBI a partir do seguinte link:

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

Antes de iniciar a instalação, verifique se você tem privilégios de root. Agora, instale os seguintes passos para instalar:

passo 1

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

Ou diretamente sob outro zip e unzip.

passo 2

Digite o diretórioruby-dbi-master,use script de configuraçãosetup.rbno diretório. Os comandos de configuração mais comuns não são seguidas por todos os parâmetros de configuração parâmetro. O comando de configuração padrão para instalar todos os drivers.

$ ruby setup.rb config

Mais especificamente, você pode usar a opção --with para listar a parte específica que deseja usar. Por exemplo, se você deseja configurar o módulo principal DBI ea unidade camada MySQL DBD, digite o seguinte comando:

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

passo 3

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

$ ruby setup.rb setup
$ ruby setup.rb install

Database Connectivity

Suponha que estamos usando o banco de dados MySQL antes de conectar ao banco de dados, certifique-se de que:

  • Você criou um banco de dados TESTDB.
  • Você criou o EMPREGADO tabela no TESTDB.
  • A tabela com um FIRST_NAME campo, LAST_NAME, idade, sexo e renda.
  • Definir ID de usuário "testuser" eo "test123" senha para acessar TESTDB
  • Já em sua máquina instalado corretamente Rubi módulo DBI.
  • Você viu MySQL tutorial, a compreensão do MySQL operacional subjacente.

Os seguintes são exemplos de MySQL conexão com o banco "TESTDB" de:

#!/usr/bin/ruby -w

require "dbi"

begin
     # 连接到 MySQL 服务器
     dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", 
                       "testuser", "test123")
     # 获取服务器版本字符串,并显示
     row = dbh.select_one("SELECT VERSION()")
     puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Quando você executar este script, irá produzir os seguintes resultados em uma máquina Linux.

Server version: 5.0.45

Se você estabelecer uma conexão com uma fonte de dados, o identificador do banco de dados devolvidos (Handle banco de dados), e salvo noDAP para uso posterior, ou DAPserá definido comovalor nulo,e.err ee :: errstrdevolver o código de erro e erro string.

Finalmente, antes de sair do programa, não se esqueça de fechar a conexão com o banco, a liberação de recursos.

operação INSERT

Quando você deseja criar um registro em uma tabela de banco de dados, você precisará usar a operação INSERT.

Depois que uma conexão de banco de dados, estamos prontos para criar uma tabela ou inserir dados na tabela para criar um método de gravação usando umfazer ou preparareexecutarmétodos.

Use fazer declaração

A declaração não retornar as linhas ligando parafazer métodos de processamento de banco de dados.Este método usa um parâmetro cadeia de instrução e retorna o número de linhas afetadas pela declaração.

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 )" );

Da mesma forma, você pode executarumainstrução SQLINSERTpara criar registros na tabela 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
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
     dbh.rollback
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Usandopreparareexecutar

Você pode usarpreparareexecutaro método de DBI para executar instruções SQL código Ruby.

Para criar um registro da seguinte forma:

  • instrução SQL preparada com a instrução INSERT. Isto será realizado através do usopreparar método.
  • Executar a consulta SQL, selecione todos os resultados do banco de dados. Isto irá ser realizado usandoo método de execução.
  • Liberar o identificador de instrução. Isto será conseguido através da utilização deacabamento API.
  • Se tudo correr bem, em seguida, a operação deconsolidação, ou você pode completar a reversão de transação.

Aqui está a sintaxe destes dois métodos:

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

Ambos os métodos podem ser utilizados paraligar um valor para passar instruções SQL.Às vezes, o valor é inserido não pode ser dado com antecedência, neste caso, é usado para vincular os valores. Use um ponto de interrogação(?) Em vez do valor real, o valor real de passar por executar API ().

O exemplo a seguir cria dois registros na tabela EMPREGADOS:

#!/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"
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
     dbh.rollback
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Se você usar vários INSERT, em seguida, primeiro preparar uma declaração, e depois executar múltiplas vezes em um loop através de cada ciclo do que ele chama fazer muito mais eficiente.

operação de leitura

operação de leitura em qualquer banco de dados refere-se a obter informações úteis a partir da base de dados.

Depois que uma conexão de banco de dados, estamos prontos para consultar o banco de dados. Podemos usar um método ouse preparareexecutarmétodo para obter o valor de uma tabela de banco de dados.

-Se passo registrados como segue:

  • Com base nas condições exigidas para a preparação de consultas SQL. Isto será realizado através do usopreparar método.
  • Executar a consulta SQL, selecione todos os resultados do banco de dados. Isto irá ser realizado usandoo método de execução.
  • Um por um, para obter resultados, e emite os resultados. Isto será conseguido através da utilização de métodosde busca.
  • Liberar o identificador de instrução. Isto será conseguido através da utilização de métodosde acabamento.

O exemplo a seguir consulta todos salário (salário) registrou mais de 1.000 da tabela EMPREGADOS.

#!/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
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Isto produz os seguintes resultados:

First Name: Mac, Last Name : Mohan
Age: 20, Sex : M
Salary :2000

First Name: John, Last Name : Poul
Age: 25, Sex : M
Salary :2300

Existem muitos métodos para a obtenção de registros do banco de dados, se você estiver interessado, você pode ver a operação de Ruby DBI Leia .

Operação atualização

Qualquer operação UPDATE banco de dados refere-se a registros existentes um ou mais atualização de banco de dados. O exemplo a seguir atualiza o sexo é 'M' para todos os registros. Aqui, vamos adicionar um ano todos os homens em idade. Vai ser dividido em três passos:

  • Com base nas condições exigidas para a preparação de consultas SQL. Isto será realizado através do usopreparar método.
  • Executar a consulta SQL, selecione todos os resultados do banco de dados. Isto irá ser realizado usandoo método de execução.
  • Liberar o identificador de instrução. Isto será conseguido através da utilização de métodosde acabamento.
  • Se tudo correr bem, em seguida, a operação deconsolidação, ou você pode completar a reversão de transação.
#!/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
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
     dbh.rollback
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

operação DELETE

Quando você quiser excluir registros do banco de dados, você precisará usar a operação de exclusão. Os exemplos a seguir eliminar AGE 20 sobre todos os registros do EMPREGADO. Os passos da operação são os seguintes:

  • Com base nas condições exigidas para a preparação de consultas SQL. Isto será realizado através do usopreparar método.
  • Executar consultas SQL, exclua os registros desejados do banco de dados. Isto irá ser realizado usandoo método de execução.
  • Liberar o identificador de instrução. Isto será conseguido através da utilização de métodosde acabamento.
  • Se tudo correr bem, em seguida, a operação deconsolidação, ou você pode completar a reversão de transação.
#!/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
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
     dbh.rollback
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Assuntos executivos

Uma transação é um mecanismo para garantir a consistência da transação. Serviços deve ter as quatro seguintes atributos:

  • Atomicidade (atomicidade): atomicidade da transação significa que o programa está incluído na transação como uma unidade lógica de banco de dados de trabalho, ele faz as operações de modificação de dados ou todos executado ou não executado.
  • Consistência (consistência): transacção consistência refere-se a uma operação executada antes e depois da implementação do banco de dados deve estar em um estado consistente.Se o estado da base de dados satisfaz todas as restrições de integridade, dizem que o banco de dados é consistente.
  • Isolation (Isolamento): isolamento de transação refere-se às operações simultâneas são isolados uns dos outros, isto é, dentro de uma transacção de dados de operação e de operação são para ser selada, que não é visto outras tentativas para modificar a operação.
  • Persistente (durabilidade): durabilidade transação significa que quando um sistema ou mídia fracasso, transações empenhada em garantir que as atualizações não pode ser perdida.Que uma vez que uma transação é confirmada, alterar seus dados no banco de dados deve ser permanente, suportar qualquer falha no sistema de banco de dados. Persistente garantida pelo backup e recuperação de dados.

DBI fornece duas maneiras de realizar a transação. Uma delas é aconfirmaçãooureversãométodos para confirmar ou reverter a transação. Há também um método deoperaçãopode ser usado para implementar a operação. Em seguida, apresentamos dois método simples de implementar transações:

método I

O primeiro método usacometemerollbackmétodos da DBI para confirmar ou cancelar a transação explicitamente:

   dbh['AutoCommit'] = false # 设置自动提交为 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

método II

O segundo método utiliza o método deoperação.Este método é relativamente simples, uma vez que requer uma operação constitui um bloco de código que contém declaração. método detransaçãoexecuta o bloco, e então o bloco é executado com sucesso, chamar automaticamenteconfirmaroureverter:

   dbh['AutoCommit'] = false # 设置自动提交为 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 operação

Commit é uma operação foi concluída para identificar as alterações de banco de dados, e após esta operação, todas as mudanças não são reembolsáveis.

Aqui está um exemplo simplescometer invocação de método.

     dbh.commit

operação de reversão

Se você não estiver satisfeito com uma ou algumas alterações, que deseja restaurar completamente estas alterações, utilize o métodorollback.

Aqui está um exemplo simples de chamada de métodorollback.

     dbh.rollback

Desligue o banco de dados

Para desconectar-se do banco de dados, use a API de desconexão.

    dbh.disconnect

Se o usuário fecha o método de desconexão conexão com o banco, DBI reverte todas as transações incompletas. No entanto, ele não contar com os detalhes de implementação de qualquer DBI, e sua aplicação pode ser uma boa chamada explícita para confirmar ou reverter.

erro de processamento

Existem muitas fontes diferentes de erro. Por exemplo, erros de sintaxe na execução da instrução SQL ou a conexão falhar, ou é uma declaração completa ou um chamadas punho cancelados buscar método.

Se um método DBI falhar, DBI irá lançar uma exceção. Método DBI pode jogar qualquer tipo de exceção, mas os dois mais importante classe de exceção éDBI :: InterfaceErroreDBI :: DatabaseError.

objetos de exceção dessas classes sãoErr,errstr três atributos eestado,sub-tabela representa o número do erro, uma string de erro descritiva e um código de erro padrão. Atributo especificado como segue:

  • err: retorna um erro inteiro que ocorreu notação, se DBD não suporta o retorno denil.Por exemplo, a Oracle DBD Retorna seção de mensagem de erro ORA-XXXX.
  • errstr: Retorna uma representação de string do erro que ocorreu.
  • Estado: Retorna o código de erro SQLSTATE ocorreu.SQLSTATE é um comprimento de cinco caracteres. A maior parte da DBD não apoiá-lo, ele irá retornar nulo.

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

rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
     dbh.rollback
ensure
     # 断开与服务器的连接
     dbh.disconnect if dbh
end

Para obter informações de depuração sobre o conteúdo do script é executado quando o script é executado, você pode ativar o rastreamento. Para fazer isso, você deve primeiro fazer o download do módulo DBI / trace, e depois chamar rastreamento modo de controle e método de saída de destinode rastreio:

require "dbi/trace"
..............

trace(mode, destination)

Modo de valor pode ser 0 (largo), 1,2, ou 3, o valor do destino deve ser um objecto IO. Os valores padrão são 2 e STDERR.

método de bloco

Existem maneiras de criar uma alça. Estes métodos são invocados pelo bloco de código. Vantagens do uso de blocos de código com o método é que eles fornecem uma alça para o bloco como um argumento quando o bloco é encerrado alça apagada automaticamente. Aqui estão alguns exemplos para ajudar a compreender este conceito.

  • DBI.connect: Este método gera um identificador de banco de dados, recomenda-se no final do blocode desconexãopara desligar chamada a base de dados.
  • dbh.prepare: Este método gera um identificador de instrução, recomenda chamadaterminarno final do bloco.Dentro de um bloco, você deve chamar o métodoexecutepara executar a instrução.
  • dbh.execute: Este método é semelhante ao dbh.prepare, mas não dbh.execute necessário chamar executar método dentro do bloco.Um identificador de instrução é executado automaticamente.

exemplo 1

DBI.connect pode ter um bloco de código, passando-o identificador do banco de dados, e o punho irá desligar automaticamente no final do bloco.

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

exemplo 2

dbh.prepare pode ter um bloco de código, passando o identificador de instrução, e chama automaticamente terminar no final do bloco.

dbh.prepare("SHOW DATABASES") do |sth|
       sth.execute
       puts "Databases: " + sth.fetch_all.join(", ")
end

exemplo 3

dbh.execute pode ter um bloco de código, passando o identificador de instrução, e chama automaticamente terminar no final do bloco.

dbh.execute("SHOW DATABASES") do |sth|
   puts "Databases: " + sth.fetch_all.join(", ")
end

método de operaçãoDBIpode também ser fornecida com um código de bloco, que nas secções anteriores têm explicado antes.

funções e propriedades específicos do driver

Vamos motorista banco de dados DBI proporciona funções adicionais de banco de dados específico, essas funções podem ser chamado por qualquer objeto método Handle usuáriofunc.

Use[] =métodoou []para definir ou obter atributos drivers específicos.

DBD :: MySQL implementa a função a seguir um driver específico:

Não. Função e Descrição
1 dbh.func (: createdb, db_name)
Criar um novo banco de dados.
2 dbh.func (: dropdb, db_name)
Para excluir um banco de dados.
3 dbh.func (: reload)
Recarregar operação.
4 dbh.func (: shutdown)
Desligue o servidor.
5 dbh.func (: insert_id) => Fixnum
Retorna o valor AUTO_INCREMENT recente da conexão.
6 dbh.func (: client_info) => string
Retorna o MySQL versão do cliente como necessário.
7 dbh.func (: client_version) => Fixnum
Dependendo da informação da versão de volta para o cliente. Isto é: Semelhante ao client_info, mas ele retornará um fixnum, em vez de retornar uma string.
8 dbh.func (: host_info) => string
Retorna as informações de host.
9 dbh.func (: proto_info) => Fixnum
Retorna os protocolos usados ​​para comunicação.
10 dbh.func (: server_info) => string
Retorna as informações MySQL versão servidor baseado.
11 dbh.func (: comando) => stringB >
Retorna o estado atual do banco de dados.
12 dbh.func (: thread_id) => Fixnum
Retorna a identificação da thread atual.

Exemplos

#!/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)
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
ensure
   dbh.disconnect if dbh
end

Isto produz os seguintes resultados:

5.0.45
50045
Localhost via UNIX socket
10
5.0.45
150621
Uptime: 384981  Threads: 1  Questions: 1101078  Slow queries: 4 \
Opens: 324  Flush tables: 1  Open tables: 64  \
Queries per second avg: 2.860