Apache Torqueについて

223 views

Published on

Apache Torque(あぱっち・とるく) について
Javaツール勉強会@福岡 2016/08
~データベースツールとかいろいろ~

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
223
On SlideShare
0
From Embeds
0
Number of Embeds
172
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Apache Torqueについて

  1. 1. Apache Torque について Javaツール勉強会@福岡 2016/08 ~データベースツールとかいろいろ~ 2016/08/26 TAKO
  2. 2. TAKO(たこ) 職業:個人事業主 はてなID:takopons Java とか PHP とかを使って仕事してます。 仕事場は自宅だったり取引先だったり。 近ごろは JavaScript, jQuery, Ajax, D3.js らへんで コーディングしてる時間が長いです(昨年比)。 最初は通信系のプログラマとしてデビューして Solaris の UNIX-C で通信プロトコルの実装を してました。普通に vi が使えます。 2 / 44
  3. 3. DB周りのフレームワークについて DBアクセス関連のミドルウェアやフレームワークには どんなものがあるの? 1. JDBC 2. EJB 3. O/Rマッピング(Hibernate, MyBatis, Torqueなど) 4. S2JDBC(Seasar2標準のDBアクセスフレームワーク) 5. Spring JDBC 6. JDO仕様の実装(Speedo, Apache JDOなど) 7. JPA(Java Persistence API) 3 / 44
  4. 4. 1. JDBC JDBC でがんばる? 僕が一番、SQLをうまく使えるんだ。 俺は JNDI と DataSource と Connection Pooling と、 あと、Dao と DTO とヘルパーBean があれば戦えるぜ! 4 / 44
  5. 5. 2. EJB(Enterprise JavaBeans) まだ EJB で消耗してるの? EJBは、その高すぎる理想のため参入障壁の壁もかなり高い。 要するに使いにくい。(EJBコンテナとか Home/Remote I/Fとか) EJBは元々、分散環境のためのコンポーネントなので、 分散オブジェクトが必要ない場合(大抵は分散不要)、 ひたすら面倒くさいだけ。 EJB3.0以降は使いやすくなったらしいが、 もはや手遅れ感がある。 5 / 44
  6. 6. 3. O/Rマッピング(Object/Relational Mapping) O/Rマッピングを使えば SQL文を書かなくて済むらしい、 というインターネッツの噂はウソ。 1つのテーブルだけ触るマスタメンテ系の処理しかない ならば、SQL文は書かなくて良い。 しかし、多くの業務処理は複数のテーブルを結合したり、 副問い合わせしたりしてデータを抽出する。 つまり、SQL文は必要。 Hibernate と MyBatis がデファクト・スタンダードの 座を争い中? 6 / 44
  7. 7. 4. S2JDBC(Seasar2標準のDBアクセスフレームワーク) S2JDBCは O/Rマッピング可能。普通に SQL文も書ける。 SQL文を外部ファイルで定義できる。(それって、Doma?) 実は、S2JDBC で充分なのだが・・・ 昨年(2015/9/28)Seasar2開発者:ひがやすをさんが、 「2016/9/26 で Seasar2 のサポートを終了する」と 宣言したことによって、 Seasar2コミュニティのメンバや コミッタの人達の士気が下がっただろうと思う。たぶん。 現在、SAStruts と S2JDBC を採用している Webシステムは 今後も使い続けて良いのか? (Yes / No) 7 / 44
  8. 8. 5.~7. 簡単に 5. Spring JDBC JDBC の ラッパーAPI。SQL文を記述するタイプのフレームワーク。 6. JDO仕様の実装(Speedo, Apache JDOなど) Java Data Objects:O/Rマッピングとオブジェクトの永続性に関する仕様。 7. JPA(Java Persistence API) EJB2.0系の問題点を解消するべく策定された、永続性のAPI。 実装は、Hibernate, EclipseLink, Apache OpenJPA など。 おまけ. Doma どま? Doma は Seasarプロジェクトだが、メンテは継続の予定。 8 / 44
  9. 9. ここから本題 9 / 44
  10. 10. Apache Torque について Torque(トルク)は、O/Rマッピングの一種。 Torque は元々、Jakarta プロジェクトの Turbine フレームワークの一部として開発。 その後、独立パッケージとして提供。 ver 3.1以降、ジェネレータとランタイムが分割。 10 / 44
  11. 11. そもそも、O/Rマッピングって何? ORM(Object/Relational Mapping)とは、 オブジェクト指向言語のオブジェクトと、RDBテーブルの レコードとのマッピング(対応付け)。 int colKey; String colValue; Date colDatetime; FugaTbl COL_KEY INTEGER COL_VALUE VARCHAR COL_DATETIME TIMESTAMP FUGA_TBL O/R マッピング クラス テーブル ちなみに、EJB の EntityBean も O/Rマッピング。 Hibernate は Object 寄りで、MyBatis は RDB 寄りの設計思想。 11 / 44
  12. 12. 今回のテスト環境 OS: Windows 8.1 ORM: torque-3.3 torque-gen-3.3 IDE: pleiades-e4.6 JDK: jdk1.8.0_91 Ant: apache-ant-1.9.7 Web: apache-tomcat-8.0.36 Servlet + JSP DB: MySQL 5.7 A5:SQL Mk-2 ver 2.11.6 (x64) 12 / 44
  13. 13. 環境設定&動作確認 1. ダウンロード 2. DBのXML定義 3. Ant実行(JavaクラスとSQLスクリプト生成) 4. 動作環境の構築 5. 実装 6. 動作確認 7. 既存DBからJavaソース生成 8. 型の対応表 9. その他、注意点など 10. テーブル結合 13 / 44
  14. 14. 1. ダウンロード(その1) torque-3.3 (2008/02/28) http://archive.apache.org/dist/db/torque/torque-3.3/binaries/ torque-3.3.zip と torque-gen-3.3.zip をダウンロード。 任意の場所に展開。 例)C:¥work¥torque-3.3 ← ランタイム C:¥work¥torque-gen-3.3 ← ジェネレータ ※1 最新バージョンは torque-4.0 (2014/04/16) ※2 Ant実行時の生成ファイルは、 [展開先]¥torque-gen-3.3¥src 以下に作成される。 14 / 44
  15. 15. 1. ダウンロード(その2) MySQL用JDBCドライバ https://dev.mysql.com/downloads/connector/j/ mysql-connector-java-5.1.39.zip をダウンロード。 zip展開後、Torque ジェネレータの lib に mysql-connector-java-5.1.39-bin.jar をコピー。 例)C:¥work¥torque-gen-3.3¥lib¥ mysql-connector-java-5.1.39-bin.jar 15 / 44
  16. 16. 2. DBのXML定義 DB名:HOGE_DB テーブル名:FUGA_TBL テーブル定義:C:¥work¥torque-gen-3.3¥src¥schema¥hoge_db-schema.xml <database name=“hoge_db"> <table name="fuga_tbl"> <column name="COL_KEY" primaryKey="true“ required="true" type="INTEGER"/> <column name="COL_VALUE" size="50" type="VARCHAR"/> <column name=“COL_DATETIME” type="TIMESTAMP"/> </table> </database> ※ 一部抜粋。 torque-gen は末尾が schema.xml のファイルを自動的に参照。 16 / 44
  17. 17. 3. Ant実行(その1) build.properties の変更 C:¥work¥torque-gen-3.3¥build.properties を 以下のように変更。(変更点のみ抜粋) torque.project = WebHello torque.database = mysql torque.targetPackage = pkg.hogedb torque.database.createUrl = jdbc:mysql://127.0.0.1:3306/mysql torque.database.buildUrl = jdbc:mysql://127.0.0.1:3306/hoge_db torque.database.url = jdbc:mysql://127.0.0.1:3306/hoge_db torque.database.driver = org.gjt.mm.mysql.Driver torque.database.user = root torque.database.password = [root password] torque.database.host = 127.0.0.1 17 / 44
  18. 18. 3. Ant実行(その2) コマンドプロンプトで C:¥work¥torque-gen-3.3へ移動。 JavaソースとSQLスクリプトの生成 ant -f build-torque.xml データベース作成:DBサーバにDB作成 ant -f build-torque.xml create-db テーブル作成:DBサーバにテーブル作成 ant -f build-torque.xml insert-sql 18 / 44
  19. 19. 3. Ant実行(その3) 生成された Java クラス - int colKey; - String colValue; - Date colDatetime; BaseFugaTbl + save() + copy() + toString() FugaTbl + String COL_KEY; + String COL_VALUE; + String COL_DATETIME; BaseFugaTblPeer + doSelect() + doUpdate() + doDelete() FugaTblPeer レコードの 登録、更新など 条件指定での 抽出など 19 / 44 Baseで始まるクラスは、 基本的に修正しないお約束。
  20. 20. 4. 動作環境の構築(その1) Torque.properties のコピー C:¥work¥torque-3.3 の Torque.properties を 動作環境へコピーして変更。 コピー先 例) C:¥work¥pleiades-e4.6¥workspace¥WebHello¥src ※ 実際に動く時は、以下の場所に自動コピーされる。 ここに手動で置いても良いが、クリーンなどで消えるので注意。 例)C:¥work¥pleiades-e4.6¥workspace¥.metadata¥.plugins¥ org.eclipse.wst.server.core¥tmp0¥wtpwebapps¥ WebHello¥WEB-INF¥classes 20 / 44
  21. 21. 4. 動作環境の構築(その2) Torque.properties の変更(変更点のみ抜粋) torque.database.default = hoge_db torque.database.hoge_db.adapter = mysql torque.dsfactory.hoge_db.factory = org.apache.torque.dsfactory.SharedPoolDataSourceFactory torque.dsfactory.hoge_db.pool.maxIdle = 8 torque.dsfactory.hoge_db.pool.maxActive = 10 torque.dsfactory.hoge_db.pool.testOnBorrow = true torque.dsfactory.hoge_db.pool.validationQuery = SELECT 1 torque.dsfactory.hoge_db.connection.driver = org.gjt.mm.mysql.Driver torque.dsfactory.hoge_db.connection.url = jdbc:mysql://localhost:3306/hoge_db?useUnicode=true&characterEncoding=UTF8 torque.dsfactory.hoge_db.connection.user = [user name] torque.dsfactory.hoge_db.connection.password = [user password] 21 / 44 エンコードの 文字コード指定 このスライドでは改行 してるが、実際は1行。
  22. 22. 4. 動作環境の構築(その3) 生成されたJavaソースのコピー 3. Ant実行で生成されたJavaソースを動作環境へコピー。 コピー元 例)C:¥work¥torque-gen-3.3¥src¥java org フォルダ pkg フォルダ コピー先 例) C:¥work¥pleiades-e4.6¥workspace¥WebHello¥src 3. Ant実行(その1)で設定した build.properties の torque.targetPackage = pkg.hogedb をもとに作られる。 22 / 44
  23. 23. 4. 動作環境の構築(その4) 実行時に必要となる jarファイルをコピー。 commons-beanutils-core-1.7.0.jar commons-collections-3.2.jar commons-configuration-1.4.jar commons-dbcp-1.2.2.jar commons-lang-2.3.jar commons-logging-1.1.jar commons-pool-1.3.jar log4j-1.2.14.jar mysql-connector-java-5.1.39-bin.jar torque-3.3.jar village-3.3.jar コピー元の jar は C:¥work¥torque-gen-3.3¥lib C:¥work¥torque-3.3¥lib C:¥work¥torque-3.3 らへんに、だいたいあるハズ。 コピー先 例)C:¥work¥pleiades-e4.6¥workspace ¥WebHello¥WebContent¥WEB-INF¥lib 23 / 44
  24. 24. 5. 実装(その1) 初期処理 TorqueTestServlet.java public void init() { try { // Torque用プロパティファイルの読み込み Class<? extends TorqueTestServlet> thisClass = this.getClass(); ClassLoader classLoader = thisClass.getClassLoader(); PropertiesConfiguration pConfig = new PropertiesConfiguration(); pConfig.load(classLoader.getResourceAsStream("Torque.properties")); // Torqueの初期設定 Torque.init(pConfig); } catch(Exception e) { e.printStackTrace(); } } 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 24 / 44
  25. 25. 5. 実装(その2) 検索処理 TorqueTestServlet#doPost() String findKey = request.getParameter("findKey"); if (findKey != null && findKey.length() > 0) { request.setAttribute("findKey", findKey); try { Criteria crit = new Criteria(); crit.add(FugaTblPeer.COL_KEY, Integer.parseInt(findKey)); List<FugaTbl> resultList = (List<FugaTbl>)FugaTblPeer.doSelect(crit); request.setAttribute("resultList", resultList); } catch(NumberFormatException nfe) { ; } catch(Exception e) { e.printStackTrace(); } } 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 25 / 44 ブラウザから送信された 検索キーを取得し、抽出 条件に設定。 ブラウザから送信された 検索キーを取得し、抽出 条件に設定。 抽出結果を設定。
  26. 26. 5. 実装(その3) 登録/更新処理 TorqueTestServlet#doPost() String setKey = request.getParameter("setKey"); String setValue = request.getParameter("setValue"); Date currDate = new Date(); String setDatetime = currDate.toString(); FugaTbl fugaTbl = new FugaTbl(); fugaTbl.setColKey(Integer.parseInt(setKey)); fugaTbl.setColValue(setValue); fugaTbl.setColDatetime(currDate); 01 02 03 04 05 06 07 08 09 26 / 44 次ページに続く。 ブラウザから送信された値 を取得し、レコード登録用 オブジェクトに設定。 ブラウザから送信された値 を取得し、レコード登録用 オブジェクトに設定。
  27. 27. 5. 実装(その4) 登録/更新処理(続き) Criteria crit = new Criteria(); crit.add(FugaTblPeer.COL_KEY, Integer.parseInt(setKey)); List<FugaTbl> resultList = (List<FugaTbl>)FugaTblPeer.doSelect(crit); if (resultList != null && resultList.size() > 0) { // UPDATE FugaTblPeer.doUpdate(fugaTbl); } else { // INSERT fugaTbl.save(); // UPDATE fugaTbl.setColValue(setValue + “ UPDATE!”); fugaTbl.save(); } 実際のコードは、全体を try ~ catch で囲んでいる。 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 27 / 44
  28. 28. 6. 動作確認(検索) 28 / 44
  29. 29. 6. 動作確認(登録) 29 / 44
  30. 30. 6. 動作確認(一覧) 30 / 44
  31. 31. 7. 既存DBから Javaソース生成 ①データベースからテーブル定義のスキーマ.xml生成 ant -f build-torque.xml jdbc ②schema.xml が生成される 例)C:¥work¥torque-gen-3.3¥src¥schema フォルダ下 ③生成された schema.xml を DB名-schema.xml に リネーム 例)hoge_db-schema.xml ④JavaソースとSQLスクリプトの生成 ant -f build-torque.xml 31 / 44
  32. 32. 8. 型の対応表(その1) No. COLUMN_NAME DATA_TYPE schema.xml Java 1 COL_TINYINT tinyint(4) TINYINT byte 2 COL_SMALLINT smallint(6) SMALLINT short 3 COL_MEDIUMINT mediumint(9) INTEGER int 4 COL_INTEGER int(11) INTEGER int 5 COL_INT int(11) INTEGER int 6 COL_BIGINT bigint(20) BIGINT long 7 COL_NUMERIC decimal(10,0) DECIMAL BigDecimal 8 COL_DECIMAL decimal(10,0) DECIMAL BigDecimal 9 COL_DEC decimal(10,0) DECIMAL BigDecimal 10 COL_FLOAT float REAL float 11 COL_DOUBLE double(10,5) DOUBLE double 12 COL_REAL double DOUBLE double 13 COL_DATE date DATE Date 14 COL_DATETIME datetime TIMESTAMP Date 15 COL_TIMESTAMP timestamp TIMESTAMP Date 32 / 44
  33. 33. 8. 型の対応表(その2) No. COLUMN_NAME DATA_TYPE schema.xml Java 16 COL_TIME time TIME Date 17 COL_YEAR year(4) DATE Date 18 COL_CHAR char(50) CHAR String 19 COL_VARCHAR varchar(50) VARCHAR String 20 COL_TINYTEXT tinytext VARCHAR String 21 COL_TEXT text LONGVARCHAR String 22 COL_MEDIUMTEXT mediumtext LONGVARCHAR String 23 COL_LONGTEXT longtext LONGVARCHAR String 24 COL_TINYBLOB tinyblob BINARY byte[] 25 COL_BLOB blob LONGVARBINARY byte[] 26 COL_MEDIUMBLOB mediumblob LONGVARBINARY byte[] 27 COL_LONGBLOB longblob LONGVARBINARY byte[] 28 COL_ENUM enum('enum1','enum2','en um3') CHAR String 29 COL_SET set('set1','set2','set3') CHAR String 33 / 44
  34. 34. 9. その他、注意点など(その1) DBカラム名の予約語 BY_NAM, BY_PEER_NAME, CATEGORY, PRIMARY_KEY などが Torque の予約語。 schema.xml の文字コード DB名-schema.xml 内で、コメントなどに日本語を 使う場合、文字コードはUTF-8で保存すること。 ShiftJISだと、ant -f build-torque.xml でエラーになる。 34 / 44
  35. 35. 9. その他、注意点など(その2) カラム型の DATETIME は、 schema.xml では TIMESTAMP になる。 そして、 カラム型に TIMESTAMP を指定して A5:SQL Mk-2でテーブル作成すると、 `COL_TIMESTAMP` timestamp, ↓ `COL_TIMESTAMP` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, となる。この CURRENT_TIMESTAMP の部分が、自動生成された Javaソース でコンパイルエラーになってしまう。 なので、DBのテーブル定義から XMLスキーマを生成した場合、XMLファイ ルを一部修正するか、または、Javaソースを修正する必要がある。 private Date colDatetime = new Date(CURRENT_TIMESTAMP); ↑ 定数:CURRENT_TIMESTAMP がない、というエラー発生。 たぶん、Torque のバグ。 35 / 44
  36. 36. 10. テーブル結合(その1) テーブル結合のSELECT 結合条件:PIYO_TBL.COL_TINYINT = FUGA_TBL.COL_KEY COL_KEY INTEGER COL_VALUE VARCHAR COL_DATETIME TIMESTAMP FUGA_TBL COL_TINYINT TINYINT COL_SMALLINT SMALLINT COL_TIMESTAMP TIMESTAMP PIYO_TBL 36 / 44
  37. 37. 10. テーブル結合(その2) PiyoTbl.java に手動で項目追加 - int fugaTblColKey; - String fugaTblColValue; PiyoTbl + getFugaTblColKey() + setFugaTblColKey() + getFugaTblColValue() + setFugaTblColValue() 37 / 44 項目名は任意。 今回は、他テーブルのカラム であることを明示するため、 この名前にした。 Getter と Setter を追加。 ※Eclipse の「getter および setter の生成」機能を使うと 自動生成できて便利。
  38. 38. 10. テーブル結合(その3) PiyoTblPeer.java に getData() メソッド追加 public static List getData() throws TorqueException { // SQL文作成 StringBuffer sb = new StringBuffer(); sb.append(“ select ”); sb.append(“ py.col_tinyint ”); sb.append(“ , py.col_smallint ”); sb.append(“ , fg.col_key ”); sb.append(“ , fg.col_value ”); sb.append(“ from ”); sb.append(“ piyo_tbl py ”); sb.append(“ left join fuga_tbl fg ”); sb.append(“ on ( ”); sb.append(“ py.col_tinyint = fg.col_key ”); sb.append(“ ) ”); sb.append(“ order by py.col_tinyint ASC ”); String sql = sb.toString(); return populateObjects2(executeQuery(sql)); } 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 38 / 44 取得する項目と結合条件、 および、並び順を指定した SELECT文を書く。
  39. 39. 10. テーブル結合(その4) PiyoTblPeer.java に row2Object2() メソッド追加 public static PiyoTbl row2Object2(Record row, int offset, Class cls) throws TorqueException { try{ PiyoTbl obj = (PiyoTbl) cls.newInstance(); populateObject2(row, offset, obj); obj.setModified(false); obj.setNew(false); return obj; } catch (InstantiationException e){ throw new TorqueException(e); } catch (IllegalAccessException e){ throw new TorqueException(e); } } 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 39 / 44 row2Object() が PiyoTblPeer.java にあるので、コピペして修正。 ※39~41ページに「コピペして 修正」と書いたが、おおまかな 処理はコピペ元と同じなので、 共通パターン化できるかも?
  40. 40. 10. テーブル結合(その5) PiyoTblPeer.java に populateObject2() メソッド追加 public static void populateObject2(Record row, int offset, PiyoTbl obj) throws TorqueException { try{ obj.setColTinyint(row.getValue(offset + 0).asByte()); obj.setColSmallint(row.getValue(offset + 1).asShort()); obj.setFugaTblColKey(row.getValue(offset + 2).asInt()); obj.setFugaTblColValue(row.getValue(offset + 3).asString()); } catch (DataSetException e) { throw new TorqueException(e); } } 01 02 03 04 05 06 07 08 09 10 11 12 13 40 / 44 38ページの 5~8行目に対応。 オフセットと型を指定して値を設定。 void populateObjects() が PiyoTblPeer.java にあるので、コピペして修正。
  41. 41. 10. テーブル結合(その6) PiyoTblPeer.java に populateObjects2() メソッド追加 public static List populateObjects2(List records) throws TorqueException { List results = new ArrayList(records.size()); for (int i = 0; i < records.size(); i++){ Record row = (Record) records.get(i); results.add(PiyoTblPeer.row2Object2( row, 1, PiyoTblPeer.getOMClass())); } return results; } 01 02 03 04 05 06 07 08 09 10 11 41 / 44 List populateObjects(List) が PiyoTblPeer.javaにあるので、 コピペして修正。
  42. 42. 10. テーブル結合(その7) 一覧取得 TorqueTestServlet#doGet() // FUGA_TBL 一覧取得 Criteria fugaCrit = new Criteria(); fugaCrit.addAscendingOrderByColumn(FugaTblPeer.COL_KEY); List fugaList = FugaTblPeer.doSelect(fugaCrit); request.setAttribute("fugaList", fugaList); // PIYO_TBL 一覧取得 Criteria piyoCrit = new Criteria(); piyoCrit.addAscendingOrderByColumn(PiyoTblPeer.COL_TINYINT); List piyoList = PiyoTblPeer.doSelect(piyoCrit); request.setAttribute("piyoList", piyoList); // 複数テーブル結合 List joinList = PiyoTblPeer.getData(); request.setAttribute("joinList", joinList); 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 実際のコードは、全体を try ~ catch で囲んでいる。 42 / 44 38ページの getData() を呼び、 抽出結果を取得。
  43. 43. Torque - Torqueユーザガイド http://www.jajakarta.org/turbine/jp/turbine/torque/user-guide.html Torqueのプログラム開発手順書 - UTL sites http://www.utl.co.jp/?p=Torque%E3%81%AE%E3%83%97%E3%83%AD%E3 %82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA%E6%89%8B% E9%A0%86%E6%9B%B8 「Seasar2が終わる!」と慌てるべきではない理由。 - Java EE 事始め! http://masatoshitada.hatenadiary.jp/entry/2016/01/27/181139 Torque http://muimi.com/j/jakarta/torque/ JavaのORM、Domaの話 +α http://backpaper0.github.io/uragamiorm/#/ 43 / 44
  44. 44. Seasar2徹底入門 SAStruts/S2JDBC対応 Spring3入門 ―Javaフレームワーク・より良い設計と アーキテクチャ Jakartaプロジェクト徹底攻略 ―WEB+DB PRESS Special Issue (Javaエキスパート・シリーズ) 44 / 44

×