Category Archives: MySQL

[SAStruts]S2JDBCでJOINのやり方をいつも忘れるからメモ

SAStrutsでJOINを行なう際、どう書くか毎回忘れてしまう。

単純なテストを以下に記す。



■データベースのスキーマ

CREATE DATABASE db_test;
USE db_test;

CREATE TABLE channels (
	channel_id INTEGER NOT NULL AUTO_INCREMENT
	, title TEXT NOT NULL
	, PRIMARY KEY (channel_id)
);

CREATE TABLE items (
	item_id INTEGER NOT NULL AUTO_INCREMENT
	, title TEXT NOT NULL
	, url VARCHAR(255) NOT NULL
	, channel_id INTEGER NOT NULL
	, PRIMARY KEY (item_id)
	, UNIQUE (url)
);

INSERT INTO channels (title) VALUES("情報考学 Passion For The Future");
INSERT INTO channels (title) VALUES("RwJ");

INSERT INTO items (title,url,channel_id) VALUES("無趣味のすすめ","http://www.ringolab.com/note/daiya/2009/07/post-1021.html",1);
INSERT INTO items (title,url,channel_id) VALUES("アイデア・スイッチ 次々と発想を生み出す装置","http://www.ringolab.com/note/daiya/2009/07/post-1023.html",1);
INSERT INTO items (title,url,channel_id) VALUES("ベガーズ・イン・スペイン","http://www.ringolab.com/note/daiya/2009/07/post-1022.html",1);
INSERT INTO items (title,url,channel_id) VALUES("psコマンドはオプションに「-」がいらないみたい","http://blog.mikuriya.biz/archives/310",2);
INSERT INTO items (title,url,channel_id) VALUES("[SAStruts]Tomcat起動時に初回のみ呼び出す独自のクラスでデータベース接続","http://blog.mikuriya.biz/archives/171",2);
INSERT INTO items (title,url,channel_id) VALUES("[PHP]フレームワーク「CakePHP」のインストールと設定","http://blog.mikuriya.biz/archives/7",2);




■jdbc.diconを編集

今回は、MySQLを使用するので、そのあたりを編集する。

<components namespace="jdbc">
	...

	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"com.mysql.jdbc.Driver"
		</property>
		<property name="URL">
			"jdbc:mysql://localhost:3306/db_test"
		</property>
		<property name="user">"root"</property>
		<property name="password">""</property>
	</component>
	...
</components>




■channelsテーブルのクラス

package biz.mikuriya.entity;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "channels")
public class Channel {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public int channelId;

	public String title;

	@OneToMany(mappedBy = "parent") // Itemに定義する変数名がparentになる
	public List<Item> childs;
}




■itemsテーブルのクラス

package biz.mikuriya.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "items")
public class Item {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public int itemId;

	public String title;

	public String url;

	public int channelId;

	@ManyToOne
	@JoinColumn(name = "channel_id")
	public Channel parent; // Channel.itemsのmappedByの値と変数名を合わせる
}




■動作テスト用実行クラス

package biz.mikuriya;

import java.util.List;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import biz.mikuriya.entity.Channel;
import biz.mikuriya.entity.Item;

public class DBTest {
	private JdbcManager jdbcManager;

	/**
	 * データベース接続
	 */
	public DBTest() {
		SingletonS2ContainerFactory.init();
		S2Container container = SingletonS2ContainerFactory.getContainer();
		this.jdbcManager = (JdbcManager) container
				.getComponent(JdbcManager.class);
	}

	/**
	 * 普通にSELECT
	 */
	public void selectChannel() {
		System.out.println("CHANNELS************************************");

		List<Channel> channels = this.jdbcManager.from(Channel.class)
				.getResultList();

		for (Channel channel : channels) {
			System.out.println("\t" + channel.channelId + "\t" + channel.title);
			System.out.println("\t--------");
		}
	}

	/**
	 * 普通にSELECT
	 */
	public void selectItem() {
		System.out.println("ITEMS************************************");

		List<Item> items = this.jdbcManager.from(Item.class).getResultList();

		for (Item item : items) {
			System.out.println("\t" + item.itemId + "\t" + item.channelId
					+ "\t" + item.title + "\t" + item.url);
			System.out.println("\t--------");
		}
	}

	/**
	 * 一対多の構造で取得する場合
	 */
	public void joinOneToMany() {
		System.out.println("JOIN************************************");

		List<Channel> channels = this.jdbcManager.from(Channel.class)
				.innerJoin("childs").getResultList(); // JOINには、変数名を指定する

		for (Channel channel : channels) {
			System.out.println("\t" + channel.channelId + "\t" + channel.title);

			for (Item item : channel.childs) {
				System.out.println("\t\t" + item.itemId + "\t" + item.channelId
						+ "\t" + item.title + "\t" + item.url);
				System.out.println("\t\t--------");
			}

			System.out.println("\t--------");
		}
	}

	/**
	 * 一対一の構造で取得する場合
	 */
	public void joinOneToOne() {
		System.out.println("JOIN************************************");

		List<Item> items = this.jdbcManager.from(Item.class)
				.innerJoin("parent").getResultList(); // JOINには、変数名を指定する

		for (Item item : items) {
			System.out.println("\t" + item.itemId + "\t" + item.channelId
					+ "\t" + item.title + "\t" + item.url + "\t"
					+ item.parent.channelId + "\t" + item.parent.title);
			System.out.println("\t--------");
		}
	}

	public static void main(String[] args) {
		DBTest test = new DBTest();

		test.selectChannel();
		test.selectItem();

		test.joinOneToMany();
		test.joinOneToOne();
	}
}

Windows VistaにMySQLをインストールするのに4時間くらいかかった

最近ノートパソコンを購入したんだが、MySQLのインストールを試みたら

Windows Vistaならではのエラーが発生。Microsoftは悪の枢軸だ。間違いない。



一通り調べたところ以下の2サイトで解決できた。



■TaoSoftware

vista mysqlをインストール



■ひるの-SNSでは書けない-日記

[vista][MySQL]VistaへのMySQLインストールメモ1/3

[vista][MySQL]VistaへのMySQLインストールメモ2/3

[vista][MySQL]VistaへのMySQLインストールメモ3/3





これだけ見てもわからないところがあったので、手順に従い気になる点を書いとく。



■Visual Studioインストール時について

参考サイトで書かれている「mt.exe」を使用するには、Visual Studioをインストールする必要がある。

私の場合は「Microsoft Visual Studio 2008」をインストールした。



1.「Microsoft Visual Studio 2008」をダウンロードする。

2.ダウンロードしたisoファイルをイメージとしてDVDに書き込む。

3.書き込んだDVDを挿入し、インストールを行なう。

  よくわからなかったので、4種類(CE#,Basic,C++,Web Developer)すべてをインストールした。

※ここまでで2時間以上かかった。Vistaであるがためにだ。



■mt.exe実行時について

スタートメニューから「Visual Studio 2008 コマンドプロンプト」を開き、

参考サイトにあるコマンドを打ってみたが、エラーが発生。

> mt.exe -inputresource:"C:\Program Files\MySQL\MySQL Server 5.0\bin\MySQlInstanceConfig.exe" -out:"C:\hoge.txt"
mt.exe : general error c101008a: Failed to save the updated manifest to the file "C:\hoge.txt". "/;9LR&UW_』"

権限的に「hoge.txt」がCドライブ直下に書き込めないらしい。Vistaらしいウンコ仕様。

hoge.txtの書き込み先をユーザーディレクトリに変更して再度実行。

> mt.exe -inputresource:"C:\Program Files\MySQL\MySQL Server 5.0\bin\MySQLInstanceConfig.exe" -out:"C:\Users\mikuriya\hoge.txt"



無事成功。



hoge.txtをテキストエディタで開き、「asAdministrator」部分を

「requireAdministrator」に書き換えて保存。



参考サイト通りに以下のコマンドを実行するが、エラーが発生。

> mt.exe /manifest "C:\Users\mikuriya\hoge.txt" /outputresource:"C:\Program Files\MySQL\MySQL Server 5.0\bin\MySQLInstanceConfig.exe"
mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file
"C:\Program Files\MySQL\MySQL Server 5.0\bin\MySQLInstanceConfig.exe". "/;9LR&ULW_』



権限的に「MySQLInstanceConfig.exe」が上書きできないらしい。またVistaのウンコ仕様。

イラつくのでMySQLディレクトリ以下を権限ユルユルに。



ちなみに権限の変更はディレクトリを右クリックし、「プロパティ」→「セキュリティ」タブ。

「編集」ボタンで全ユーザーに対し「許可」に全部チェック。これでユルユル。



再度同じコマンドを実行してみると成功した。



あとはMySQLInstanceConfig.exeを実行すればインストールが完了する。

ググったところから数えればだいたい4時間くらいかかった。MySQLのインストールにだ。いらつく

Wikipediaのデータベースをインポート(英語版)

Wikipediaのデータベースをダウンロードできるということで、
データをインポートしてみた。

道のりが長かったため、時間があるときに試してもらうのがよいと思う。
以下のURLへ接続し、MySQLのdumpデータをダウンロードする。
http://download.wikimedia.org/enwiki/

■ダウンロード
試したのは、以下の日付のdumpデータ
http://download.wikimedia.org/enwiki/20070908/

# wget http://download.wikimedia.org/enwiki/20070908/enwiki-20070908-page.sql.gz
# wget http://download.wikimedia.org/enwiki/20070908/enwiki-20070908-categorylinks.sql.gz
# wget http://download.wikimedia.org/enwiki/20070908/enwiki-20070908-pagelinks.sql.gz
# wget http://download.wikimedia.org/enwiki/20070908/enwiki-20070908-redirect.sql.gz

■解凍

# gunzip enwiki-20070908-page.sql.gz
# gunzip enwiki-20070908-categorylinks.sql.gz
# gunzip enwiki-20070908-pagelinks.sql.gz
# gunzip enwiki-20070908-redirect.sql.gz

■データベース作成

# mysql -u root
mysql> CREATE DATABASE enwiki;
mysql> exit

■pageテーブルのインポート
enwiki-20070908-page.sqlをエディタで開き、
UNIQUE KEYである(`page_namespace`,`page_title`)を除去して保存。
http://d.hatena.ne.jp/dkfj/searchdiary?word=MySQL

# mysql -u root enwiki < enwiki-20070908-page.sql

データを登録するわけでもないので、
UNIQUE INDEXではなく、INDEXをつけて完成。

mysql> CREATE INDEX name_title ON page (`page_namespace`, `page_title`);

■redirectテーブルのインポート
特にエラーは発生しないので、通常通りにインポート

# mysql -u root enwiki < enwiki-20070908-redirect.sql

■categorylinksテーブルのインポート
普通にインポートすると以下のようなエラーが発生する。

ERROR 1071 (42000) at line 12: Specified key was too long; max key length is 1000 bytes

UNIQUE INDEXを作成するキーの合計バイト数が1000byteを超えているらしい。
http://www.zoids-fan.net/zoids/mtb/pc/linux/

そこでテーブル構造をいじる。
カラムcl_toの長さを255から240に変更。

(240 * 3) + (86 * 3) = 978

これで1000byteを超えないのでいけました。

# mysql -u root enwiki < enwiki-20070908-categorylinks.sql

■pagelinksテーブルのインポート
enwiki-20070908-categorylinks.sqlをエディタで開き、
UNIQUE KEY部分をKEYのみに編集。

そんでインポート

# mysql -u root enwiki < enwiki-20070908-pagelinks.sql

これがかなり時間がかかるので注意。

以上、後はWikipediaを遊んでください。