日本語

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=26967&forum=7&9
これを見て、今までテーブル名やカラム名に日本語を使ったことないなーと思って。

http://arton.no-ip.info/diary/20051027.html#p02

あと以前にこれもよんでたので、
S2とS2Daoでどこまで日本語が使えるか、ちょっと実験。

テーブルは日本語で

CREATE TABLE 社員(
    番号 NUMERIC(4) NOT NULL PRIMARY KEY,
    名前 VARCHAR(10)
);

うまく作れた。HSQLDBは日本語でもOKみたい。


まずテストクラスをつくらないと。極力日本語を使うようにして

package 例.日本語;

import java.util.List;

import org.seasar.extension.unit.S2TestCase;

public class 社員ダオTest extends S2TestCase {

    private 社員ダオ ダオ;

    public void setUp() {
        include("全ダオ.dicon");
    }

    public void test全部ちょうだいTx() {
        readXlsWriteDb("社員データ.xls");
        List 結果 = ダオ.全部ちょうだい();
        assertNotNull(結果);
        assertEquals(3, 結果.size());
    }

}

とりあえずこんな感じにした。


次はEntityクラス

package 例.日本語;

public class 社員 {

    private int 番号;

    private String 名前;

    public int get番号() {
        return 番号;
    }

    public void set番号(int 番号) {
        this.番号 = 番号;
    }

    public String get名前() {
        return 名前;
    }

    public void set名前(String 名前) {
        this.名前 = 名前;
    }

    public String toString() {
        return "[" + 番号 + "," + 名前 + "]";
    }

}

そして、Dao

package 例.日本語;

import java.util.List;

public interface 社員ダオ {

    Class BEAN = 社員.class;

    List 全部ちょうだい();

}

そういえば、ここまでコンパイルエラーでてないから日本語でも大丈夫なんだー。

次は全ダオ.diconファイル。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
  "http://www.seasar.org/dtd/components21.dtd">
<components>
  <include path="dao.dicon"/>
  <include path="aop.dicon"/>

  <component name="daoInterceptorChain"
      class="org.seasar.framework.aop.interceptors.InterceptorChain">
    <initMethod name="add"><arg>aop.traceInterceptor</arg></initMethod>
    <initMethod name="add"><arg>dao.interceptor</arg></initMethod>
  </component>

    <!-- auto registration -->
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"例.日本語"</arg>
      <arg>".*ダオ"</arg>
    </initMethod>
  </component>
  <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
    <property name="interceptor">daoInterceptorChain</property>
    <initMethod name="addClassPattern">
      <arg>"例.日本語"</arg>
      <arg>".*ダオ"</arg>
    </initMethod>
  </component>

</components>

順調順調。

あと、社員データ.xlsを忘れないように作って

番号 名前
10 太郎
11 次郎
12 三郎

これで、テストが動くはず。
レッドバー。。。

org.seasar.framework.aop.javassist.CannotCompileRuntimeException: 
[ESSR0017]例外が発生しました。
理由はjavassist.CannotCompileException: [source error] syntax error
	at org.seasar.framework.aop.javassist.AbstractGenerator.createMethod(AbstractGenerator.java:262)
	at org.seasar.framework.aop.javassist.AbstractGenerator.createMethod(AbstractGenerator.java:246)

javassistって日本語ダメなのかなー?
よくわからないと思うけど、ちょっとみよーかなーと思ったら、
3.1RC2ってのがあった。
これに入れ替えて再度実行。


グリーンバー!!


やっぱり、動くんだー。


今度は一気にテストを追加して

package 例.日本語;

import java.util.List;

import org.seasar.extension.unit.S2TestCase;

public class 社員ダオTest extends S2TestCase {

    private 社員ダオ ダオ;

    public void setUp() {
        include("全ダオ.dicon");
    }

    public void test全部ちょうだいTx() {
        readXlsWriteDb("社員データ.xls");
        List 結果 = ダオ.全部ちょうだい();
        assertNotNull(結果);
        assertEquals(3, 結果.size());
    }

    public void test全部ちょうだいだけどないTx() {
        List 結果 = ダオ.全部ちょうだい();
        assertNotNull(結果);
        assertEquals(0, 結果.size());
    }

    public void testこれちょうだいTx() {
        readXlsWriteDb("社員データ.xls");
        社員 結果 = ダオ.これちょうだい(11);
        assertNotNull(結果);
        assertEquals(11, 結果.get番号());
        assertEquals("次郎", 結果.get名前());
    }

    public void testこれちょうだいだけどないTx() {
        readXlsWriteDb("社員データ.xls");
        社員 結果 = ダオ.これちょうだい(99);
        assertNull(結果);
    }

    public void test追加してTx() {
        社員 ある社員 = new 社員();
        ある社員.set番号(99);
        ある社員.set名前("追加太郎");

        ダオ.追加して(ある社員);
        社員 結果 = ダオ.これちょうだい(ある社員.get番号());
        assertNotNull(結果);
        assertEquals(ある社員.get番号(), 結果.get番号());
        assertEquals(ある社員.get名前(), 結果.get名前());
    }

}

ダオにもメソッドを追加

package 例.日本語;

import java.util.List;

public interface 社員ダオ {

    Class BEAN = 社員.class;

    List 全部ちょうだい();

    社員 これちょうだい(int 番号);

    void 追加して(社員 ある社員);

}

あと社員ダオ_これちょうだい.sqlも作ってテスト実行。


レッドバー。。。


「追加して」メソッドがダメみたい。select文になってる。。。
うーむ、社員ダオ_追加して.sqlを作って再度実行。

レッドバー。。。
やっぱりダメだ。。。


「追加して」メソッドを「insertして」メソッドに変更したら、グリーンバーになった。


恥ずかしくて回避方法を聞けないなー。ま、こんなとこにこだわっても仕方ないか。。。


[追記]
「追加して」メソッドをinsert処理として認識させる方法を教えてもらったので早速やってみる。

まず、DaoMetaDataImplをオーバーライドして

package 例.日本語;

import javax.sql.DataSource;

import org.seasar.dao.AnnotationReaderFactory;
import org.seasar.dao.impl.DaoMetaDataImpl;
import org.seasar.extension.jdbc.ResultSetFactory;
import org.seasar.extension.jdbc.StatementFactory;

public class 日本語DaoMetaDataImpl extends DaoMetaDataImpl {

    public 日本語DaoMetaDataImpl(Class daoClass, DataSource dataSource,
            StatementFactory statementFactory,
            ResultSetFactory resultSetFactory,
            AnnotationReaderFactory annotationReaderFactory) {
        super(daoClass, dataSource, statementFactory, resultSetFactory,
                annotationReaderFactory);
    }

    protected boolean isInsert(String methodName) {
        if (methodName.startsWith("追加")) {
            return true;
        }
        return super.isInsert(methodName);
    }

}

とりあえず、追加のみ対応。


そしてこのDaoMetaDataを生成するFactoryを定義。
これはDaoMetaDataFactoryImplの内容をほぼそのまま利用。

package 例.日本語;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.seasar.dao.AnnotationReaderFactory;
import org.seasar.dao.DaoMetaData;
import org.seasar.dao.DaoMetaDataFactory;
import org.seasar.extension.jdbc.ResultSetFactory;
import org.seasar.extension.jdbc.StatementFactory;

public class 日本語DaoMetaDataFactoryImpl implements DaoMetaDataFactory {

    protected Map daoMetaDataCache_ = new HashMap();

    protected DataSource dataSource_;

    protected StatementFactory statementFactory_;

    protected ResultSetFactory resultSetFactory_;

    protected AnnotationReaderFactory readerFactory_;

    public 日本語DaoMetaDataFactoryImpl(DataSource dataSource,
            StatementFactory statementFactory,
            ResultSetFactory resultSetFactory,
            AnnotationReaderFactory readerFactory) {

        dataSource_ = dataSource;
        statementFactory_ = statementFactory;
        resultSetFactory_ = resultSetFactory;
        readerFactory_ = readerFactory;
    }

    public synchronized DaoMetaData getDaoMetaData(Class daoClass) {
        String key = daoClass.getName();
        DaoMetaData dmd = (DaoMetaData) daoMetaDataCache_.get(key);
        if (dmd != null) {
            return dmd;
        }
        dmd = new 日本語DaoMetaDataImpl(daoClass, dataSource_, statementFactory_,
                resultSetFactory_, readerFactory_);
        daoMetaDataCache_.put(key, dmd);
        return dmd;
    }

}

最後にdao.diconを

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="dao">
	<include path="j2ee.dicon"/>
	<component
		class="org.seasar.dao.impl.FieldAnnotationReaderFactory"/>
	<component
		class="例.日本語.日本語DaoMetaDataFactoryImpl"/>
	<component name="interceptor"
		class="org.seasar.dao.interceptors.S2DaoInterceptor"/>
</components>

このように修正して実行したら、グリーンバーになった!!

「追加して」メソッドも正常に動作したー!!

まとめ

日本語でも一応動いた。


クラス名と変数名をいかに区別するか考えないといけない。「社員」クラスを使う場合は「ある社員」とか「社員さん」とかがいいと思う。


自分みたいに英語に弱い人は、「ちょうだい」メソッド、「して」メソッド、「ですか」メソッドみたいな感じでわかりやすい。


実際は使わないと思うけど、メソッド名に日本語を使うのはちょっといいかもって思った。