MySQL道普請便り

第73回RubyからMySQLを操作してみる

今回は、RubyプログラムからMySQLの操作がしたい場合に、mysql2というライブラリを利用してMySQLへアクセスする方法を紹介したいと思います。mysql2はRuby on Railsでも利用されているライブラリで、RailsのActiveRecordと組み合わせて利用される事も多いですが、今回はRubyのプログラムからアクセスする方法を紹介したいと思います。

検証環境

第10回 yum, rpmインストールにおけるMySQL 5.6とMySQL 5.7の違いで紹介されたyumリポジトリーを使用したインストールを利用しています。また、MySQLのバージョンは5.7.22を使用しています。つい先日(2018年4月19日⁠⁠、MySQ L8.0もGAになりましたが、今回は5.7を利用して説明を行っていきます。

mysql2をインストールする際に、mysqlのヘッダファイルが必要となるため、追加でsudo yum install mysql-community-devel -yを実行しておきましょう。これを忘れると次のmysql2をインストール中にエラーが出て途中で停止してしまいます。

Rubyのインストールをする

CentOSでRubyをインストールする方法としては、大まかに分けて4種類が考えられます。

  1. rbenvとruby-buildを利用してインストールする
  2. rvmを利用してインストールする
  3. yumを利用してインストールする
  4. 自力でビルドをする

今回は手軽に試して行きたいので、yumでrubyをインストールします。しかし、yumでインストールされるRubyは2.0系とかなり古いので、実際に開発や本番で利用する際には、rbenvやrvmを利用して、なるべく最新のrubyを使うようにしましょう。

$ sudo yum install -y ruby ruby-devel

以上のコマンドでrubyをインストールすることができます。

mysql2をインストールする

Rubyでライブラリをインストールするには、RubyGemsというライブラリを管理する仕組みを利用します。とりあえず試してみたい場合は、以下のようにgem installコマンドを使ってmysql2をインストールしてみましょう。

$ sudo gem install mysql2

正しくインストールができているかは、以下のようにirbという対話的なインタープリタを使うことで確認することができます。この例のようにrequire 'mysql2'を実行した時にtrueが返ってきたら、正しくインストールが完了しています。この時にLoadError: cannot load such file -- mysql2のようなメッセージが出た場合は、mysql2のインストールに失敗しているので、もう一度最初から試してみてください。

$ irb
irb(main):001:0> require 'mysql2'
=> true

gem installでインストールした場合に、インストールを行った時期によって複数バージョンがインストールされてしまうことがあります。複数のバージョンが混在するような場合に、どのバージョンを使っているかを指定する仕組みとして、bundlerがあります。こちらを使ってインストールを行う場合は以下のようにコマンドを実行してください。また、bundleを使った場合はirbを実行する時に、単にirbと打つのではなく、bundle exec irbとコマンドがちょっとだけ変わるのに注意をしてください。

$ gem install bundler

$ bundle init
$ ls
Gemfile

$ echo 'gem mysql2' > Gemfile
$ bundle install
$ bundle exec irb
irb(main):001:0> require 'mysql2'
=> true

bundle installを行った時点で生成されているGemfile.lockですが、こちらに使用するバージョン情報などが書かれています。そのため、別のPCなどへソースコードを持っていった場合にも、同じバージョンをインストールしてすぐに利用することができるようになります。Gemfile.lockの中身は以下のようになっており、mysql2のバージョン情報(今回は0.5.1)も含めて記録されていることがわかります。

GEM
  remote: https://rubygems.org/
  specs:
    mysql2 (0.5.1)

PLATFORMS
  ruby

DEPENDENCIES
  mysql2

BUNDLED WITH
   1.16.1

mysql2を使ってMySQLに接続をする

rubyのインストールとmysql2のインストール、お疲れさまでした。ここからは、インストールしたmysql2を使ってMySQLに接続をするプログラムを書いてみます。

require 'mysql2'

client = Mysql2::Client.new(host: "localhost", username: "root", password: '', database: 'mysql')

上記のように、MySQL2::Clientクラスを使って接続を行います。引数にrubyのハッシュ値を渡すことで、接続情報を加えることができます。よく使うオプションについて、以下の表にまとめました。

オプション オプションの意味
host 接続先のホスト情報
username 接続に使用するユーザ名
password 接続に使用するパスワード
database 接続するデータベース
socket unixドメインソケットの情報
port 接続先のポート情報(デフォルトは3306)
encoding 文字エンコーディングの指定

これ以外でどのようなオプションがあるのか気になる方は、GitHub上のReadmeに書かれているConnection optionsの項を確認してみてください。

SQLを実行してみる

接続することができたので、続けてSQLを実行してみようと思います。SQLを実行するには、queryメソッドにSQL文字列を渡す事で実行されます。今回は文字列を結合する方式で行っているため、文字列をescapeして問題とならないように修正して結合しています。

$ cat main.rb
require 'mysql2'

client = Mysql2::Client.new(host: "localhost", username: "root", password: '', database: 'mysql')

escaped = client.escape('performance_schema')
results = client.query("SELECT Db  FROM db WHERE Db = '#{escaped}'")

results.each do |row|
  puts row
  puts row['Db']
end

$ bundle exec ruby main.rb
{"Db"=>"performance_schema"}
performance_schema

上記のコードを実行するとSELECTが実行されて、Dbカラムがperfomance_schemaになっている要素が取得できていることがわかります。

プリペアードステートメントを使ってみる

さて、前項ではエスケープをした文字列を結合する形でSQLを組み立てました。しかし、この方法だとエスケープに漏れがあった場合に、SQLインジェクションという恐ろしい脆弱性を引き起こしてしまう可能性があります。その脆弱性を防ぐために、プリペアードステートメントという仕組みがあります。ここではその使い方を紹介していこうと思います。

$ cat main2.rb
require 'mysql2'

client = Mysql2::Client.new(host: "localhost", username: "root", password: '', database: 'mysql')

statement = client.prepare('SELECT Db  FROM db WHERE Db = ?')
results = statement.execute('performance_schema')

results.each do |row|
  puts row
  puts row['Db']
end

$ bundle exec ruby main2.rb 
{"Db"=>"performance_schema"}
performance_schema

今回はprepareメソッドとexecuteメソッドを使用しています。prepareメソッドでプリペアードステートメントを定義しています。SQL中で、プログラムから指定を行いたい箇所に?と書きます。

その後、executeメソッドで実行しています。引数にはプログラムからSQLに与えたい文字列を渡しています。こちらもqueryメソッドで実行したときと同様に、Dbカラムがperfomance_schemaになっている要素が取得できていることがわかります。

まとめ

今回は、mysql2というライブラリを利用して、RubyのプログラムからMySQLに接続する基本的な方法を紹介しました。このライブラリを利用すると、簡単にプログラムからMySQLを利用できるようになります。ちょっとした変換などを行いたい場合に、SQLだけで頑張るのは辛いときもあります。そんな時に、この方法を使えばRubyとSQLを組み合わせて簡単に実現できるようになるので、試してみてはいかがでしょうか。

おすすめ記事

記事・ニュース一覧