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一般的なアーキテクチャは、二つの層を使用しています。
- データベースインタフェース(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 :: InterfaceErrorとDBI :: 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