Yii Frameworkで複数データソースを扱う

Yii Framework第2弾。

負荷分散などの理由で、データベースを複数に分けたりすること、ありますよね。しかし、やり方がYiiの日本語ガイドには書いてなかったので、書いてみます。

やり方は簡単で、protected/config/main.phpにちょこちょこっと記述するだけです。

// application components
'components'=>array(
	'db'=>array(
		'connectionString' => 'mysql:host=hostname1;dbname=hoge',
		'emulatePrepare' => true,
		'enableParamLogging' => true,
		'username' => 'user1',
		'password' => 'pass1',
		'charset' => 'utf8',
	),
	'db_fuga'=>array(
		'class' => 'CDbConnection', // ここ重要
		'connectionString' => 'mysql:host=hostname2;dbname=fuga',
		'emulatePrepare' => true,
		'enableParamLogging' => true,
		'username' => 'user2',
		'password' => 'pass2',
		'charset' => 'utf8',
	),

これだけで、Yii::app()->dbと同様に、以下のような感じで使えるようになります。

Yii::app()->db_fuga; // fugaデータベース

ね、簡単でしょ?

Yii Frameworkでabstract classを使う

仕事でYii Frameworkってのを使ってるのですが、日本ではじぇんじぇん流行ってないみたい。
てことで、以前はまった経験を書いておこうと思います。
普通に開発をしていると、共通の機能を抽象クラスとして切り出したい場面が出てくると思います。
だもんで、こんな風にabstract classを書いてみます。

protected/controllers/AbstractTestController.php

<?php
abstract class AbstractTestController extends CController
{
	protected function hoge()
	{
		echo "hoge"; // 共通処理
	}
}

protected/controllers/TestController.php

<?php
class TestController extends AbstractTestController
{
	public function actionHoge()
	{
		$this->hoge();
	}
}

で、ブラウザからhogeアクションにアクセスすると、怒られます。

include(AbstractTestController.php) [function.include]: failed to open stream: No such file or directory

AbstractTestController.phpが読み込めないようです。yiiには自動クラスロード機構があるので、勝手にincludeしてくれるはずなのですが。。。
protected/config/main.phpを見てみます。

	// autoloading model and component classes
	'import'=>array(
		'application.models.*',
		'application.components.*',
	),

yiicで自動生成したままでは、'application.controllers.*'が入ってないようです。以下のように修正します。

	// autoloading model and component classes
	'import'=>array(
		'application.models.*',
		'application.components.*',
		'application.controllers.*',
	),

これで、ブラウザからhogeアクションにアクセスすると無事"hoge"が表示されます。

Doltengで生成したpom.xmlのハマリどころ。

以前ハマった経験より。

Doltengで自動生成したプロジェクトのpom.xmlにこんな記述があります。

<repository>
	<id>local</id>
	<name>Local Repository</name>
	<url>file:repo</url>
</repository>

この記述は、プロジェクト内にjarを配置することで、公開リポジトリにないjar(たとえばojdbc6.jarとか)のインストールを簡略化させるためのものです(たぶん)。
具体的に言うと、プロジェクトをsvnなどで配布したときに、個々の開発者がmvn installを叩いてojdbc6.jarとかをローカルリポジトリにインストールする必要がなくなります。
はずなのですが、これが機能していなくてかなり悩みました。。。
まずは、プロジェクト内にこんな感じでjarを配置します。

my-project
 + repo
  + com
   + oracle
    + ojdbc6
     + 11.2.0.1.0
      + ojdbc6-11.2.0.1.0.jar

で、pom.xmlにこんな感じで依存を追加します。

<dependency>
	<groupId>com.oracle</groupId>
	<artifactId>ojdbc6</artifactId>
	<version>11.2.0.1.0</version>
</dependency>

そして、m2eclipseから依存を解決させます。

プロジェクト右クリック->Maven->依存関係の更新

これでローカルリポジトリにojdbc6.jarがインストールされると思いきや、こんなメッセージが。。。

10/04/14 23:55:19 JST: Missing artifact com.oracle:ojdbc6:jar:11.2.0.1.0:compile

見つからないようだ。。。
色々と試行錯誤した結果、pom.xmlを以下のように書き換えることで解決。


	local
	Local Repository
	file:${basedir}/repo

ojdbc6.jarがローカルリポジトリにインストールされ、依存もきちんと解決されました。
ちなみに、環境はこんな感じ。環境の問題なのだろうか。。。?

Dolteng 0.40.0
m2eclipse 0.10.0.20100209-0800
Maven 2.2.1

Cubbyを動かしてみる。

CubbyEclipse+Maven2+m2eclipse+Tomcatプラグイン+devloaderで動かしてみました。
理由は以前業務で使った時に使い易かったから。。。その時はSAStrutsでしたけど。
なんで使い易いかは、下記の通りです。
http://bagineer.blog59.fc2.com/blog-entry-98.html

下準備

JDK6とかTomcat6とかMaven2とかは省略します。よしなにインストール。
EclipsePleiades All in Oneを使いました。Tomcatプラグインがすでに入っています。
http://mergedoc.sourceforge.jp/
m2eclipseプラグインは下記のダウンロードサイトからインストールします。
http://m2eclipse.sonatype.org/sites/m2e/
Devloaderは下記リンクを参考に、devloader-3.2.1ex.jarとdevloader.confを配置します。
http://jfut.integ.jp/2007/11/16/m2eclipse-and-devloader-ex/
devloader.confに以下の1行を追加します。

file:/(.*)/geronimo-el(.*).jar

プロジェクト作成

コマンドプロンプトを起動し、Eclipseワークスペースに移動し、プロジェクトのひな型を作成します。

cd c:\workspace
mvn archetype:generate -DarchetypeCatalog=http://cubby.seasar.org

なんだかたくさん出力されたあとに、いくつか質問が投げかけられます。太字が入力した部分です。

Choose archetype:
1: http://cubby.seasar.org -> cubby-s2-archetype (Cubby 2.0.9 S2Container Integration)
2: http://cubby.seasar.org -> cubby-guice-archetype (Cubby 2.0.9 Guice Integration)
3: http://cubby.seasar.org -> cubby-spring-archetype (Cubby 2.0.9 Spring Integration)
4: http://cubby.seasar.org -> cubby-archetype (Cubby 1.1.7)
Choose a number:  (1/2/3/4): 1[Enter]
Define value for groupId: : com.example.cubby.test[Enter]
Define value for artifactId: : cubby-test[Enter]
Define value for version:  1.0-SNAPSHOT: :[Enter]
Define value for package:  com.example.cubby.test: :[Enter]
Confirm properties configuration:
java-source-version: 1.6
java-target-version: 1.6
cubby-version: 2.0.9
s2container-version: 2.4.40
s2dao-version: 1.0.50
use-s2dao: false
use-s2jdbc: true
use-oval: true
groupId: com.example.cubby.test
artifactId: cubby-test
version: 1.0-SNAPSHOT
package: com.example.cubby.test
 Y: : Y[Enter]

Maven2リポジトリのパスを表すクラスパス変数(M2_REPO)を追加します。

mvn eclipse:configure-workspace -Declipse.workspace=c:\workspace

プロジェクトのディレクトリに移動し、Eclipseの設定ファイルを生成します。

cd cubby-test
mvn org.apache.maven.plugins:maven-eclipse-plugin:2.7:m2eclipse

Tomcatプラグインの設定ファイルを生成します。

mvn sysdeo-tomcat:m2eclipse

Eclipseにインポート

Eclipseを起動し、生成したプロジェクトをインポート。

ファイル->インポート->一般->既存プロジェクトをワークスペースへ->次へ
->ルートディレクトリの選択の参照ボタン->c:\workspace\cubby-testを選択->完了

インポートしたら、Devloaderを使用するように設定変更。

プロジェクト右クリック->プロパティー->Tomcat->開発用クラスローダーのクラスパス
->org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINERにチェック->OK

Tomcatにコンテキスト追加。

プロジェクト右クリック->Tomcatプロジェクト->コンテキスト定義を更新

あとは、TomcatプラグインTomcatを起動して、http://localhost:8080/cubby-test/にアクセスすればいけるはず。