/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.extension.jdbc.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.sql.DataSource; import org.seasar.extension.jdbc.SqlLog; import org.seasar.extension.jdbc.SqlLogRegistry; import org.seasar.extension.jdbc.SqlLogRegistryLocator; import org.seasar.extension.jdbc.StatementFactory; import org.seasar.extension.jdbc.ValueType; import org.seasar.extension.jdbc.types.ValueTypes; import org.seasar.extension.jdbc.util.BindVariableUtil; import org.seasar.extension.jdbc.util.DataSourceUtil; import org.seasar.framework.exception.EmptyRuntimeException; import org.seasar.framework.exception.SQLRuntimeException; import org.seasar.framework.log.Logger; /** * SQL文を実行するための基本的なクラスです。 * * @author higa * */ public class BasicHandler { private DataSource dataSource; private String sql; private StatementFactory statementFactory = BasicStatementFactory.INSTANCE; /** * ログで使われるクラスです。 */ protected Class loggerClass = BasicHandler.class; /** * {@link BasicHandler}を作成します。 */ public BasicHandler() { } /** * {@link BasicHandler}を作成します。 * * @param ds * データソース * @param sql * SQL */ public BasicHandler(DataSource ds, String sql) { this(ds, sql, BasicStatementFactory.INSTANCE); } /** * {@link BasicHandler}を作成します。 * * @param ds * データソース * @param sql * SQL * @param statementFactory * ステートメントファクトリ */ public BasicHandler(DataSource ds, String sql, StatementFactory statementFactory) { setDataSource(ds); setSql(sql); setStatementFactory(statementFactory); } /** * データソースを返します。 * * @return データソース */ public DataSource getDataSource() { return dataSource; } /** * データソースを設定します。 * * @param dataSource * データソース */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * SQLを返します。 * * @return SQL */ public String getSql() { return sql; } /** * SQLを設定します。 * * @param sql * SQL */ public void setSql(String sql) { this.sql = sql; } /** * ステートメントファクトリを返します。 * * @return ステートメントファクトリ */ public StatementFactory getStatementFactory() { return statementFactory; } /** * ステートメントファクトリを設定します。 * * @param statementFactory * ステートメントファクトリ */ public void setStatementFactory(StatementFactory statementFactory) { this.statementFactory = statementFactory; } /** * コネクションを返します。 * * @return コネクション */ protected Connection getConnection() { if (dataSource == null) { throw new EmptyRuntimeException("dataSource"); } return DataSourceUtil.getConnection(dataSource); } /** * 準備されたステートメントを返します。 * * @param connection * コネクション * @return 準備されたステートメント */ protected PreparedStatement prepareStatement(Connection connection) { if (sql == null) { throw new EmptyRuntimeException("sql"); } return statementFactory.createPreparedStatement(connection, sql); } /** * 引数をバインドします。 * * @param ps * 準備されたステートメント * @param args * 引数 * @param argTypes * 引数のタイプ */ protected void bindArgs(PreparedStatement ps, Object[] args, Class[] argTypes) { if (args == null) { return; } for (int i = 0; i < args.length; ++i) { ValueType valueType = getValueType(argTypes[i]); try { valueType.bindValue(ps, i + 1, args[i]); } catch (SQLException ex) { throw new SQLRuntimeException(ex); } } } /** * 引数の型を返します。 * * @param args * 引数 * @return 引数の型 */ protected Class[] getArgTypes(Object[] args) { if (args == null) { return null; } Class[] argTypes = new Class[args.length]; for (int i = 0; i < args.length; ++i) { Object arg = args[i]; if (arg != null) { argTypes[i] = arg.getClass(); } } return argTypes; } /** * 完全なSQL文を返します。 * * @param args * 引数 * @return 完全なSQL文 */ protected String getCompleteSql(Object[] args) { return BindVariableUtil.getCompleteSql(sql, args); } /** * バインド変数を文字列として返します。 * * @param bindVariable * バインド変数 * @return バインド変数の文字列表現 */ protected String getBindVariableText(Object bindVariable) { return BindVariableUtil.getBindVariableText(bindVariable); } /** * S2JDBC用の値の型を返します。 * * @param clazz * クラス * @return S2JDBC用の値の型 */ protected ValueType getValueType(Class clazz) { return ValueTypes.getValueType(clazz); } /** * SQLをログ出力します。 * * @param args * SQLにバインドされる値の配列 * @param argTypes * SQLにバインドされる値の型の配列 */ protected void logSql(Object[] args, Class[] argTypes) { Logger logger = Logger.getLogger(loggerClass); SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance(); if (logger.isDebugEnabled() || sqlLogRegistry != null) { String completeSql = getCompleteSql(args); if (logger.isDebugEnabled()) { logger.debug(completeSql); } if (sqlLogRegistry != null) { SqlLog sqlLog = new SqlLogImpl(getSql(), completeSql, args, argTypes); sqlLogRegistry.add(sqlLog); } } } /** * ログ用のクラスを返します。 * * @return ログ用のクラス */ public Class getLoggerClass() { return loggerClass; } /** * ログ用のクラスを設定します。 * * @param loggerClass * ログ用のクラス */ public void setLoggerClass(Class loggerClass) { this.loggerClass = loggerClass; } }