integration technology of ruby and db
DESCRIPTION
Rubyとデータベースの連携技術TRANSCRIPT
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
1© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
RubyRubyとデータベースとの連携技術とデータベースとの連携技術Integration Technology of Ruby and Database
鹿児島大学 学術情報基盤センター学術情報処理研究部門古屋 保[email protected]
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
2© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
内容内容● 1. データベース連携概要● 2. MySQLバインディングによる連携● 3. ActiveRecordによる連携
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
3© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
1. 1. データベース連携概要データベース連携概要● RubyとMySQLデータベースとの連携
– データベース抽象レイヤを使用せず,直接バインディングを使用してみる.(SQLを記述する必要がある)
「mysql2」…MySQL用のバインディングGem(https://github.com/brianmario/mysql2)
#MySQLのバインディングをインストールする$ gem install mysql2
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
4© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
1. 1. データベース連携概要データベース連携概要● Rubyとデータベースとの連携
– ほとんどのDBMSと連携可能 MySQL,PostgreSQL,Oracle,Microsoft SQL
Server,DB2,SQLite 各データベースAPIへのバインディングをGemで提供
– データベース抽象レイヤ(ActiveRecord) DBの違いを意識することなくコーディング可能.
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
5© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
2. MySQL2. MySQLバインディングによる連携バインディングによる連携● 連携するデータベース(テーブル)
– 「students」テーブル(予めmysqlツールで作成)mysql> use test;mysql> CREATE TABLE students (-> id CHAR(11) NOT NULL,-> name VARCHAR(40),-> e_mail VARCHAR(80),-> PRIMARY KEY (id)->);
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
6© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
2. MySQL2. MySQLバインディングによる連携バインディングによる連携● プログラム例
# -*- coding: utf-8 -*-require 'mysql2'
# ユーザ dbuser で MySQL の test データベースに接続する.client = Mysql2::Client.new( :host => "localhost", :database => "test", :username => "dbuser", :password => "pass" )
# SQLを実行し結果セットを得る.results = client.query("SELECT * FROM students")
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
7© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
2. MySQL2. MySQLバインディングによる連携バインディングによる連携● プログラム例
# 結果セットから全レコードのカラムの値をイテレータで取得する.results.each do |row| printf "%s\t%s\t%s\n", row["id"], row["name"], row["e_mail"]end
# データベースと接続をクローズする.client.close
$ ruby dbaccess.rb1234567891 鹿児島太郎 [email protected] 薩摩花子 [email protected] 西郷隆盛 [email protected]
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
8© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● ActiveRecord
– データベース抽象レイヤのモジュール– Ruby on Railsを構成するライブラリ群の1つ– O/Rマッピング(Object / Relation Mapping)ライブラリ
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
9© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● O/Rマッピング
– データベースのレコードとRubyのオブジェクトをマップする– テーブルのフィールドが、オブジェクトの属性となり,フィー
ルド名がそのままアクセサとして定義される.
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
10© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● プログラム例(ActiveRecord編)
# -*- coding: utf-8 -*-require 'active_record'
# 1.8系 # require 'rubygems' # require 'activerecord'
# データベースとの接続ActiveRecord::Base.establish_connection(
:adapter => 'mysql2', # 使用するDBはMySQLデータベース :host => 'localhost', :database => 'test', :username => 'dbuser', :password => 'pass')
(次のスライドへ続く...)
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
11© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● プログラム例(ActiveRecord編)
# O/Rマッピングclass Student < ActiveRecord::Baseend
students = Student.find(:all)students.each do |res| printf "%s\t%s\t%s\n", res.id, res.name, res.e_mailend
$ ruby dbaccess.rb1234567891 鹿児島太郎 [email protected] 薩摩花子 [email protected] 西郷隆盛 [email protected]
id,name,e_mail等の属性メソッドは定義してないのにも関わらず...
id,name,e_mail等の属性メソッドは定義してないのにも関わらず...
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
12© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● Conversion over Configuration(CoC)
– 「設定よりも規約」(Railsの哲学)– XMLファイルなどのコンフィグはいらない– すべては命名規約に従うこと
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
13© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● YAMLファイルの利用
– YAML (YAML Ain't Markup Language)
– 構造化されたテキストフォーマット– Railsでは config/database.yml で利用
development_test: adapter: mysql2 host: localhost database: test username: dbuser password: pass socket: /opt/local/var/run/mysql5/mysqld.sock encoding: utf8 pool: 5
YAMLファイルの例: database.yml(MySQL用)
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
14© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● プログラム例(ActiveRecord,YAML利用)
# -*- coding:utf-8 -*-require 'active_record'
# YAMLを利用したデータベースの接続ActiveRecord::Base.configurations = YAML.load_file('database.yml')ActiveRecord::Base.establish_connection('development_test')
class Student < ActiveRecord::Baseend
students = Student.find(:all)students.each do |res| printf "%s\t%s\t%s\n", res.id, res.name, res.e_mailend
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
15© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● findメソッドの使用法
例えば...result = Student.find(2)
これは次のSQL文と同等であるSELECT * FROM students WHERE id = 2
※プライマリキーフィールドは「id」というフィールド名でなければNG
解決策class Student < ActiveRecord::Base
set_table_name 'gakusei' # テーブル名は任意でもOK
set_primary_key 's_code' # プライマリキーは任意でもOKend
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
16© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● もうSQLは書かなくても良い?
さらに条件をつけて抽出したい場合は...result = Student.find(:all,
:conditions => [ 'name = ?', '鹿児島太郎' ])
SELECT * FROM students WHERE name = '鹿児島太郎'
find以外にも次のようなメソッドも準備されている...result = Student.find_by_name("鹿児島太郎")
さらにレコードの新規追加も...student = Student.new(:id => '1234567894',
:name =>"川内次郎", :e_mail => '[email protected]')
student.save
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
17© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
3. ActiveRecord3. ActiveRecordによる連携による連携● ホントにSQLは書かなくても良い?
複雑なクエリーは,直接SQLで書くことも可能...
result = Student.find_by_sql("SELECT * FROM students WHERE name LIKE '%太郎%' AND e_mail LIKE '%jp%'")
まとめ...● 規約に従えばきちんとO/Rマッピングしてくれる.● マッピングできれば用意されたメソッドで結果セットを得られる.● 結果セットから属性メソッドでフィールドデータを得られる.● 極力SQLを書かなくて済む● データベースをいつでも交換できる
その他...● DMLだけでなくDDLも可能(Migrationクラス)
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
18© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
4. 4. おまけおまけ● テーブルのJOIN
id name e_mail
1234567891 鹿児島太郎 [email protected]
1234567892 薩摩花子 [email protected]
1234567893 西郷隆盛 [email protected]
id name teacher
S01 情報科学入門 山田太郎S02 エンドユーザ実習 鈴木一郎S03 応用数学 松井秀喜
student_id subject_id rating
1234567891 S02 A
1234567891 S03 B
1234567892 S01 C
1234567893 S02 B
students(学生) subjects(科目)
courses(履修)
1
多 多
1
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
19© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
4. 4. おまけおまけ● 結合ビュー
student_id name subject_id name rating
1234567891 鹿児島太郎 S02 エンドユーザ実習 A
1234567891 鹿児島太郎 S03 応用数学 B
1234567892 薩摩花子 S01 情報科学入門 C
1234567893 西郷隆盛 S02 エンドユーザ実習 B
mysql> SELECT student_id, students.name, subject_id, -> subjects.name, rating -> FROM students JOIN (courses JOIN subjects -> ON courses.subject_id = subjects.id ) -> ON students.id = courses.student_id;
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
20© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
4. 4. おまけおまけ● テーブルのJOIN
id name e_mail
1234567891 鹿児島太郎 [email protected]
1234567892 薩摩花子 [email protected]
1234567893 西郷隆盛 [email protected]
id name teacher
S01 情報科学入門 山田太郎S02 エンドユーザ実習 鈴木一郎S03 応用数学 松井秀喜
student_id subject_id rating
1234567891 S02 A
1234567891 S03 B
1234567892 S01 C
1234567893 S02 B
students(学生) subjects(科目)
courses(履修)has_many :course has_many :course
belongs_to :student belongs_to :subject
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
21© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
4. 4. おまけおまけ● テーブル間リレーションを意識した定義
class Student < ActiveRecord::Base has_many :courseend
class Subject < ActiveRecord::Base has_many :courseEnd
class Course < ActiveRecord::Base belongs_to :student belongs_to :subjectend
Rubyとデータベースとの連携技術Rubyとデータベースとの連携技術
22© Tamotsu FURUYA, All rights reserved.K-Ruby, July 28, 2011
4. 4. おまけおまけ● 結合結果の出力
courses = Course.find(:all, :include => [:student, :subject])courses.each do |res|
printf "%s\t%s\t%s\t%s\t%s\n", res.student_id, res.student.name,
res.subject_id, res.subject.name, res.ratingend
$ ruby dbaccess.rb1234567891 鹿児島太郎 S02 エンドユーザ実習 A1234567891 鹿児島太郎 S03 応用数学 B1234567892 薩摩花子 S01 情報科学入門 C1234567893 西郷隆盛 S02 エンドユーザ実習 B