/* * Copyright (c) 2013 ITOCHU Techno-Solutions Corporation. * * 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 jp.co.ctc_g.jfw.core.jdbc.mybatis; import java.lang.reflect.Field; import java.util.List; import jp.co.ctc_g.jfw.core.internal.InternalException; import org.apache.ibatis.executor.statement.RoutingStatementHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.mapping.StatementType; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.factory.DefaultObjectFactory; import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory; import org.apache.ibatis.type.TypeHandlerRegistry; /** * <p> * MyBatisの{@link StatementHandler}のクエリー情報にアクセスするためのAPIを提供します。 * </p> * @author ITOCHU Techno-Solutions Corporation. */ public class QueryInformation { private String query; private String preparedQuery; private String callableQuery; private SqlCommandType sqlCommandType; private StatementType statementType; private TypeHandlerRegistry typeHandlerRegistry; private StatementHandler statementHandler; private MappedStatement mappedStatement; private BoundSql boundSql; private Object parameterObject; private MetaObject metaObject; private List<ParameterMapping> parameterMappingList; /** * デフォルトコンストラクタです。 */ public QueryInformation() {} /** * コンストラクタです。 * MyBatisの{@link StatementHandler}の解析に失敗した場合に{@link InternalException}をスローします。 * @param statementHandler {@link StatementHandler} */ public QueryInformation(StatementHandler statementHandler) { try { this.typeHandlerRegistry = new TypeHandlerRegistry(); this.statementHandler = getConcreteStatementHandler(statementHandler); this.mappedStatement = getMappedStatement(this.statementHandler); this.boundSql = this.statementHandler.getBoundSql(); this.parameterObject = this.boundSql.getParameterObject(); this.parameterMappingList = boundSql.getParameterMappings(); this.sqlCommandType = mappedStatement.getSqlCommandType(); this.statementType = mappedStatement.getStatementType(); this.metaObject = parameterObject == null ? null : MetaObject.forObject(parameterObject, new DefaultObjectFactory(), new DefaultObjectWrapperFactory()); switch (statementType) { case STATEMENT: this.query = boundSql.getSql(); break; case PREPARED: this.preparedQuery = boundSql.getSql(); break; case CALLABLE: this.callableQuery = boundSql.getSql(); break; default: throw new InternalException(QueryInformation.class, ""); } } catch (Exception e) { throw new InternalException(QueryInformation.class, "E-JDBC-MYBATIS#0002", e); } } /** * SQLを返却します。 * @return SQL */ public String getQuery() { return this.query; } /** * プリペアードクエリを返却します。 * @return プリペアードクエリ */ public String getPreparedQuery() { return this.preparedQuery; } /** * コーラブルクエリを返却します。 * @return コーラブルクエリ */ public String getCallablString() { return this.callableQuery; } /** * SQLのコマンドタイプを返却します。 * @return SQLのコマンドタイプ {@link SqlCommandType} */ public SqlCommandType getSqlCommandType() { return this.sqlCommandType; } /** * ステートメントタイプを返却します。 * @return ステートメントタイプ {@link StatementType} */ public StatementType getStatementType() { return this.statementType; } /** * {@link TypeHandlerRegistry}を返却します。 * @return ステートメントタイプ {@link TypeHandlerRegistry} */ public TypeHandlerRegistry getTypeHandlerRegistry() { return this.typeHandlerRegistry; } /** * コーラブルクエリを返却します。 * @return コーラブルクエリ */ public String getCallableQuery() { return this.callableQuery; } /** * {@link BoundSql}を返却します。 * @return {@link BoundSql} */ public BoundSql getBoundSql() { return this.boundSql; } /** * パラメータを表現するオブジェクトを返却します。 * @return パラメータを表現するオブジェクト */ public Object getParameterObject() { return this.parameterObject; } /** * {@link MetaObject}を返却します。 * @return {@link MetaObject} */ public MetaObject getMetaObject() { return this.metaObject; } /** * {@link ParameterMapping}のリストを返却します。 * @return {@link ParameterMapping}のリスト */ public List<ParameterMapping> getParameterMappingList() { return this.parameterMappingList; } private StatementHandler getConcreteStatementHandler(StatementHandler handler) throws Exception { RoutingStatementHandler routingStatementHandler = (RoutingStatementHandler)handler; Field filed = routingStatementHandler.getClass().getDeclaredField("delegate"); filed.setAccessible(true); return (StatementHandler)filed.get(routingStatementHandler); } private MappedStatement getMappedStatement(StatementHandler handler) throws Exception { Field filed = handler.getClass().getSuperclass().getDeclaredField("mappedStatement"); filed.setAccessible(true); return (MappedStatement)filed.get(handler); } }