普通に書ける!

ちょっと前まで,普通に「蛯原友里ちゃん」と書くと,「蛯原友里」ではなく「里ちゃん」がキーワードになってしまっていたのですが,いつの間にか「蛯原友里」がキーワードになるようになってます.よかったよかった.
これで,「ちゃん」をキーワードよけするとかしなくても平気になりました.
っていうか,それを忘れたために気づいたのですが.
これでまた一歩前進です(なにが?).

プロかノンプロか

こっちも参考に.


えと,本題から外れてるとは思いつつ...
レビューが野球(ピッチャーとバッター)に例えられているのですが,ちょっと微妙に違和感を感じます.
レビューする人とされる人って,対戦相手なんですか?(^^;
同じチームの一員じゃないのかなぁ?
要するに草野球チームの中にただ一人プロレベルの選手が混じっていることの悲劇なんでしょうけれど,草野球とはいえ勝つことがチームの目的であるなら,キャッチャーさえ捕れない剛速球を投げるってのはいかがなものかと.
三振とっても振り逃げで出塁されちゃうよ.(^^;
その後もパスボールで進塁されて,ノーヒットなのに大量失点...絵に描いたようなピッチャーの独り相撲が目に浮かびます.守ってる野手もリズムに乗れなかったりやる気なくなったりで,逆転も期待できなくなっちゃいそう.
それで試合に勝てるわけがないと思われるのですが,そういう目的(チームの勝利)を見失っている剛速球ピッチャーって,それでもプロって呼べるのでしょうか?
野球でもサッカーでもバスケでもF1でも,結局はチームの勝利に貢献できる選手こそが一番評価されるのであって,自分の実力を発揮する,あるいは見せつけることが最大の目的だったら,それはプロじゃなくてセミプロなどと呼ばれるアマチュアじゃないかなぁ,と思ったりしました.
それでレビューですが,それもまたプロジェクトの成功のために行うわけですよね.そのために問題点を指摘したり,同じ間違いを繰り返さないようにアドバイスしたりするわけですよね.
であるなら,誰も捕れない剛速球を投げるのもねぇ.剛速球が投げれないからってマウンドに上がりたがらないのもねぇ.
プロジェクトのメンバーの能力を考慮して,その上でプロジェクトの成功のためにできることってたくさんあるんじゃないのかなぁ.そのために剛速球を封印しても,それを手抜きとはいわないと思う.
あぁ,なんか偉そうなことを書いてしまった.そういう私は間違いなくアマチュアです.私がめいっぱい剛速球(当社比)を投げつけたせいで,退職して地元へ帰ってしまった若者もいたなぁ... 心より恥じる.

「プレミアの巣窟」

いやー,満足,満足\(^o^)/
恋するハニカミ!」でのもどかしさを吹き飛ばしてくれる,蛯原友里ちゃん大フィーチャーのこの番組,今週もよかったです.堪能しました.
友里ちゃんの今日の衣装は白っぽいキャミの上にかなりゆったーりとしたピンクのブラウス(っていうの?),それにロールアップのデニム.色あわせは今日のハニカミと同じですね.やっぱりピンク好きなのかな.白っぽくて薄い大小二枚の円盤(?)がつながったピアス付けてます.足元はあまり映らなかったのでよく分からず.無念だ.
さすがにこの番組も3回目ということで,友里ちゃんも随分と緊張感がほぐれてきた様子.ほどよくリラックスした感じに見えます.でも,イベントの紹介(原稿読み)はまだまだスムーズとは言い難く,噛み噛みです.(^^; 今後の成長ぶりが楽しみです.
そしてこの番組の目玉(?),「Premiere Flush」ですが,先週までは透明なフレームの眼鏡だったのですが,今回は薄い紫のフレーム,しかもチェーン付きというややコミカルな眼鏡で変身です.そのためか,先週までのクールで大人っぽさを強調したキャラではなく,ちょっと意地悪(?)っていうか毒舌なキャラみたい.(^^; いやぁ,いろいろな友里ちゃんが見られてうれしいっす.
で,最初の情報の紹介で...

アバの大ヒットナンバーでつづる劇団四季の超人気公演が先日,とてつもない記録をじゅろつ,じゅりゅつ,樹立した模様です.

ちょっと舌が回らなかったみたい.(^^; それでちょっと照れ笑い? それとも苦笑い? の笑顔がなかなかよかったです.
このコーナーの最後,「ハッスル3」というプロレスイベントを紹介した後の友里ちゃんのセリフ...

仕事の厳しさに弱音を吐いている新社会人諸君,この真剣勝負を見て,根性叩き直してください!

(^^; 友里ちゃんに叩き直して欲しいです,ハイ.
いやぁ,満足の20分でした.っていうか,この日記を書いている間に2回見直したので,合計1時間,堪能しまくりました.あぁ,これでまた1週間生きていける!
しかし気がかりなことが.テレビ番組の情報誌によると,次週5/7はゴルフのダイジェスト(?)があり,「プレミアの巣窟」はお休みっぽい... 無念だ.(ToT)
しょうがない,「恋するハニカミ!」に期待しよう... 期待できるかなぁ? 期待できないか.無念だ.

お仕事スタイル

今日もお仕事なんですよ,ということをアピールしたいのでボールドにしてみるてすと.
あぅ,見出しはデフォでボールドでしたか.心より恥じる.

Spring Framework 入門記 JDBCその4 JdbcTemplate 残り

GW中ということもあり,ちょっと中だるみ気味の入門記です.
ところで,この入門記は一応「Reference Documentation」に沿って学習しています.そのつもりでした.しかし...
Chapter 8. DAO support」を完全に見落としていたことに気づいてしまいました.無念だ.別にたいした内容じゃないからすっ飛ばしたとかいう訳ではなく,なぜか見落としていたのです.心より恥じる.
Sprint Padへ持っていくときにこっそり追加することにしようかな...


さぁ,気を取り直していきましょう! っていうか,気合を入れましょう!
... ごめん,気合が抜けちゃってます.無念だ.
本来さくっと終わらせるはずだったJdbcTemplateなのですが,油断してquery()の仲間たちをチェックしてしまったものですから,勢いでupdate()の仲間たちも見てしまったのが痛い.これでexecute()の仲間たちを無視したら,いかにも手抜きではないですか.
そんなわけで,今回はJdbcTemplateの残りのメソッドを見ることにします.


まず,本来なら前回見ておくべきだったのが,

    • int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss)

です.一応update系なので.いわゆるバッチ更新をやってくれるメソッドですね.
JDBCドライバがバッチ更新をサポートしていない場合は,普通にPreparedStatement#execute()を呼び出してくれます.こういうのは気が利いていていいかも.
BatchPreparedStatementSetterは,次のメソッドを持っています.

    • int getBatchSize()
    • void setValues(PreparedStatement ps, int i)

最初のメソッドが返した回数だけsetValues(PreparedStatement, int)が呼び出されるわけですね.
setValues(PreparedStatement, int)の第二引数のiは,バッチアップデート中の何件目かを示す,0から始まる値です.
簡単に使えそうですね.


次はexecute()の仲間たちを見ていきます.
実はこれまでのお試しコードでも,create tableするために

    • void execute(String sql)

をこっそりと使っていたのですが,これはもう,そのまんまSQLを実行してくれるというだけのメソッドです.
で,いつものように,このSQL文字列からPreparedStatementを作って実行してくれるわけですが,その部分をカスタマイズできるように,

    • Object execute(final String sql, PreparedStatementCallback action)
    • Object execute(PreparedStatementCreator psc, PreparedStatementCallback action)

というメソッドが用意されています.
PreparedStatementCallbackというinterfaceは,次のメソッドを持っています.

    • Object doInPreparedStatement(PreparedStatement ps)

JdbcTemplateが用意したPreparedStatementexecute()が呼び出される前に,好きなように細工できるというわけです.PreparedStatementSetter#setValues(PreparedStatement)と同じように使えるわけですね.っていうか,どちらも引数がPreparedStatementで戻り値がObjectになっていたりして,なぜ異なったinterfaceを用意しなければならなかったのか,いまひとつ分かりません.
しかもですね,これまで見てきたJdbcTemplate#update(String, PreparedStatementSetter)などですが,実はPreparedStatementSetterPreparedStatementCallbackにラップされて呼び出されていたみたいです.うーみゅ.相変わらず太った凝ったつくりになってるなぁ.ま,GW中だからいっか.


JdbcTemplate#execute()の仲間はこれだけではありません.ストアドプロシジャ/ファンクションを呼び出すために,次のメソッドが用意されています.

    • Object execute(final String callString, CallableStatementCallback action)
    • Object execute(CallableStatementCreator csc, CallableStatementCallback action)

CallableStatementCallbackCallableStatementCreatorの役割はそれぞれ,PreparedStatementCallbackPreparedStatementCreatorと同じで,PreparedStatementではなくCallableStatementを扱うのが違うくらいです.ということで詳細は省略.心より恥じる.


最後に,

    • Map call(CallableStatementCreator csc, List declaredParameters)

というメソッドがあります.これもストアドを呼び出すためのメソッドなのですが,ResultSetを戻すようなストアドを扱うためのものみたい.やべぇ,そんなの使ったことないよっ! ということでスキップです.無念だ.


これでJdbcTemplatepublicなメソッドは一通り見たことになります.いや,文句なしに見たんです! 見たことにしてくださいっ!
ということでお試しコーナーです.あまりやる気しない感じなのですが,OFF会などやむにやまれぬ事情ががある場合を除いてお試しするのがこの日記のお約束なのです.
ということで,今回はバッチ更新を使ってみましょう.
Propertiesネーム・バリュー・ペアをまるっとinsertするように,いつものFooを修正します.

package study;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;

public class Foo {
    private DataSource dataSource;
    private Properties properties;
    public DataSource getDataSource() {
        return dataSource;
    }
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    /**
     * @@org.springframework.transaction.interceptor.DefaultTransactionAttribute()
     */
    public void createTable() {
        JdbcTemplate jt = new JdbcTemplate(dataSource);
        jt.execute("create table pair (key varchar, value varchar, primary key(key))");
    }
    /**
     * @@org.springframework.transaction.interceptor.DefaultTransactionAttribute()
     */
    public void insert() {
        final Iterator it = properties.entrySet().iterator();
        JdbcTemplate jt = new JdbcTemplate(dataSource);
        jt.batchUpdate("insert into pair (key, value) values(?, ?)", new BatchPreparedStatementSetter() {
            public int getBatchSize() {
                return properties.size();
            }
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Map.Entry entry = (Map.Entry) it.next();
                ps.setString(1, (String) entry.getKey());
                ps.setString(2, (String) entry.getValue());
            }
        });
    }
    /**
     * @@org.springframework.transaction.interceptor.DefaultTransactionAttribute(readOnly=true)
     */
    public Properties query() {
        JdbcTemplate jt = new JdbcTemplate(dataSource);
        return (Properties) jt.query("select * from pair", new ResultSetExtractor() {
            public Object extractData(ResultSet rs) throws SQLException {
                Properties props = new Properties();
                while (rs.next()) {
                    props.put(rs.getString("key"), rs.getString("value"));
                }
                return props;
            }
        });
    }
}

忘れずにAttribute Compilerでコンパイルします.
次に定義ファイル.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd"
>
<beans>
    <bean id="autoProxyCreator" 
        class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <value>foo</value>
        </property>
        <property name="interceptorNames">
            <value>transactionInterceptor,trace</value>
        </property>
    </bean>

    <bean id="foo" class="study.Foo">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="properties">
            <props>
                <prop key="Yuri">Ebihara</prop>
                <prop key="Akiko">Yada</prop>
            </props>
        </property>
    </bean>
</beans>

foopropertiesというプロパティにinsertするデータを設定しています.
最後に実行クラス.いつもとあまり変わりません.

package study;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.context.ApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;

public class Main {
    public static void main(String[] args) {
        try {
            BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance();
            BeanFactoryReference ref = locator.useBeanFactory("context");
            ApplicationContext context = (ApplicationContext) ref.getFactory();

            Foo foo = (Foo) context.getBean("foo");
            foo.createTable();
            foo.insert();
            System.out.println(foo.query());

            ref.release();
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

こいつを実行!!!!

 BEGIN study.Foo#createTable()
 - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
 - Creating shared instance of singleton bean 'DB2'
 - Creating shared instance of singleton bean 'HSQL'
 - Creating shared instance of singleton bean 'MS-SQL'
 - Creating shared instance of singleton bean 'MySQL'
 - Creating shared instance of singleton bean 'Oracle'
 - Creating shared instance of singleton bean 'Informix'
 - Creating shared instance of singleton bean 'PostgreSQL'
 - SQLErrorCodes loaded: [HSQL Database Engine, Oracle, Microsoft SQL Server, Informix Dynamic Server, PostgreSQL, MySQL, DB2]
 - Looking up default SQLErrorCodes for DataSource
 - Database Product Name is HSQL Database Engine
 - Driver Version is 1.7.1
 END study.Foo#createTable() : null
 - Initiating transaction commit
 BEGIN study.Foo#insert()
 - Looking up default SQLErrorCodes for DataSource
 - Database product name found in cache {17131806}. Name is HSQL Database Engine
 END study.Foo#insert() : null
 - Initiating transaction commit
 BEGIN study.Foo#query()
 - Looking up default SQLErrorCodes for DataSource
 - Database product name found in cache {17131806}. Name is HSQL Database Engine
 END study.Foo#query() : {Yuri=Ebihara, Akiko=Yada}
 - Initiating transaction commit
 {Yuri=Ebihara, Akiko=Yada}

ということで,うまく動いたように見えます.これで,だらだらと続いてしまった退屈なJdbcTemplateを終わりにします.
最後に,バッチ更新のサンプルでありながらHSQLDBを使っているために,実際にはバッチ更新が行われていないことを... 心より恥じる.

「恋するハニカミ!」

主役二人のデートは素晴らしかったのですが...
蛯原友里ちゃんの出番はやっぱりちょびっとだけ.(;_;)
でも,退屈そうな表情ばかり拾われていた先週よりも,今週の方が笑顔が多かったのでよしとしよう.
ちなみに今週の衣装はピンクのベアトップにデニム,靴はシルバーっぽかった.ピアスはしてなくて,シルバーのネックレスっていうの? ペンダントっていうの? を付けてました.
それにしてもなー,チラッと映るのを待ちながら30分テレビにかじりついているってのも辛いなー.生殺しって感じ?
そうか,Mになればいいのか! そうすれば「プレミアの巣窟」の「Premiere Flush」で,ますます友里ちゃんに叱られたくなる!
うーみゅ,ちょっとアホなこと書きすぎてる... 心より恥じる.