Más contenido relacionado
La actualidad más candente (20)
Similar a Apache Torqueについて (20)
Apache Torqueについて
- 2. TAKO(たこ)
職業:個人事業主 はてなID:takopons
Java とか PHP とかを使って仕事してます。
仕事場は自宅だったり取引先だったり。
近ごろは JavaScript, jQuery, Ajax, D3.js らへんで
コーディングしてる時間が長いです(昨年比)。
最初は通信系のプログラマとしてデビューして
Solaris の UNIX-C で通信プロトコルの実装を
してました。普通に vi が使えます。
2 / 44
- 5. 2. EJB(Enterprise JavaBeans)
まだ EJB で消耗してるの?
EJBは、その高すぎる理想のため参入障壁の壁もかなり高い。
要するに使いにくい。(EJBコンテナとか Home/Remote I/Fとか)
EJBは元々、分散環境のためのコンポーネントなので、
分散オブジェクトが必要ない場合(大抵は分散不要)、
ひたすら面倒くさいだけ。
EJB3.0以降は使いやすくなったらしいが、
もはや手遅れ感がある。
5 / 44
- 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. 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
- 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
- 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
- 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. 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. 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行。
- 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. 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. 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. 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
- 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. 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. 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
- 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
- 37. 10. テーブル結合(その2)
PiyoTbl.java に手動で項目追加
- int fugaTblColKey;
- String fugaTblColValue;
PiyoTbl
+ getFugaTblColKey()
+ setFugaTblColKey()
+ getFugaTblColValue()
+ setFugaTblColValue()
37 / 44
項目名は任意。
今回は、他テーブルのカラム
であることを明示するため、
この名前にした。
Getter と Setter を追加。
※Eclipse の「getter および
setter の生成」機能を使うと
自動生成できて便利。
- 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. 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. 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. 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. 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() を呼び、
抽出結果を取得。