tanigonのS2部屋

メイン日記はこちら(tanigonの日記)

2005-07-07

[] レスポンス出力内容の検証

S2TestCaseでgetResponse()すると MockHttpServletResponseがもらえる。

テスト対象のクラスが、HttpServletResponseからWriterを取得して何かしら出力するとき、その内容を検証するなら以下のようなコードがテストケースの中にはいる。

.
.
MockHttpServletResponse response = getResponse();
String actualOutput = response.getWriter().toString();
assertEquals("出力内容が不正", expectedOutput, actualOutput);
.
.

MockHttpServletResponseのgetWriterは SPrintWriterというクラスを返すようになっている。SPrintWriterは StringWriterをかぶせたもので、toString()すると StringWriter#toString()、つまり今まで書いたもののStringが帰ってくるのでテストが出来るというわけですね。

痒いところにまで手が届きまくりで使いやすさ抜群。最近.diconとかincludeしなくても S2TestCase使ってますね。。

ValjeanValjean2012/02/16 19:01In the complicated world we live in, it's good to find simple soltuinos.

eneorymfeneorymf2012/02/17 02:45fk5m1L <a href="http://dhnrfqdigfwj.com/">dhnrfqdigfwj</a>

tuoccietuoccie2012/02/22 02:15nVRoow <a href="http://ygqrbrhbkbgp.com/">ygqrbrhbkbgp</a>

2005-03-30

というわけで

うちの会社でまた1つ開発プロジェクトリリースマイルストンを迎えました。今回はこんな感じみたいです。

  • DAOは全部S2Dao
    • S2Daoを使ったおかげで sqlパッケージ依存している個所がゼロ(!)
    • Daoのimplはゼロ
    • 故に、使っているメトリクスプラグインでは DAOの「規模」は 0step.
    • 複雑な問い合わせもあったけど基本的にSQLファイルもゼロ (QUERYアノテーションに直書き)

開発チームは、SQLを書けない・読めない人は一人もいなかった。つまりDB技術者Java技術者のような住み分けは必要ではなかった。にもかかわらず、開発メンバーのほぼ全員が S2Daoによって救われた面が多かったようです。

このケースで特に思うのは

  • 全部S2Daoで implなし ResultSetなしはすぐに出来る

ということか。反面開発チームが挙げた問題点は

ということでした。なるほど。MySQLでいう LIMIT OFFSETですか。Oracleの場合

SELECT ROWNUM hoge, sq.* from (SELECTの元SQL) sq WHERE hoge>...

みたいな感じのものがパターンなんですが、このへんをもっと共通関心事として提供してあげたら評判が良くなるのかしらん。

「全S2Dao」のパイロットケースとしてはなかなか残したものも大きかったようです。

koichikkoichik2005/03/31 03:14S2Pager がありますよ.
http://d.hatena.ne.jp/agt/20050320#p1
近々 S2Dao 本体に取り込まれるはずですが.

SamuelSamuel2012/02/18 12:32That kind of thiiknng shows you're on top of your game

zskaflzhhzskaflzhh2012/02/20 00:10WCr6uT , [url=http://ipncewhtqzgt.com/]ipncewhtqzgt[/url], [link=http://dykklajgbivs.com/]dykklajgbivs[/link], http://qhgeybfirszp.com/

mpaemurfgmpaemurfg2012/02/26 02:3816JyZp <a href="http://dilhfnrmahdm.com/">dilhfnrmahdm</a>

2005-03-02

[] SQLファイルが嫌な人へ

SQLファイルがキライ、もしくはSQLファイルを嫌がる人がいたりして、導入が大変な人へ。

QUERYアノテーションには WHERE句以降のみ書くのが普通みたいですが、SELECTで始まる文字列を書いておくとSQLファイル同等の事が出来ます。

public static final String hoge_ARGS = "bean,foo,bar";
public static final String hoge_QUERY = 
   "select * from hoge a, fuga b where a.row = /*bean.no*/ " +
        " and b.kindid = a.kindid ";

とかなんとか。

まあ、使い方が正しいかどうか考える必要もありますが。

PKのないテーブルにupdate,deleteする時なんかは自動生成出来ないのでSQLファイル作る必要がありますが、このときは_QUERYは使えないと思います。たぶん。

higayasuohigayasuo2005/03/02 18:27IDアノテーションassignedで偽のPKを教えてあげれば出来るかも。

tanigontanigon2005/03/02 18:40おお、なるほど... 試してみます!

METALLICMETALLIC2012/02/18 13:25That's going to make things a lot eiaesr from here on out.

omvoeofomvoeof2012/02/19 19:18V9rDjJ <a href="http://kzumgzukdrec.com/">kzumgzukdrec</a>

wfqldpnvgwfqldpnvg2012/02/20 00:25EzSFKL , [url=http://uszujhpektpu.com/]uszujhpektpu[/url], [link=http://tyxotvakitlz.com/]tyxotvakitlz[/link], http://gzqiccvetsrs.com/

prqlhaprqlha2012/02/26 03:277uwatP <a href="http://ksnundjwkwyb.com/">ksnundjwkwyb</a>

NicoNico2013/11/23 11:03Me dull. You smart. That's just what I nedede.

KateKate2013/11/24 02:41That's a clever answer to a tricky <a href="http://xswyrvyqa.com">quetoisn</a>

ShafikriShafikri2013/11/25 04:48You really found a way to make this whole precoss easier. http://pltfjheqdx.com [url=http://wdsakyaqcqx.com]wdsakyaqcqx[/url] [link=http://hazgrofz.com]hazgrofz[/link]

TapiwaTapiwa2013/11/25 11:14Pleasing you should think of <a href="http://ekqpguh.com">sominhetg</a> like that

TetrisTetris2013/11/26 16:19Normally I'm against killing but this article sleeghturad my ignorance. http://djkhrwxe.com [url=http://ndulnaocku.com]ndulnaocku[/url] [link=http://crthppcozob.com]crthppcozob[/link]

2004-11-24

あっちにも書いたけども

メインのはてなダイアリのエントリを受けて...

実務的には遭遇しそうなトラブルではあるがどう考えてもOracleドライバ責任…なんだよなあ。しかし、この「責任」の発想に固執するとたとえば「~」文字が化けちゃうOracleのShift-JISマッピングの問題とかもその通りなわけで、いかに解決するか、のみを考えるのが真に実務的なのかもしれない。

S2JDBCでResultSetのハンドラを自分で実装してやって ClobとかならStringに変換してやればいいのかしらん...?

StringType#getValue()で

return resultSet.getString(columnName);

がCLOB列に対して呼ばれている。ふむ、つまりOracleのJDBCドライバ(Thin)は CLOB列に対してgetStringするとnullを返してるわけだな。このへんの仕様ドライバ依存だしなあ... CLOB列に対してgetString()したときにStringに変換するあたりの処理は入れてくれてもよさそうなもんなんだけど…といってても仕方ないので…どうなんだろう。DTOをsetObject()になるように変えてしまうとか...? むぐぐ

seasar-usersでLOBについて書いてあったような気がするけどこの件とは似ているが CLOBはStringにできますよね、というところがポイントなので少し違うか (MLのほうはBLOBだった気がする)

急場しのぎ

public static final String hoge_COLUMN = "HOGE";
  を
public static final String hogeAsClob_COLUMN = "HOGE";

にする。で、

    private String hoge;
    
    public void setHoge(String a) { ... }
    public void setHogeAsClob(Clob clob) throws SQLException {
        this.setHoge(clob.getSubString(1L, (int)clob.length()));
    }

とする。これで set名前As型(型 a); という形式でDAOにアクセスしてもらえるので、引数型を見たときにClobなので getObject()してコールしてもらえる、というわけです。

急場しのぎというか結構アリな気もしてきた。こういう解決策は全然ありかも?? (インピーダンスミスマッチに近い問題の気がする)

追っかけてないけど insert文自動生成のときにヤバいかもしれない... うちはいまinsert文はSQLファイルになっているので...うーむ?

と思ったらinsert updateで大コケ

OracleのJDBCドライバ

 PreparedStatement#setString(1, "ながーーーい文字列");

とかすると、

java.sql.SQLException: データ・サイズがこの型の最大サイズを超えています。: 145000

とか出るんですよ。うう。OracleSQLでCLOB型の列 hoge に対してinsertするときは

  insert into tablename(hoge) values('文字')

でいけるんですよ。暗黙の型変換。で、短いときは JDBCからでも #setString() でもいけるんです。ところが長くなると…

これは暗黙のうちにVARCHAR2(最大4000)の制約を受けてるのか...

だとしたら、Clob格納はOracleオススメのClobロケータ取得後のAsciiOutputStreamに対してwriteするという方法…か。つまり一度Selectしないとダメか。ぐはぁーーー!!

insert,updateでのさらなるドハマリ

仕方ない、interfaceS2Daoを使うんじゃなくて abstractclassS2Daoをカマせよう... abstractclassではCLOBがらみのinsert,update系だけ実装してあとはS2DaoInterceptorがやってくれる…

ということでやりました。abstractクラスに DataSourceをinjectionしてもらい、.diconに arg とか書き込んで初期化してもらいます。

んでupdate,insertでは

  • BasicSelectHandlerとか使って SELECT CLOB列 FROM ... WHERE ... FOR UPDATEなSQL文を投げる(Oracle様ご推奨...(皮肉))
  • 帰ってくる値はLOBロケータなのでこれに作業を行う

と、ここまでは良かった。ところがですよ、ふつーに

Writer stream = clob.setCharacterStream(1);
stream.write(song.getLooooooongText());
stream.flush();
stream.close();

なんてすると、Oracle様は「サポートされていない機能です」なんて言うんですよ。えっ、でもjava.sql.Clobって他に書き込みする方法ないんじゃない? なにしろマニュアルには

重要: JDBC 2.0 の仕様では、PreparedStatement のメソッド
setBinaryStream() およびsetObject() を使用して、ストリーム値
をBLOB として入力でき、また、PreparedStatement のメソッド
setAsciiStream()、setUnicodeStream()、
setCharacterStream() およびsetObject() を使用して、ストリーム
値をCLOB として入力できると規定されています。これにより、LOB ロ
ケータを通さず、直接LOB データ自体にアクセスできます。
Oracle JDBC ドライバの実装では、この機能はリリース8.1.6 以上のデータ
ベースおよび8.1.6 以上のJDBC OCI ドライバを使用した構成でのみサ
ポートされます。その他の構成では、この機能を使用しないでください。
データが破損する可能性があります。

なんて書いてあるんですよ。Thinドライバだよ、こっちは(泣)

で、Oracle様がどうしろ、といってるかというと、

ということなんだそうです。それでイケるならなんでラッパーしてくれないの...(ぶちぶち)

結局どうなるかというと、

            Writer stream = null;
            if (clob instanceof oracle.sql.CLOB) {
                stream = ((CLOB)clob).getCharacterOutputStream();
            } else {
                stream = clob.setCharacterStream(1);
            }
            stream.write(song.getLyricText());
            stream.flush();
            stream.close();

オーノー。

S2Daoの恩恵にあずかれない、コードは生書き、しかもメチャメチャ油っこい…なにかいい方法はないものだろうか...

それとも根本的に大きな間違いをしているのだろうか? 私はどうもOracleが好き勝手やってるようにしか見えないのだが...

S2NazoWeb

NanoWeb万歳の私としては期待大。これ、そういうことですよね? > takaiさん

厳格さ、自由度、プロセスの性質、とかなんとかは基本的に対象物の性質に依存すると思うので、NanoWebのほうが目的を簡単に達成できるケースもあれば、StrutsだとかJSFとかのほうが目的を達成できるケースもあると思います。個人的には前者の状況に対して重いフレームワークとかXML地獄を適用してしまうケースのほうがイタイ目にあっているので、超軽量なんでもありフレームワーク(ただし負荷には弱いし、ちゃんとしたシステムを作る上では生産物の整合性や一貫性を取るのが大変)に期待してしまうんです。

自分で作れよって自分に言い聞かせてたのですが、nanoWebの移植してたらNazoWebを見つけてしまったのですよ...

higayasuohigayasuo2004/11/24 20:57オラクル側は、BLOBにして、ダミーのプロパティを追加し、byte[]とStringの相互変換をする。

tanigontanigon2004/11/24 20:59なるほど... BLOBに対する byte[]のサポートはありますもんね。byte[]とStringの変換はjavaのレイヤでするわけですね。キャラクタセットとかの扱いも考えないといけないのか...

2004-11-01

tanigon20041101

沖縄みやげだそうで

もはやSeasarファミリがなくなると開発がたちゆかなくなりそうな状況の人たちが沖縄社員旅行にいって買った土産の写真

がんばれ、しーさー。

ってのもあるけど、おれもがんばらなくては。多忙言い訳にしていては負のスパイラル突入

DomingoDomingo2007/07/16 08:06http://8021dafeaff94ac87278f38fe6a01c11-t.zjdicn.org <a href="http://8021dafeaff94ac87278f38fe6a01c11-h.zjdicn.org">8021dafeaff94ac87278f38fe6a01c11</a> [url]http://8021dafeaff94ac87278f38fe6a01c11-b1.zjdicn.org[/url] [url=http://8021dafeaff94ac87278f38fe6a01c11-b2.zjdicn.org]8021dafeaff94ac87278f38fe6a01c11[/url] [u]http://8021dafeaff94ac87278f38fe6a01c11-b3.zjdicn.org[/u] 9b90290ebc5b707b8f998fd2e6478888

JaylonJaylon2012/02/16 01:11I never thought I would find such an evreaydy topic so enthralling!

PriyaPriya2012/02/18 13:32Nothing I could say would give you undue cdeirt for this story.

ebftxmemxdlebftxmemxdl2012/02/19 19:21hcVxqH <a href="http://iobgnnixhjly.com/">iobgnnixhjly</a>

friyjmkloekfriyjmkloek2012/02/19 23:44KEpPzO , [url=http://ttohkojxdrmb.com/]ttohkojxdrmb[/url], [link=http://rtmhpzdlrqpb.com/]rtmhpzdlrqpb[/link], http://caqraytvcfqw.com/

ciiqdseciiqdse2012/02/26 03:14dLH6Yi <a href="http://fpicmrgmltkl.com/">fpicmrgmltkl</a>