Latest web development tutorials

Rubyのデータベースアクセス - DBIチュートリアル

この章では、データベースにアクセスするためのRubyを使用する方法を紹介します。RubyのDBIモジュールはデータベースに依存しないインタフェースは、Rubyスクリプト用のPerl DBIモジュールに似ています。

Rubyのデータベースに依存しないインターフェースの代わりにDBI、すなわちデータベースに依存しないインタフェース、。 基礎となるデータベースとRubyコードの間のDBIを使用すると、簡単にデータベースの切り替えを実現することを可能にする抽象レイヤを提供します。 これは、メソッド、変数や規範のセットを定義するデータベースに依存しない一貫性のあるデータベース・インタフェースを提供します。

DBIは、次のと対話することができます:

  • ADO(ActiveXデータオブジェクト)
  • DB2
  • Frontbaseの
  • mSQLの
  • MySQLの
  • ODBC
  • オラクル
  • OCI8(Oracleの)
  • PostgreSQLの
  • プロキシ/サーバ
  • SQLiteの
  • SQLRelay

DBIアプリケーションアーキテクチャ

バックグラウンドで使用可能な任意のデータベースのDBIの独立しました。 あなたは、Oracle、MySQLは、Informixのを使用しているかどうか、あなたはDBIを使用することができます。 次のグラフは明らかにこの点を示しています。

RubyのDBIのアーキテクチャ

RubyのDBI一般的なアーキテクチャは、二つの層を使用しています。

  • データベースインタフェース(DBI)層。 この層はデータベースに依存しないで、関係なく、アプローチの種類の、データベース・サーバーを使用して、パブリックアクセス方法のシリーズを提供しています。
  • データベースドライバ(DBD)層。 この層は、異なるドライブが別のデータベースエンジンへのアクセスを提供し、データベースに依存しています。 別のドライブを使用してMySQL、PostgreSQLの、InterBaseの、オラクル、それぞれ。 各ドライバはDBI層からの要求を解釈するための責任があり、そしてこれらの要求は、データベース・サーバーの指定されたタイプの要求に適用するようにマッピングされます。

インストール

MySQLデータベースにアクセスするためのRubyスクリプトを書きたい場合は、RubyのMySQLのモジュールをインストールする必要があります。

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のは、DBIをインストールし使用する(推奨)

2003年11月に設立され、約RubyGemsのは、Ruby 1.9のバージョンからRubyの標準ライブラリの一部となりました。 詳細は見ることができます: ルビーRubyGemsの

DBIとDBD-mysqlのインストールの宝石を使用します。

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

コードのインストール(Rubyのバージョン1.9未満、このメソッドを使用する)を使用します

モジュールから、DBDであるhttp://tmtm.org/downloads/mysql/ruby/のダウンロード。

最新のパッケージをダウンロードした後、ディレクトリに解凍し、インストールするには、次のコマンドを実行します。

% ruby extconf.rb

或者

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

或者

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

その後、コンパイルします。

% make

ルビー/ DBIを入手してインストール

あなたは以下のリンクからのRuby DBIモジュールをダウンロードしてインストールすることができます。

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

インストールを開始する前に、root権限を持っていることを確認してください。 さて、インストールするには、次の手順をインストールします。

ステップ1

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

または直接、別のzipと解凍の下で。

ステップ2

ディレクトリルビー-DBI-マスターを入力して、ディレクトリ内のsetup.rbを構成スクリプトを使用。 最も一般的なコンフィギュレーションコマンドは、任意のパラメータの設定パラメータが続いていません。 デフォルトのコンフィギュレーションコマンドはすべてのドライバをインストールします。

$ ruby setup.rb config

具体的には、あなたが使用したい特定の部分を一覧表示するには--withオプションを使用することができます。 あなたがメインのDBIモジュールとMySQL DBD層のドライブを設定したい場合は、次のコマンドを入力します。

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

ステップ3

最後のステップは、インストールするには、次のコマンドを使用して、ドライブを作成することです:

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

データベース接続

そのことを確認してください、私たちはデータベースに接続する前にMySQLデータベースを使用していると仮定します。

  • あなたは、データベースTESTDBを作成しました。
  • あなたはTESTDBに表EMPLOYEEを作成しました。
  • フィールドFIRST_NAME、LAST_NAME、年齢、性別、所得を持つテーブル。
  • TESTDBにアクセスするための設定ユーザID「TESTUSER」とパスワード「test123」
  • すでにマシン上で正しくRubyのモジュールDBIをインストールしました。
  • あなたは、基礎となるオペレーティング・MySQLを理解し、MySQLのチュートリアルを見てきました。

MySQLデータベースの接続」TESTDB」のの例を示します。

#!/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

このスクリプトを実行すると、Linuxマシン上で次のような結果を生成します。

Server version: 5.0.45

あなたは、データソース、返されたデータベースハンドル(データベース・ハンドル)との接続を確立し、その後の使用のためにDBHに保存、またはDBHが nilの値、e.errおよびeに設定されている場合::エラーコードとエラーを返すERRSTR文字列。

最後に、このプログラムを終了する前に、データベース接続、リソースの解放を確実に閉じてください。

INSERT操作

あなたは、データベーステーブルのレコードを作成したいときは、INSERT操作を使用する必要があります。

データベース接続したら、私たちはテーブルを作成したり、実行したり準備実行の方法を用いた記録方法を作成するために、テーブルにデータを挿入する準備が整いました。

使用do文

文は、データベースの処理方法を行う呼び出すことによって、行を返しません。 このメソッドは、SQL文の文字列パラメータを取り、文によって影響を受けた行数を返します。

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

同様に、あなたはEMPLOYEE表にレコードを作成するためのSQL INSERT文を実行することができます。

#!/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

準備実行の使用

あなたはRubyのコードのSQL文を実行するためにDBIの準備実行方法を使用することができます。

次のようにレコードを作成するには:

  • INSERT文とSQL文を作成しました。 これは、方法を準備する使用によって達成されます。
  • SQLクエリを実行し、データベースからすべての結果を選択します。 これを実行する方法を使用することによって達成されます。
  • ステートメント・ハンドルを解放します。 これは、仕上げAPIの使用を通じて達成されます
  • すべてがうまくいけば、その後の操作をコミットするか、トランザクション・ロールバックを完了することができます。

ここではこれらの2つの方法の構文は次のとおりです。

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

両方の方法は、SQL文を渡すために値をバインドするために使用することができます。 時には、入力された値は、この場合には、値をバインドするために使用され、事前に与えられなくてもよいです。 疑問符(?)を使用する代わりに、実際の値の、実際の値は()APIを実行通過します。

次の例では、EMPLOYEE表の2つのレコードを作成します。

#!/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

あなたが複数のINSERTを使用する場合は、最初の文を準備し、それははるかに効率的に行う呼び出しよりも、各サイクルをループ内で複数回実行します。

READ動作

任意のデータベース上のREAD操作は、データベースから有用な情報を得ることを指します。

データベース接続したら、我々はデータベースを照会する準備が整いました。 私たちは、この方法を使用することができたり、データベーステーブルから値を取得するメソッドを作成し、実行します

次のようにステップを記録しましょう:

  • SQLクエリの作成に必要な条件に基づきます。 これは、方法を準備する使用によって達成されます。
  • SQLクエリを実行し、データベースからすべての結果を選択します。 これを実行する方法を使用することによって達成されます。
  • 一つ一つは、結果を取得し、結果を出力します。 このフェッチ方法の使用を通じて達成されます。
  • ステートメント・ハンドルを解放します。 これは、仕上げ方法を使用することによって達成されます。

次の例のクエリは、すべての賃金(給与)は、EMPLOYEE表から1,000人以上を記録しました。

#!/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

これにより、以下の結果が得られます。

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

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

データベースからレコードを取得する多くの方法は、あなたが興味を持っている場合は、表示することができ、存在するのRuby DBI読み取り操作を

更新操作

任意のデータベース更新操作は、1つ以上のデータベースの更新既存のレコードを指します。 次の例では、すべてのレコードの 'M'でSEXを更新します。 ここでは、年間のすべての男性のAGEを追加します。 それは3つのステップに分割されます。

  • SQLクエリの作成に必要な条件に基づきます。 これは、方法を準備する使用によって達成されます。
  • SQLクエリを実行し、データベースからすべての結果を選択します。 これを実行する方法を使用することによって達成されます。
  • ステートメント・ハンドルを解放します。 これは、仕上げ方法を使用することによって達成されます。
  • すべてがうまくいけば、その後の操作をコミットするか、トランザクション・ロールバックを完了することができます。
#!/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

DELETE操作

あなたは、データベースからレコードを削除したいときは、DELETE操作を使用する必要があります。 次の例では、EMPLOYEEのすべてのレコードを介してAGE 20を削除します。 次のように操作手順は次のとおりです。

  • SQLクエリの作成に必要な条件に基づきます。 これは、方法を準備する使用によって達成されます。
  • SQLクエリを実行し、データベースから目的のレコードを削除します。 これを実行する方法を使用することによって達成されます。
  • ステートメント・ハンドルを解放します。 これは、仕上げ方法を使用することによって達成されます。
  • すべてがうまくいけば、その後の操作をコミットするか、トランザクション・ロールバックを完了することができます。
#!/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

エグゼクティブ総務

トランザクションは、トランザクションの整合性を確保するための仕組みです。 サービスには、次の4つの属性を持っている必要があります。

  • アトミック(原子性):トランザクションの原子は、プログラムが作業データベースの論理的な単位としてトランザクションに含まれていることを意味し、それはデータ変更操作を行うのいずれかのすべての実行、またはまったく実行されません。
  • 整合性(一貫性):整合性トランザクションは、データベースの実装が一貫性のある状態でなければなりません前と後に実行されたトランザクションを指します。データベースの状態は、すべての整合性制約を満たしている場合、データベースは一貫性があると言います。
  • 絶縁(アイソレーション):トランザクション分離は、それがトランザクションを変更するための他の試みを見ていないされ、封止されるべき操作や運転データのトランザクション内、つまり、互いに分離される並行トランザクションを指します。
  • 永続性(耐久性):トランザクションの耐久性は、システム障害やメディア障害は、更新が失われることができないことを確実にするために、トランザクションをコミットしたときにことを意味します。つまり、一度トランザクションがデータベース内のデータを変更し、コミットし、任意のデータベースシステムの障害に耐え、永久的でなければなりません。 永続的なデータベースのバックアップとリカバリによって保証されています。

DBIはトランザクションを実行する2つの方法を提供します。 一つは、トランザクションをコミットまたはロールバックするには、コミットまたはロールバックする方法です。 トランザクションを実装するために使用することができる取引方法もあります。 次に、トランザクションを実装する2つの簡単な方法をご紹介します:

方法I

第一の方法は、明示的にトランザクションをコミットまたはキャンセルするDBIのコミットロールバックメソッドを使用しています。

   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

方法II

第二の方法は、 取引方法を使用しています。 それはトランザクションが文を含むコードブロックを構成する必要があるため、この方法は、比較的簡単です。 自動的にコミットまたはロールバック呼び出し、 取引方法は、ブロックを実行し、その後、ブロックが正常に実行されます

   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操作

コミット操作は、データベースの変更を識別するために完了しており、この操作の後、すべての変更はリカバリできませんされています。

ここでは簡単な例は、メソッド呼び出しをコミットしています。

     dbh.commit

ROLLBACK操作

あなたは、1つまたはいくつかの変更に満足していない場合、あなたは完全にこれらの変更を復元する、rollbackメソッドを使用します。

ここでは、ロールバックメソッドコールの簡単な例です。

     dbh.rollback

データベースを切断します

データベースから切断するには、切断APIを使用します。

    dbh.disconnect

ユーザーがデータベース接続の切断方法を閉じた場合、DBIは、すべての不完全なトランザクションをロールバックします。 しかし、それは任意のDBIの実装の詳細に依存しない、とあなたのアプリケーションがコミットまたはロールバックするには良いの明示的な呼び出しすることができます。

処理エラー

エラーのさまざまなソースがあります。 たとえば、構文のSQL文の実行中のエラーまたは接続が失敗した場合、または完全なステートメントであるか、またはキャンセルされたハンドルの呼び出しは、メソッドを取得します。

DBIメソッドが失敗した場合、DBIは例外をスローします。 DBIメソッドは、例外の任意の型を投げることができますが、最も重要な二つの例外クラスは、DBI :: InterfaceErrorDBI :: DatabaseErrorです

これらのクラスの例外オブジェクトはerrがあり、3つの属性や状態ERRSTR、サブテーブルには、エラー番号、エラーの内容を表す文字列と標準エラーコードを表します。 次のように指定された属性:

  • ERR:DBDがnilの復帰をサポートしていない場合、表記を発生した整数エラーを返しますたとえば、Oracle DBDはセクションORA-XXXXのエラーメッセージを返します。
  • errstrは:発生したエラーの文字列表現を返します。
  • 状態:SQLSTATEエラーコードが発生しました返します。SQLSTATEは、5文字の文字列の長さです。 DBDのほとんどはそれをサポートしていない、それはnilを返します。

上記の例では、次のコードを見てきました:

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

スクリプトが実行されたとき、あなたはトレースを有効にすることができます実行されるスクリプトの内容に関するデバッグ情報を取得するには。 これを行うには、まずDBI /トレースモジュールをダウンロードし、制御モードと出力先トレースメソッドを追跡呼び出す必要があります:

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

trace(mode, destination)

値モードが0(オフ)、1,2、または3であることができ、先の値がIOオブジェクトでなければなりません。 デフォルト値は2とSTDERRです。

ブロック法

ハンドルを作成する方法があります。 これらのメソッドは、コードブロックによって呼び出されます。 この方法を使用してコードブロックを使用する利点は、それらがブロックは自動的にクリアされたハンドルを終了する引数としてブロックに対するハンドルを提供することです。 ここでは、この概念を理解するのに役立ついくつかの例があります。

  • DBI.connect:このメソッドは、データベース・ハンドルを生成し、データベースを切断するブロックの呼切断の終了時に推奨されます。
  • dbh.prepare:この方法は、ブロックの最後に仕上げを呼び出してお勧めします、ステートメント・ハンドルを生成します。ブロック内では、ステートメントを実行するためにexecuteメソッドを呼び出す必要があります。
  • dbh.execute:このメソッドはdbh.prepareと似ているが、ブロック内のメソッドを実行呼び出す必要はありませdbh.execute。ステートメント・ハンドルが自動的に実行されます。

例1

DBI.connectはそれをデータベースハンドルを渡して、コードのブロックを有していてもよく、およびハンドルは自動的にブロックの最後に切断されます。

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

例2

dbh.prepareは、ステートメント・ハンドルを渡して、コードブロックを持っており、自動的にブロックの最後に仕上げを呼び出すことができます。

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

例3

dbh.executeは、ステートメント・ハンドルを渡して、コードブロックを持っており、自動的にブロックの最後に仕上げを呼び出すことができます。

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

DBI取引方法は、上記の項で前に説明したコードのブロックを備えることができます。

ドライバ固有の機能とプロパティ

DBIのデータベースドライバは、これらの関数は、任意のユーザーFUNC法ハンドルオブジェクトで呼び出すことができ、特定のデータベースの追加機能を提供してみましょう。

設定または属性を特定のドライバを取得するには、[] =または[]メソッドを使用します。

DBD :: mysqlのは、特定のドライバ次の関数を実装しています。

いいえ。 機能と説明
1 dbh.func(:createdbは、DB_NAME)
新しいデータベースを作成します。
2 dbh.func(:dropdbは、DB_NAME)
データベースを削除します。
3 dbh.func(:リロード)
操作をリロードします。
4 dbh.func(:シャットダウン)
サーバーをシャットダウンします。
5 dbh.func(:INSERT_ID)=> Fixnumか
接続の最近のAUTO_INCREMENT値を返します。
6 dbh.func(:CLIENT_INFO)=>文字列
必要に応じてのMySQLクライアントのバージョン情報を返します。
7 dbh.func(:クライアント_)=> Fixnumか
クライアントに戻すバージョン情報に応じて。 CLIENT_INFOと同様ですが、それはむしろ文字列を返すよりも、FIXNUMを返します。これがあります。
8 dbh.func(:host_info)=>文字列
ホスト情報を返します。
9 dbh.func(:proto_info)=> Fixnumか
通信に使用されるプロトコルを返します。
10 dbh.func(:SERVER_INFO)=>文字列
ベースのMySQLサーバのバージョン情報を返します。
11 dbh.func(:STAT)=> Stringb >
データベースの現在の状態を返します。
12 dbh.func(:thread_idは)=> Fixnumか
現在のスレッドのIDを返します。

#!/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

これにより、以下の結果が得られます。

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