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.fukurou.process; 017 018import org.opengion.fukurou.util.Argument; 019import org.opengion.fukurou.util.SystemParameter; 020import org.opengion.fukurou.util.StringUtil; 021import org.opengion.fukurou.util.LogWriter; 022import org.opengion.fukurou.util.HybsEntry ; 023import org.opengion.fukurou.util.Closer; 024import org.opengion.fukurou.model.Formatter; 025import org.opengion.fukurou.db.ConnectionFactory; 026 027import java.util.Map ; 028import java.util.LinkedHashMap ; 029import java.util.Set ; 030import java.util.HashSet ; 031 032import java.sql.Connection; 033import java.sql.Statement; 034import java.sql.PreparedStatement; 035import java.sql.ParameterMetaData; 036import java.sql.SQLException; 037 038/** 039 * Process_DBWriter は、上流から受け取ったデータをデータベースに書き込む 040 * CainProcess インターフェースの実装クラスです。 041 * 042 * 上流(プロセスチェインのデータは上流から下流へと渡されます。)から受け取った 043 * LineModel を元に、データベースへの書き込みを行います。 044 * 045 * データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に 046 * 設定された接続(Connection)を使用します。 047 * 048 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 049 * 引数文字列の 『=』の前後には、スペースは挟めません。必ず、-key=value の様に 050 * 繋げてください。 051 * 052 * SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。 053 * 054 * @og.formSample 055 * Process_DBWriter -dbid=DBGE -table=GE41 056 * 057 * [ -dbid=DB接続ID ] : -dbid=DBGE (例: Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定) 058 * [ -table=登録テーブルID ] : SQL文を指定する場合は不要。INSERT する場合のテーブルID 059 * [ -sql=検索SQL文 ] : -sql="UPDATE GE41 SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME] 060 * WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]" 061 * [ -sqlFile=登録SQLファイル ] : -sqlFile=update.sql 062 * : -sql や -sqlFile が指定されない場合は、-table で指定のテーブルに全カラム insert です。 063 * [ -sql_XXXX=固定値 ] : -sql_SYSTEM_ID=GE 064 * SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。 065 * WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE' 066 * [ -const_XXXX=固定値 ] : -const_FGJ=1 067 * LineModel のキー(const_ に続く文字列)の値に、固定値を設定します。 068 * キーが異なれば、複数のカラム名を指定できます。 069 * [ -omitClms=AAA,BBB,… ] : -omitClms=UNIQ,FGJ,DYSET 070 * -table 属性でINSERT文を自動作成する場合、取り除くカラム名を 071 * カンマ区切りで複数指定できます。 072 * [ -initSql=開始時SQL文 ] : -initSql="DELETE FROM GE41 WHERE FGJ = '9'" 073 * [ -initSqlFile=開始時SQLファイル] : -initSqlFile=update.sql 074 * [ -endSql=終了時SQL文 ] : -endSql="UPDATE GE41 SET FGJ = '1'" 075 * [ -endSqlFile=終了時SQLファイル ] : -endSqlFile=update.sql 076 * [ -commitCnt=commit処理指定 ] : 指定数毎にコミットを発行します。0 の場合は、終了までコミットしません。 077 * [ -display=[false/true] ] : 結果を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 078 * [ -debug=[false/true] ] :デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 079 * 080 * @version 4.0 081 * @author Kazuhiko Hasegawa 082 * @since JDK5.0, 083 */ 084public class Process_DBWriter extends AbstractProcess implements ChainProcess { 085 private static final String CNST_KEY = "const_" ; 086 private static final String SQL_KEY = "sql_" ; 087 088 private Connection connection = null; 089 private PreparedStatement pstmt = null; 090 private ParameterMetaData pMeta = null; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す。(PostgreSQL対応) 091 private boolean useParamMetaData = false; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す。(PostgreSQL対応) 092 093 private String dbid = null; 094 private String sql = null; 095// private String initSql = null; // 5.7.2.2 (2014/01/24) 追加 096 private String endSql = null; // 5.7.2.2 (2014/01/24) 追加 097 private String table = null; 098 private int[] clmNos = null; // ファイルのヘッダーのカラム番号 099 private int commitCnt = 0; // コミットするまとめ件数 100 private boolean display = false; // 表示しない 101 private boolean debug = false; // 5.7.3.0 (2014/02/07) デバッグ情報 102 103 private String[] cnstClm = null; // 固定値を設定するカラム名 104 private int[] cnstClmNos = null; // 固定値を設定するカラム番号 105 private String[] constVal = null; // カラム番号に対応した固定値 106 107 private boolean firstRow = true; // 最初の一行目 108 private int count = 0; 109 private String[] omitClms = null; // 4.0.0.0 (2007/09/21) table 指定時に取り除くカラム 110 111 private static final Map<String,String> mustProparty ; // [プロパティ]必須チェック用 Map 112 private static final Map<String,String> usableProparty ; // [プロパティ]整合性チェック Map 113 114 static { 115 mustProparty = new LinkedHashMap<String,String>(); 116 117 usableProparty = new LinkedHashMap<String,String>(); 118 usableProparty.put( "dbid", "Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定" ); 119 usableProparty.put( "table", "INSERT する場合のテーブルID SQL文を指定する場合は不要。" ); 120 usableProparty.put( "sql", "更新SQL文(sql or sqlFile 必須)" + 121 CR + "例: \"UPDATE GE41 " + 122 CR + "SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME] " + 123 CR + "WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]\"" ); 124 usableProparty.put( "sqlFile", "登録SQLファイル(sql or sqlFile 必須)例: update.sql" ); 125 usableProparty.put( "sql_", "SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。" + 126 CR + "WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE'" ); 127 usableProparty.put( "const_", "LineModel のキー(const_ に続く文字列)の値に、固定値を" + 128 CR + "設定します。キーが異なれば、複数のカラム名を指定できます。" + 129 CR + "例: -sql_SYSTEM_ID=GE" ); 130 // 4.0.0.0 (2007/09/21) 属性を追加 131 usableProparty.put( "omitClms", "-table 属性でINSERT文を自動作成する場合、取り除くカラム名を" + 132 CR + "カンマ区切りで複数指定できます。" + 133 CR + "例: -omitClms=UNIQ,FGJ,DYSET" ); 134 usableProparty.put( "initSql" , "開始時に一度だけ実行されるSQL文を指定します。" ); // 5.7.2.2 (2014/01/24) 追加 135 usableProparty.put( "initSqlFile", "開始時に一度だけ実行されるSQLファイルを指定します。" ); // 5.7.2.2 (2014/01/24) 追加 136 usableProparty.put( "endSql" , "終了時に一度だけ実行されるSQL文を指定します。" ); // 5.7.2.2 (2014/01/24) 追加 137 usableProparty.put( "endSqlFile" , "終了時に一度だけ実行されるSQLファイルを指定します。" ); // 5.7.2.2 (2014/01/24) 追加 138 usableProparty.put( "commitCnt", "指定数毎にコミットを発行します。" + 139 CR + "0 の場合は、終了までコミットしません(初期値:0)" ); 140 usableProparty.put( "display", "結果を標準出力に表示する(true)かしない(false)か" + 141 CR + "(初期値:false:表示しない)" ); 142 usableProparty.put( "debug", "デバッグ情報を標準出力に表示する(true)かしない(false)か" + 143 CR + "(初期値:false:表示しない)" ); // 5.7.3.0 (2014/02/07) デバッグ情報 144 } 145 146 /** 147 * デフォルトコンストラクター。 148 * このクラスは、動的作成されます。デフォルトコンストラクターで、 149 * super クラスに対して、必要な初期化を行っておきます。 150 * 151 */ 152 public Process_DBWriter() { 153 super( "org.opengion.fukurou.process.Process_DBWriter",mustProparty,usableProparty ); 154 } 155 156 /** 157 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 158 * 初期処理(ファイルオープン、DBオープン等)に使用します。 159 * 160 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属性を追加 161 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 162 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応) 163 * @og.rev 5.7.2.2 (2014/01/24) initSql,initSqlFile,endSql,endSqlFile 追加 164 * 165 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 166 */ 167 public void init( final ParamProcess paramProcess ) { 168 Argument arg = getArgument(); 169 170 table = arg.getProparty("table"); 171 sql = arg.getFileProparty("sql","sqlFile",false); 172// initSql = arg.getFileProparty("initSql","initSqlFile",false); // 5.7.2.2 (2014/01/24) 追加 173 endSql = arg.getFileProparty("endSql","endSqlFile",false); // 5.7.2.2 (2014/01/24) 追加 174 commitCnt = arg.getProparty("commitCnt",commitCnt); 175 display = arg.getProparty("display",display); 176 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) デバッグ情報 177 178 dbid = arg.getProparty("dbid"); 179 connection = paramProcess.getConnection( dbid ); 180 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 181 useParamMetaData = ConnectionFactory.useParameterMetaData( dbid ); // 5.3.8.0 (2011/08/01) 182 183 // 取り除くカラム名リストを配列に変換します。 184 String tempClms = arg.getProparty("omitClms",null); 185 if( tempClms != null ) { 186 omitClms = StringUtil.csv2Array( tempClms ); 187 } 188 189 if( sql == null && table == null ) { 190 String errMsg = "sql を指定しない場合は、table を必ず指定してください。"; 191 throw new RuntimeException( errMsg ); 192 } 193 194 // 3.8.0.1 (2005/06/17) {@DATE.XXXX} 変換処理の追加 195 // {@DATE.YMDH} などの文字列を、yyyyMMddHHmmss 型の日付に置き換えます。 196 // SQL文の {@XXXX} 文字列の固定値への置き換え 197 HybsEntry[] entry =arg.getEntrys(SQL_KEY); // 配列 198 SystemParameter sysParam = new SystemParameter( sql ); 199 sql = sysParam.replace( entry ); 200 201 // 5.7.2.2 (2014/01/24) initSql,endSql にも{@XXXX} 文字列の置き換えを行います。 202 String initSql = arg.getFileProparty("initSql","initSqlFile",false); // 5.7.2.2 (2014/01/24) 追加 203 if( initSql != null ) { 204 SystemParameter sysParam2 = new SystemParameter( initSql ); 205 initSql = sysParam2.replace( entry ); 206 execSql( initSql ); 207 } 208 if( endSql != null ) { 209 SystemParameter sysParam3 = new SystemParameter( endSql ); 210 endSql = sysParam3.replace( entry ); 211 } 212 213 HybsEntry[] cnstKey = arg.getEntrys( CNST_KEY ); // 配列 214 int csize = cnstKey.length; 215 cnstClm = new String[csize]; 216 constVal = new String[csize]; 217 for( int i=0; i<csize; i++ ) { 218 cnstClm[i] = cnstKey[i].getKey(); 219 constVal[i] = cnstKey[i].getValue(); 220 } 221 } 222 223 /** 224 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 225 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 226 * 227 * @og.rev 4.0.0.0 (2007/11/27) commit,rollback,remove 処理を追加 228 * @og.rev 5.1.1.0 (2009/11/11) pMeta のクリア 229 * @og.rev 5.7.2.2 (2014/01/24) endSql 処理の追加 230 * 231 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 232 */ 233 public void end( final boolean isOK ) { 234 boolean flag = Closer.stmtClose( pstmt ); 235 pstmt = null; 236 pMeta = null; // 5.1.1.0 (2009/11/11) 237 238 // 5.7.2.2 (2014/01/24) endSql の実行 239 Throwable th2 = null; 240 if( isOK && endSql != null ) { 241 try { execSql( endSql ); } catch (Throwable th) { th2 = th ; } 242 } 243 244 // 5.7.2.2 (2014/01/24) すべて異常がない場合のみ、処理する様に変更。 245 if( isOK && flag && th2 == null ) { 246 Closer.commit( connection ); 247 } 248 else { 249 Closer.rollback( connection ); 250 } 251 ConnectionFactory.remove( connection,dbid ); 252 253 if( !flag ) { 254 String errMsg = "ステートメントをクローズ出来ません。"; 255 throw new RuntimeException( errMsg ); 256 } 257 258 // 5.7.2.2 (2014/01/24) endSql の実行失敗時の処理 259 if( th2 != null ) { 260 String errMsg = "endSql の実行に失敗しました。sql=[" + endSql + "]" + CR 261 + th2.getMessage() + CR ; 262 throw new RuntimeException( errMsg,th2 ); 263 } 264 } 265 266 /** 267 * 引数の LineModel を処理するメソッドです。 268 * 変換処理後の LineModel を返します。 269 * 後続処理を行わない場合(データのフィルタリングを行う場合)は、 270 * null データを返します。つまり、null データは、後続処理を行わない 271 * フラグの代わりにも使用しています。 272 * なお、変換処理後の LineModel と、オリジナルの LineModel が、 273 * 同一か、コピー(クローン)かは、各処理メソッド内で決めています。 274 * ドキュメントに明記されていない場合は、副作用が問題になる場合は、 275 * 各処理ごとに自分でコピー(クローン)して下さい。 276 * 277 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 278 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData setNull 対応(PostgreSQL対応) 279 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 280 * 281 * @param data オリジナルのLineModel 282 * 283 * @return 処理変換後のLineModel 284 */ 285 public LineModel action( final LineModel data ) { 286 count++ ; 287 try { 288 if( firstRow ) { 289 pstmt = makePrepareStatement( table,data ); 290 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 291 if( useParamMetaData ) { 292 pMeta = pstmt.getParameterMetaData(); 293 } 294 295 int size = cnstClm.length; 296 cnstClmNos = new int[size]; 297 for( int i=0; i<size; i++ ) { 298 cnstClmNos[i] = data.getColumnNo( cnstClm[i] ); 299 } 300 301 firstRow = false; 302 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 303 } 304 305 // 固定値置き換え処理 306 for( int j=0; j<cnstClmNos.length; j++ ) { 307 data.setValue( cnstClmNos[j],constVal[j] ); 308 } 309 310 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 311 if( useParamMetaData ) { 312 for( int i=0; i<clmNos.length; i++ ) { 313 int type = pMeta.getParameterType( i+1 ); 314 // 5.3.8.0 (2011/08/01) setNull 対応 315 Object val = data.getValue(clmNos[i]); 316 if( val == null || ( val instanceof String && ((String)val).isEmpty() ) ) { 317 pstmt.setNull( i+1, type ); 318 } 319 else { 320 pstmt.setObject( i+1, val, type ); 321 } 322 } 323 } 324 else { 325 for( int i=0; i<clmNos.length; i++ ) { 326 pstmt.setObject( i+1,data.getValue(clmNos[i]) ); 327 } 328 } 329 330 pstmt.execute(); 331 if( commitCnt > 0 && ( count%commitCnt == 0 ) ) { 332 Closer.commit( connection ); 333 } 334 } 335 catch (SQLException ex) { 336 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 337 String errMsg = "SQL を実行できませんでした。" + CR 338 + "errMsg=[" + ex.getMessage() + "]" + CR 339 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 340 + "dbid=[" + dbid + "]" + CR 341 + "sql =[" + sql + "]" + CR 342 + "data=[" + data.dataLine() + "]" + CR ; 343 throw new RuntimeException( errMsg,ex ); 344 } 345 if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 346 return data; 347 } 348 349 /** 350 * 内部で使用する PreparedStatement を作成します。 351 * 引数指定の SQL または、LineModel から作成した SQL より構築します。 352 * 353 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属性を追加 354 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 355 * 356 * @param table 処理対象のテーブルID 357 * @param data 処理対象のLineModel 358 * 359 * @return PreparedStatementオブジェクト 360 */ 361 private PreparedStatement makePrepareStatement( final String table,final LineModel data ) { 362 if( sql == null ) { 363 StringBuilder buf = new StringBuilder(); 364 String[] names = data.getNames(); 365 366 // カラムを取り除く場合 367 if( omitClms != null ) { 368 Set<String> set = new HashSet<String>(); 369 for( int i=0; i<names.length; i++ ) { 370 set.add( names[i] ); 371 } 372 for( int i=0; i<omitClms.length; i++ ) { 373 set.remove( omitClms[i] ); 374 } 375 names = set.toArray( new String[set.size()] ); 376 } 377 int size = names.length; 378 379 buf.append( "INSERT INTO " ).append( table ).append( " (" ); 380 buf.append( names[0] ); 381 for( int i=1; i<size; i++ ) { 382 buf.append( "," ).append( names[i] ); 383 } 384 buf.append( " ) VALUES ( ?" ); 385 for( int i=1; i<size; i++ ) { 386 buf.append( ",?" ); 387 } 388 buf.append( " )" ); 389 sql = buf.toString(); 390 391 // カラム番号を設定します。 392 clmNos = new int[size]; 393 for( int i=0; i<size; i++ ) { 394 clmNos[i] = data.getColumnNo( names[i] ); // 4.0.0.0 (2007/09/21) 395 } 396 } 397 else { 398 Formatter format = new Formatter( data ); 399 format.setFormat( sql ); 400 sql = format.getQueryFormatString(); 401 clmNos = format.getClmNos(); 402 } 403 404 final PreparedStatement ps ; 405 try { 406 ps = connection.prepareStatement( sql ); 407 } 408 catch (SQLException ex) { 409 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 410 String errMsg = "PreparedStatement を取得できませんでした。" + CR 411 + "errMsg=[" + ex.getMessage() + "]" + CR 412 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 413 + "dbid =[" + dbid + "]" + CR 414 + "sql =[" + sql + "]" + CR 415 + "table=[" + table + "]" + CR 416 + "data =[" + data.dataLine() + "]" + CR ; 417 throw new RuntimeException( errMsg,ex ); 418 } 419 420 return ps; 421 } 422 423 /** 424 * SQL処理を実行します。 425 * 主に、initSql,endSqlの実行用です。 426 * ここでは、エラーが発生しても、connection は閉じません。 427 * 最終的に、endメソッドで処理されるためです。 428 * 429 * @og.rev 5.7.2.2 (2014/01/24) 新規追加 430 * 431 * @param sql 実行するSQL文 432 */ 433 private void execSql( final String sql ) { 434 Statement stmt = null; 435 try { 436 stmt = connection.createStatement(); 437 stmt.execute( sql ); 438 } 439 catch (SQLException ex) { 440 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 441 String errMsg = "SQL を実行できませんでした。" + CR 442 + "errMsg=[" + ex.getMessage() + "]" + CR 443 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 444 + "dbid=[" + dbid + "]" + CR 445 + "sql =[" + sql + "]" + CR ; 446 throw new RuntimeException( errMsg,ex ); 447 } 448 finally { 449 // connection は、endメソッドで処理されます。 450 Closer.stmtClose( stmt ); 451 } 452 } 453 454 /** 455 * プロセスの処理結果のレポート表現を返します。 456 * 処理プログラム名、入力件数、出力件数などの情報です。 457 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 458 * 形式で出してください。 459 * 460 * @return 処理結果のレポート 461 */ 462 public String report() { 463 String report = "[" + getClass().getName() + "]" + CR 464 + TAB + "DBID : " + dbid + CR 465 + TAB + "Output Count : " + count ; 466 467 return report ; 468 } 469 470 /** 471 * このクラスの使用方法を返します。 472 * 473 * @return このクラスの使用方法 474 */ 475 public String usage() { 476 StringBuilder buf = new StringBuilder(); 477 478 buf.append( "Process_DBWriter は、上流から受け取ったデータをデータベースに書き込む" ).append( CR ); 479 buf.append( "CainProcess インターフェースの実装クラスです。" ).append( CR ); 480 buf.append( CR ); 481 buf.append( "上流(プロセスチェインのデータは上流から下流へと渡されます。)から" ).append( CR ); 482 buf.append( "受け取った LineModel を元に、データベースへの書き込みを行います。" ).append( CR ); 483 buf.append( CR ); 484 buf.append( "データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に" ).append( CR ); 485 buf.append( "設定された接続(Connection)を使用します。" ).append( CR ); 486 buf.append( CR ); 487 buf.append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。" ).append( CR ); 488 buf.append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に" ).append( CR ); 489 buf.append( "繋げてください。" ).append( CR ); 490 buf.append( CR ); 491 buf.append( "SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。" ).append( CR ); 492 buf.append( CR ).append( CR ); 493 buf.append( getArgument().usage() ).append( CR ); 494 495 return buf.toString(); 496 } 497 498 /** 499 * このクラスは、main メソッドから実行できません。 500 * 501 * @param args コマンド引数配列 502 */ 503 public static void main( final String[] args ) { 504 LogWriter.log( new Process_DBWriter().usage() ); 505 } 506}