Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Apache Torqueについて

1,022 views

Published on

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

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

×