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.plugin.query; 017 018import org.opengion.hayabusa.common.HybsSystemException; 019import org.opengion.hayabusa.db.AbstractQuery; 020import org.opengion.fukurou.util.ErrorMessage; 021import org.opengion.fukurou.util.StringUtil; 022 023import java.sql.PreparedStatement; 024import java.sql.ResultSet; 025import java.sql.SQLException; 026 027/** 028 * 引数引き当て(PreparedStatement) を利用した登録系Queryです。 029 * 030 * java.sql.PreparedStatement を用いて、データベース検索処理を行います。 031 * 引数に、指定した値を配列で渡します。 032 * 内部変数の受け渡しのデフォルト実装は、AbstractQuery クラスを継承している 033 * ため,ここでは、execute() メソッドを実装しています。 034 * このクラスでは、ステートメント文を execute() する事により,データベースを 035 * 検索した結果を DBTableModel に割り当てます。 036 * 037 * このクラスは、Query で使用されるより、内部の DBTableModelUtilから、 038 * 利用されるケースが主です。 039 * Query で使用する場合は、JDBCPrepared ではなく、JDBCTableUpdate を 040 * 使用することを、ご検討ください。 041 * 042 * @og.formSample 043 * 例: 044 * 可変引数付きのSQL文を実行します。 045 * これは、INSERT,UPDATE,DELETE など、どのようなSQL文でも実行できます。 046 * names 属性で指定するのは、DBTableModelのカラム名で、その値が順番に、 047 * 引数(?記号)の個所に設定されます。 048 * 選択されたデータ(行)の数だけ、繰り返し実行されます。 049 * 050 * jsp/TYPE1A/copy.jsp 051 * <og:value scope="session" 052 * key="names" 053 * value="CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG" /> 054 * <og:value scope="session" key="SQL" > 055 * INSERT INTO GEA08 056 * (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG, 057 * FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD) 058 * VALUES 059 * (?,?,?,?,?,?, 060 * '1','{@USER.YMDH}','{@USER.YMDH}','{@USER.ID}','{@USER.ID}','{@GUI.KEY}') 061 * </og:value> 062 * 063 * jsp/TYPE1A/entry.jsp 064 * <h:tableUpdate 065 * command = "{@command}" 066 * queryType = "JDBCPrepared" 067 * names = "{@names}" > 068 * {@SQL} 069 * </og:tableUpdate> 070 * 071 * <!-- 前画面で指定のSQL文を削除します。(scope="session"なので削除が必要。) --> 072 * <og:value scope="session" key="names" command="REMOVE" /> 073 * <og:value scope="session" key="SQL" command="REMOVE" /> 074 * 075 * @og.group データ表示 076 * @og.group データ編集 077 * 078 * @version 4.0 079 * @author Kazuhiko Hasegawa 080 * @since JDK5.0, 081 */ 082public class Query_JDBCPrepared extends AbstractQuery { 083 /** このプログラムのVERSION文字列を設定します。 {@value} */ 084 private static final String VERSION = "6.4.2.1 (2016/02/05)" ; 085 086 /** 087 * デフォルトコンストラクター 088 * 089 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 090 */ 091 public Query_JDBCPrepared() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 092 093 /** 094 * 引数配列付のクエリーを実行します。 095 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 096 * これは、PreparedQuery で使用する引数を配列でセットするものです。 097 * select * from emp where deptno = ? and job = ? などの PreparedQuery の 098 * ? 部分の引数を 099 * 順番にセットしていきます。 100 * 101 * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更 102 * @og.rev 2.3.1.3 (2003/01/28) Open Cursor が、大量に残る件の対応。ResultSet を close() 103 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 104 * @og.rev 3.3.3.1 (2003/07/18) DB登録時の後ろスペースを削除する。 105 * @og.rev 3.5.6.0 (2004/06/18) PreparedStatement をexecute 間で使いまわします。 106 * @og.rev 3.8.0.8 (2005/10/03) エラーメッセージの出力順をメッセージ+Queryに変更します。 107 * @og.rev 5.3.8.0 (2011/08/01) pstmt.setObject で、useParamMetaData の判定を避けるため、pstmt.setString で代用(PostgreSQL対応) 108 * @og.rev 6.3.6.1 (2015/08/28) close(),realClose() 廃止。Queryはキャッシュしません。 109 * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。 110 * @og.rev 6.9.3.0 (2018/03/26) DB_FETCH_SIZE追加。 111 * 112 * @param args オブジェクトの引数配列(可変長引数) 113 */ 114 @Override 115 public void execute( final String... args ) { // 6.1.1.0 (2015/01/17) refactoring 116 117 // 6.4.2.1 (2016/02/05) try-with-resources 文 118 try( final PreparedStatement pstmt = getConnection().prepareStatement( getStatement() ) ) { 119 pstmt.setQueryTimeout( DB_MAX_QUERY_TIMEOUT ); 120 121 // 6.1.1.0 (2015/01/17) refactoring. 可変引数にしたため、null は来ない。 122 for( int i=0; i<args.length; i++ ) { 123 pstmt.setString( i+1,StringUtil.rTrim( args[i] ) ); // 5.3.8.0 (2011/08/01) 処理の簡素化 124 } 125 126 if( pstmt.execute() ) { 127 try( final ResultSet resultSet = pstmt.getResultSet() ) { 128 resultSet.setFetchSize( DB_FETCH_SIZE ); // 6.9.3.0 (2018/03/26) 129 createTableModel( resultSet ); 130 setUpdateFlag( false ); 131 } 132 } 133 else { 134 setExecuteCount( pstmt.getUpdateCount() ); 135 } 136 137 setErrorCode( ErrorMessage.OK ); 138 } 139 catch( final SQLException ex ) { // catch は、close() されてから呼ばれます。 140 setErrorCode( ErrorMessage.EXCEPTION ); 141 142 final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR 143 + getStatement() + CR; 144 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 145 } 146 } 147 148}