001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.db; 017 018import java.sql.Connection; 019import java.sql.ResultSet; 020import java.sql.SQLException; 021 022import org.opengion.fukurou.system.HybsConst ; // 6.1.0.0 (2014/12/26) 023import org.opengion.fukurou.util.ErrorMessage; 024import org.opengion.fukurou.system.ThrowUtil; // 6.4.2.0 (2016/01/29) 025import org.opengion.hayabusa.common.HybsSystem; 026import org.opengion.hayabusa.common.HybsSystemException; 027import org.opengion.hayabusa.resource.ResourceManager; 028 029/** 030 * Query インターフェースを継承した Query の実装クラスです。 031 * クエリークラスにステートメントを与えて execute()することにより内部に DBTableModel を 032 * 作成します。 033 * このクラスは、Abstract クラスのため、実装は個々のサブクラスで行います。 034 * 唯一実装する必要があるのは, execute() メソッドだけです。 035 * 036 * @og.group DB検索 037 * @og.group DB登録 038 * 039 * @version 4.0 040 * @author Kazuhiko Hasegawa 041 * @since JDK5.0, 042 */ 043public class AbstractQuery implements Query { 044 /** システムの改行コードを設定します。*/ 045 protected static final String CR = HybsConst.CR; // 6.1.0.0 (2014/12/26) refactoring 046 /** StringBilderなどの初期値を設定します。 {@value} */ 047 protected static final int BUFFER_MIDDLE = HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 048 049 private Connection connection ; 050 private int rtnCode = ErrorMessage.OK; 051 private ErrorMessage errMessage ; 052 private ResourceManager resource ; 053 054 private DBTableModel table ; 055 private String stmtString ; 056 private int executeCount = -1 ; 057 private int skipRowCount ; 058 private int maxRowCount = HybsSystem.sysInt( "DB_MAX_ROW_COUNT" ) ; 059 private boolean updateFlag = true ; 060 private DBEditConfig config ; // 5.3.6.0 (2011/06/01) 061 062 // 5.1.9.0 (2010/08/01) DB_RETRY_COUNT,DB_RETRY_TIME 廃止 063 /** データ検索時の最大処理制限時間 {@value} */ 064 protected static final int DB_MAX_QUERY_TIMEOUT = HybsSystem.sysInt( "DB_MAX_QUERY_TIMEOUT" ) ; 065 066 /** 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ {@value} */ 067 protected static final int DB_FETCH_SIZE = HybsSystem.sysInt( "DB_FETCH_SIZE" ) ; 068 069 // 3.5.2.0 (2003/10/20) 内部オブジェクトタイプ名を システムパラメータ で定義します。 070 /** 内部オブジェクトタイプ名 {@value} */ 071 public static final String ARG_ARRAY = "ARG_ARRAY" ; 072 /** 内部オブジェクトタイプ名 {@value} */ 073 public static final String SYSARG_ARRAY = "SYSARG_ARRAY" ; 074 /** 内部オブジェクトタイプ名 {@value} */ 075 public static final String ERR_MSG = "ERR_MSG" ; 076 /** 内部オブジェクトタイプ名 {@value} */ 077 public static final String ERR_MSG_ARRAY = "ERR_MSG_ARRAY" ; 078 079 /** 080 * デフォルトコンストラクター 081 * 082 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 083 */ 084 protected AbstractQuery() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 085 086 /** 087 * Connectionオブジェクトを外部から設定します。 088 * 089 * 通常は、Transaction と 接続先(DBID) を使用して作成した Connection を渡します。 090 * このクラスでは、Connection の close() や、ConnectionFactory への返却なども 091 * 行いません。それらは、外部処理(通常は、Transactionオブジェクト)で行います。 092 * 093 * Connection には、null は登録できません。 094 * 095 * @og.rev 6.3.6.1 (2015/08/28) 新規追加 096 * 097 * @param conn Connectionオブジェクト 098 */ 099 public void setConnection( final Connection conn ) { 100 if( conn == null ) { 101 final String errMsg = "Connection に null は指定できません。" + CR ; 102 throw new HybsSystemException( errMsg ); 103 } 104 connection = conn; 105 } 106 107 /** 108 * ステートメント文字列をセットします。 109 * 110 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 111 * 112 * @param stmt ステートメント文字列 113 * 114 */ 115 public void setStatement( final String stmt ) { 116 this.stmtString = stmt.trim(); 117 } 118 119 /** 120 * ステートメント文字列を取り出します。 121 * 122 * @return ステートメント文字列 123 * 124 */ 125 public String getStatement() { 126 return stmtString; 127 } 128 129 /** 130 * 引数配列付のクエリーを実行します。 131 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 132 * これは、PreparedQuery で使用する引数を配列でセットするものです。 133 * select * from emp where deptno = ? and job = ? などの PreparedQuery や 134 * { call xxxx( ?,?,? ) } などの CallableStatement の ? 部分の引数を 135 * 順番にセットしていきます。 136 * ※ このクラスでは実装されていません。 137 * 138 * @og.rev 6.1.1.0 (2015/01/17) 引数配列を可変引数にして、execute() を含めて定義します。 139 * 140 * @param args オブジェクトの引数配列(可変長引数) 141 */ 142 public void execute( final String... args ) { // 6.1.1.0 (2015/01/17) refactoring 143 final String errMsg = "このクラスでは実装されていません。execute( String... )"; 144 throw new UnsupportedOperationException( errMsg ); 145 } 146 147 /** 148 * 引数配列付のクエリーを実行します。 149 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 150 * これは、PreparedQuery で使用する引数を配列でセットするものです。 151 * select * from emp where deptno = ? and job = ? などの PreparedQuery の 152 * ? 部分の引数を 153 * 順番にセットしていきます。 154 * ※ このクラスでは実装されていません。 155 * 156 * @og.rev 4.0.0.0 (2005/01/31) 新規追加 157 * 158 * @param keys オブジェクトのキー配列 159 * @param args オブジェクトの引数配列(可変長引数) 160 */ 161 public void execute( final String[] keys, final String... args ) { // 6.1.1.0 (2015/01/17) refactoring 162 final String errMsg = "このクラスでは実装されていません。execute( String[],String... )"; 163 throw new UnsupportedOperationException( errMsg ); 164 } 165 166 /** 167 * 引数配列付のクエリーを実行します。 168 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 169 * これは、PreparedQuery で使用する引数を配列でセットするものです。 170 * select * from emp where deptno = ? and job = ? などの PreparedQuery の 171 * ? 部分の引数を 172 * 順番にセットしていきます。 173 * ※ このクラスでは実装されていません。 174 * 175 * @og.rev 4.0.0.0 (2005/01/31) 引数をすべて受け取って実行するメソッドを標準メソッドとして追加 176 * 177 * @param names カラム名(CSV形式) 178 * @param dbArrayType アレイタイプ名称 179 * @param sysArg DBSysArg配列 180 * @param userArg DBUserArg配列 181 */ 182 public void execute( final String names,final String dbArrayType, 183 final DBSysArg[] sysArg,final DBUserArg[] userArg ) { 184 final String errMsg = "このクラスでは実装されていません。execute( String,String,DBSysArg[],DBUserArg[] )"; 185 throw new UnsupportedOperationException( errMsg ); 186 } 187 188 /** 189 * 引数配列付のクエリーを実行します。 190 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 191 * これは、PreparedQuery で使用する引数を配列でセットするものです。 192 * select * from emp where deptno = ? and job = ? などの PreparedQuery の 193 * [カラム名] 部分の引数を、DBTableModelから順番にセットしていきます。 194 * ※ このクラスでは実装されていません。 195 * 196 * @param rowNo 選択された行番号配列(登録する対象行) 197 * @param table DBTableModelオブジェクト(登録する元データ) 198 */ 199 public void execute( final int[] rowNo, final DBTableModel table ) { 200 final String errMsg = "このクラスでは実装されていません。execute( final int[] rowNo, final DBTableModel table )"; 201 throw new UnsupportedOperationException( errMsg ); 202 } 203 204 /** 205 * クエリーの実行結果件数をセットします。 206 * 初期値は -1 です。(クエリーが失敗した場合や,CallableStatement の呼び出し等で 207 * 実行件数が明確でない場合の戻り値)。 208 * 209 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 210 * 211 * @param executeCount 実行結果件数 212 */ 213 protected void setExecuteCount( final int executeCount ) { 214 this.executeCount = executeCount; 215 } 216 217 /** 218 * クエリーの実行結果を返します。 219 * クエリーが失敗した場合や,CallableStatement の呼び出し等で実行件数が明確でない 220 * 場合は, -1 が返されます。 221 * 222 * @return 実行結果件数 223 */ 224 public int getExecuteCount() { 225 return executeCount; 226 } 227 228 /** 229 * DBTableModel をセットします。 230 * なお、検索系実行前に setDBTableModel() でテーブルをセットしていたとしても 231 * そのオブジェクトは破棄されて、新しい DBTableModel が生成されます。 232 * 233 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 234 * 235 * @param table DBTableModelオブジェクト 236 */ 237 protected void setDBTableModel( final DBTableModel table ) { 238 this.table = table; 239 } 240 241 /** 242 * 実行結果の DBTableModel を返します。 243 * 244 * @return DBTableModelオブジェクト 245 */ 246 public DBTableModel getDBTableModel() { 247 return table; 248 } 249 250 /** 251 * データベースの最大検索件数を返します。 252 * (初期値:DB_MAX_ROW_COUNT[={@og.value SystemData#DB_MAX_ROW_COUNT}])。 253 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 254 * DBTableModelのデータとして登録する最大件数をこの値に設定します。0は無制限です。 255 * サーバーのメモリ資源と応答時間の確保の為です。 256 * 257 * @return 最大検索件数 258 */ 259 public int getMaxRowCount() { 260 return maxRowCount; 261 } 262 263 /** 264 * データベースの最大検索件数をセットします。 265 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 266 * DBTableModelのデータとして登録する最大件数をこの値に設定します。 267 * サーバーのメモリ資源と応答時間の確保の為です。 268 * ゼロ、または、負の値を設定すると、無制限(Integer.MAX_VALUE)になります。 269 * 270 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 271 * @og.rev 4.0.0.0 (2005/08/31) ゼロ、または、負の値は、無制限(Integer.MAX_VALUE)にする。 272 * 273 * @param maxRowCount 最大検索件数 274 */ 275 public void setMaxRowCount( final int maxRowCount ) { 276 this.maxRowCount = maxRowCount > 0 ? maxRowCount : Integer.MAX_VALUE ; 277 } 278 279 /** 280 * データベースの検索スキップ件数を返します。 281 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 282 * DBTableModelのデータとしては、スキップ件数分は登録されません。 283 * サーバーのメモリ資源と応答時間の確保の為です。 284 * 285 * @return 最大検索件数 286 */ 287 public int getSkipRowCount() { 288 return skipRowCount; 289 } 290 291 /** 292 * データベースの検索スキップ件数をセットします。 293 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 294 * DBTableModelのデータとしては、スキップ件数分は登録されません。 295 * サーバーのメモリ資源と応答時間の確保の為です。 296 * 297 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 298 * 299 * @param skipRowCount スキップ件数 300 */ 301 public void setSkipRowCount( final int skipRowCount ) { 302 this.skipRowCount = skipRowCount; 303 } 304 305 /** 306 * アップデートフラグをセットします。 307 * これは、Query で更新処理の SQL 文を実行したときにセットされます。 308 * 更新処理が実行:true / 検索処理のみ:false をセットします。 309 * このメソッドを呼び出さない場合は、デフォルト:true です。 310 * 311 * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更 312 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 313 * 314 * @param up アップデートされたかどうか[true:更新処理/false:検索処理] 315 */ 316 protected void setUpdateFlag( final boolean up ) { 317 updateFlag = up; 318 } 319 320 /** 321 * アップデートフラグを取得します。 322 * これは、Query で更新処理の SQL 文を実行したときに true にセットされます。 323 * 更新処理が実行:true / 検索処理のみ:false を取得できます。 324 * 325 * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更 326 * @og.rev 4.0.0.0 (2007/07/20) メソッド名変更( getUpdateFlag() ⇒ isUpdate() ) 327 * 328 * @return アップデートされたかどうか[true:更新処理/false:検索処理] 329 */ 330 public boolean isUpdate() { 331 return updateFlag ; 332 } 333 334 /** 335 * リソースマネージャーをセットします。 336 * これは、言語(ロケール)に応じた DBColumn をあらかじめ設定しておく為に 337 * 必要です。 338 * リソースマネージャーが設定されていない、または、所定のキーの DBColumn が 339 * リソースに存在しない場合は、内部で DBColumn オブジェクトを作成します。 340 * 341 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 342 * 343 * @param resource リソースマネージャー 344 */ 345 public void setResourceManager( final ResourceManager resource ) { 346 this.resource = resource; 347 } 348 349 /** 350 * エラーコード を取得します。 351 * エラーコード は、ErrorMessage クラスで規定されているコードです。 352 * 353 * @return エラーコード 354 */ 355 public int getErrorCode() { 356 return rtnCode; 357 } 358 359 /** 360 * エラーコード をセットします。 361 * エラーコード は、ErrorMessage クラスで規定されているコードです。 362 * 363 * @param cd エラーコード 364 */ 365 protected void setErrorCode( final int cd ) { 366 rtnCode = cd; 367 } 368 369 /** 370 * エラーメッセージオブジェクト を取得します。 371 * 372 * @return エラーメッセージオブジェクト 373 */ 374 public ErrorMessage getErrorMessage() { 375 return errMessage; 376 } 377 378 /** 379 * エラーメッセージオブジェクト をセットします。 380 * 381 * @param em エラーメッセージオブジェクト 382 */ 383 protected void setErrorMessage( final ErrorMessage em ) { 384 errMessage = em; 385 } 386 387 /** 388 * 編集設定オブジェクトをセットします。 389 * 390 * @og.rev 5.3.6.0 (2011/06/01) 新規追加 391 * 392 * @param config 編集設定オブジェクト 393 */ 394 public void setEditConfig( final DBEditConfig config ) { 395 this.config = config; 396 } 397 398 /** 399 * 編集設定オブジェクトを取得します。 400 * 401 * @og.rev 5.3.6.0 (2011/06/01) 新規追加 402 * 403 * @return 編集設定オブジェクト 404 */ 405 protected DBEditConfig getEditConfig() { 406 return config; 407 } 408 409 ////////////////////////////////////////////////////////////////////////// 410 // 411 // 継承時にサブクラスから使用するメソッド類( protected ) 412 // 413 ////////////////////////////////////////////////////////////////////////// 414 415 /** 416 * ResultSet を DBTableModelに割り当てます。 417 * 418 * 毎回,検索毎に,DBTableModel にコピーするイメージです。 419 * ResulSet 以外のオブジェクトから,DBTableModelを作成する場合は, 420 * このメソッドをオーバーライドします。 421 * 422 * このメソッドは, execute からのみ,呼び出されます。 423 * それ以外からは呼出し出来ません。 424 * 425 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 426 * @og.rev 3.3.3.3 (2003/08/06) カラムのラベル名を、大文字に変換する。 427 * @og.rev 3.8.5.0 (2006/03/02) CLOB カラムかどうかを判定しCLOBの場合は、Clob オブジェクトから文字列を取り出します。 428 * @og.rev 3.8.8.8 (2007/05/11) ROWID対応(小数点対応 "0.3" が ".3" と表示される対策) 429 * @og.rev 4.0.0.0 (2006/01/31) CLOB カラムかどうかを判定しCLOBの場合は、ストリームから値を取り出します。 430 * @og.rev 5.3.6.0 (2011/06/01) DBTableModel作成処理をDBTableModelUtilに移動&集計機能対応 431 * @og.rev 6.3.6.1 (2015/08/28) close(),realClose() 廃止。Queryはキャッシュしません。 432 * 433 * @param resultSet ResultSetオブジェクト 434 */ 435 protected void createTableModel( final ResultSet resultSet ) { 436 try { 437 if( config == null ) { 438 table = DBTableModelUtil.makeDBTable( resultSet, getSkipRowCount(), maxRowCount, resource ); 439 } 440 else { 441 table = DBTableModelUtil.makeEditDBTable( resultSet, getSkipRowCount(), maxRowCount, resource, config ); 442 } 443 444 setExecuteCount( table.getRowCount() ); 445 } 446 catch( final SQLException ex ) { 447 final String errMsg = "テーブルモデルを作成できませんでした。"; 448 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 449 } 450 } 451 452 /** 453 * ConnectionFactory.connection( String ); を利用して,Connection 454 * オブジェクトを取り出します。 455 * 456 * コネクションプールが一杯の場合は、即エラーになります。 457 * 458 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 459 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 460 * @og.rev 5.1.9.0 (2010/08/01) transaction 属性追加。 461 * @og.rev 6.3.6.1 (2015/08/28) transaction 属性廃止。内部のConnectionを返します。 462 * 463 * @return コネクション 464 */ 465 protected Connection getConnection() { 466 467 return connection; 468 } 469 470 /** 471 * この接続が、PreparedStatement#getParameterMetaData() を使用するかどうかを判定します。 472 * 473 * ConnectionFactory#useParameterMetaData(String) の結果を返します。(postgreSQL対応) 474 * 475 * ※ 暫定処理です。もっと、良い方法を考える必要があります。 476 * 477 * @og.rev 5.3.8.0 (2011/08/01) 新規追加 478 * @og.rev 6.3.6.1 (2015/08/28) 内部変数にconnIDが無くなったため、直接所得することになりました。 479 * @og.rev 6.4.2.0 (2016/01/29) ex.printStackTrace() を、ThrowUtil#ogStackTrace(Throwable) に置き換え。 480 * 481 * @return 使用する場合:true / その他:false 482 * @see org.opengion.fukurou.db.ConnectionFactory#useParameterMetaData(String) 483 */ 484 protected boolean useParameterMetaData() { 485 // return ConnectionFactory.useParameterMetaData( connID ); 486 try { 487 return "PostgreSQL".equalsIgnoreCase( connection.getMetaData().getDatabaseProductName() ); 488 } 489 catch( final Throwable th ) { 490 System.err.println( ThrowUtil.ogStackTrace( th ) ); // 6.4.2.0 (2016/01/29) 491 } 492 return false ; 493 } 494 495 ////////////////////////////////////////////////////////////////////////// 496 // 497 // Object クラスのオーバーライド部分 498 // 499 ////////////////////////////////////////////////////////////////////////// 500 501 /** 502 * オブジェクトの識別子として,最後のクエリーを返します。 503 * 504 * @return 最後のクエリー 505 * @og.rtnNotNull 506 */ 507 @Override 508 public String toString() { 509 return "LastQuery :[" + getStatement() + "] "; 510 } 511}