Search in sources :

Example 21 with BoundSql

use of org.apache.ibatis.mapping.BoundSql in project mybatis.flying by limeng32.

the class AutoMapperInterceptor method intercept.

@Override
public Object intercept(Invocation invocation) throws Throwable {
    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    MetaObject metaStatementHandler = getRealObj(statementHandler);
    String originalSql = (String) metaStatementHandler.getValue(DELEGATE_BOUNDSQL_SQL);
    Configuration configuration = (Configuration) metaStatementHandler.getValue(DELEGATE_CONFIGURATION);
    Object parameterObject = metaStatementHandler.getValue(DELEGATE_BOUNDSQL_PARAMETEROBJECT);
    FlyingModel flyingModel = CookOriginalSql.fetchFlyingFeature(originalSql);
    MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue(DELEGATE_MAPPEDSTATEMENT);
    if (flyingModel.isHasFlyingFeature()) {
        if ((flyingModel.getDataSourceId() != null) && !((Connection) invocation.getArgs()[0]).getCatalog().equalsIgnoreCase(flyingModel.getConnectionCatalog())) {
            ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
            if (applicationContext != null) {
                DataSource dataSource = (DataSource) applicationContext.getBean(flyingModel.getDataSourceId());
                if (dataSource == null) {
                    throw new AutoMapperException(AutoMapperExceptionEnum.cannotFindAssignedDataSourceInContext.description());
                }
                Connection connection = ((SmartDataSource) (applicationContext.getBean(flyingModel.getDataSourceId()))).getConnection();
                invocation.getArgs()[0] = connection;
            } else {
                throw new AutoMapperException(AutoMapperExceptionEnum.cannotFindApplicationContextProvider.description());
            }
        }
        String newSql = "";
        switch(flyingModel.getActionType()) {
            case count:
                newSql = SqlBuilder.buildCountSql(parameterObject);
                break;
            case delete:
                newSql = SqlBuilder.buildDeleteSql(parameterObject);
                break;
            case insert:
                newSql = SqlBuilder.buildInsertSql(parameterObject, flyingModel);
                break;
            case select:
                newSql = SqlBuilder.buildSelectSql(mappedStatement.getResultMaps().get(0).getType(), flyingModel);
                break;
            case selectAll:
                newSql = SqlBuilder.buildSelectAllSql(parameterObject, flyingModel);
                break;
            case selectOne:
                newSql = SqlBuilder.buildSelectOneSql(parameterObject, flyingModel);
                break;
            case update:
                newSql = SqlBuilder.buildUpdateSql(parameterObject, flyingModel);
                break;
            case updatePersistent:
                newSql = SqlBuilder.buildUpdatePersistentSql(parameterObject, flyingModel);
                break;
            default:
                break;
        }
        logger.warn(new StringBuffer("Auto generated sql:").append(newSql).toString());
        SqlSource sqlSource = buildSqlSource(configuration, newSql, parameterObject.getClass());
        List<ParameterMapping> parameterMappings = sqlSource.getBoundSql(parameterObject).getParameterMappings();
        metaStatementHandler.setValue(DELEGATE_BOUNDSQL_SQL, sqlSource.getBoundSql(parameterObject).getSql());
        metaStatementHandler.setValue(DELEGATE_BOUNDSQL_PARAMETERMAPPINGS, parameterMappings);
    }
    /* 开始处理分页问题 */
    if (invocation.getTarget() instanceof RoutingStatementHandler) {
        BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, DELEGATE);
        mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate, MAPPEDSTATEMENT);
        BoundSql boundSql = delegate.getBoundSql();
        if (parameterObject == null) {
            throw new AutoMapperException(AutoMapperExceptionEnum.parameterObjectIsNull);
        } else if (parameterObject instanceof Conditionable) {
            Conditionable condition = (Conditionable) parameterObject;
            String sql = boundSql.getSql();
            if (condition.getLimiter() != null) {
                Connection connection = (Connection) invocation.getArgs()[0];
                String countSql = new StringBuffer("select count(0) from (").append(sql).append(") myCount").toString();
                PreparedStatement countStmt = connection.prepareStatement(countSql);
                BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject);
                setParameters(countStmt, mappedStatement, countBS, parameterObject);
                ResultSet rs = countStmt.executeQuery();
                int count = 0;
                if (rs.next()) {
                    count = rs.getInt(1);
                }
                rs.close();
                countStmt.close();
                condition.getLimiter().setTotalCount(count);
            }
            String pageSql = generatePageSql(sql, condition);
            ReflectHelper.setValueByFieldName(boundSql, SQL, pageSql);
        } else {
        }
    }
    /* 调用原始statementHandler的prepare方法完成原本的逻辑 */
    statementHandler = (StatementHandler) metaStatementHandler.getOriginalObject();
    statementHandler.prepare((Connection) invocation.getArgs()[0], mappedStatement.getTimeout());
    /* 传递给下一个拦截器处理 */
    return invocation.proceed();
}
Also used : FlyingModel(indi.mybatis.flying.models.FlyingModel) Conditionable(indi.mybatis.flying.models.Conditionable) SqlSource(org.apache.ibatis.mapping.SqlSource) Configuration(org.apache.ibatis.session.Configuration) MetaObject(org.apache.ibatis.reflection.MetaObject) Connection(java.sql.Connection) RoutingStatementHandler(org.apache.ibatis.executor.statement.RoutingStatementHandler) PreparedStatement(java.sql.PreparedStatement) SmartDataSource(org.springframework.jdbc.datasource.SmartDataSource) DataSource(javax.sql.DataSource) SmartDataSource(org.springframework.jdbc.datasource.SmartDataSource) ApplicationContext(org.springframework.context.ApplicationContext) AutoMapperException(indi.mybatis.flying.exception.AutoMapperException) ParameterMapping(org.apache.ibatis.mapping.ParameterMapping) BaseStatementHandler(org.apache.ibatis.executor.statement.BaseStatementHandler) BoundSql(org.apache.ibatis.mapping.BoundSql) BaseStatementHandler(org.apache.ibatis.executor.statement.BaseStatementHandler) StatementHandler(org.apache.ibatis.executor.statement.StatementHandler) RoutingStatementHandler(org.apache.ibatis.executor.statement.RoutingStatementHandler) ResultSet(java.sql.ResultSet) MetaObject(org.apache.ibatis.reflection.MetaObject) MappedStatement(org.apache.ibatis.mapping.MappedStatement)

Example 22 with BoundSql

use of org.apache.ibatis.mapping.BoundSql in project mybatis-paginator by HuQingmiao.

the class OffsetLimitInterceptor method intercept.

public Object intercept(final Invocation invocation) throws Throwable {
    final Executor executor = (Executor) invocation.getTarget();
    final Object[] queryArgs = invocation.getArgs();
    final MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
    final Object parameter = queryArgs[PARAMETER_INDEX];
    final RowBounds rowBounds = (RowBounds) queryArgs[ROWBOUNDS_INDEX];
    //DAO接口中没有传PageBounds参量
    if (!(rowBounds instanceof PageBounds)) {
        return invocation.proceed();
    }
    //DAO接口传有PageBounds参量
    PageBounds pageBounds = (PageBounds) rowBounds;
    if (pageBounds.notValid()) {
        return new PageList((List) invocation.proceed());
    }
    final Dialect dialect;
    try {
        Class clazz = Class.forName(dialectClass);
        Constructor constructor = clazz.getConstructor(MappedStatement.class, Object.class, PageBounds.class);
        dialect = (Dialect) constructor.newInstance(new Object[] { ms, parameter, pageBounds });
    } catch (Exception e) {
        throw new ClassNotFoundException("Cannot create dialect instance: " + dialectClass, e);
    }
    final BoundSql boundSql = ms.getBoundSql(parameter);
    queryArgs[MAPPED_STATEMENT_INDEX] = copyFromNewSql(ms, boundSql, dialect.getPageSQL(), dialect.getParameterMappings(), dialect.getParameterObject());
    queryArgs[PARAMETER_INDEX] = dialect.getParameterObject();
    queryArgs[ROWBOUNDS_INDEX] = new RowBounds();
    //采用同步方式,执行分页查询
    //修复bug: 提交后台线程破坏了spring 事务管理,参见TransactionSynchronizationManager
    Callable<List> queryThread = new Callable<List>() {

        public List call() throws Exception {
            return (List) invocation.proceed();
        }
    };
    Future<List> queryFuture = call(queryThread, false);
    //如果不需要count总的结果集,则直接返回分页查询结果
    if (!pageBounds.isIfCount()) {
        return new PageList(queryFuture.get());
    }
    //对总的结果集进行count
    Callable<Integer> countThread = new Callable<Integer>() {

        public Integer call() throws Exception {
            Cache cache = ms.getCache();
            Integer count = null;
            if (cache != null && ms.isUseCache() && ms.getConfiguration().isCacheEnabled()) {
                CacheKey cacheKey = executor.createCacheKey(ms, parameter, new RowBounds(), copyFromBoundSql(ms, boundSql, dialect.getCountSQL(), boundSql.getParameterMappings(), boundSql.getParameterObject()));
                count = (Integer) cache.getObject(cacheKey);
                if (count == null) {
                    count = SQLHelp.getCount(ms, parameter, boundSql, dialect);
                    cache.putObject(cacheKey, count);
                }
            } else {
                count = SQLHelp.getCount(ms, parameter, boundSql, dialect);
            }
            return count;
        }
    };
    Future<Integer> countFutrue = call(countThread, false);
    return new PageList(queryFuture.get(), countFutrue.get().intValue());
}
Also used : Constructor(java.lang.reflect.Constructor) RowBounds(org.apache.ibatis.session.RowBounds) Executor(org.apache.ibatis.executor.Executor) BoundSql(org.apache.ibatis.mapping.BoundSql) Dialect(com.github.walker.mybatis.paginator.dialect.Dialect) List(java.util.List) MappedStatement(org.apache.ibatis.mapping.MappedStatement) CacheKey(org.apache.ibatis.cache.CacheKey) Cache(org.apache.ibatis.cache.Cache)

Example 23 with BoundSql

use of org.apache.ibatis.mapping.BoundSql in project mybatis-3 by mybatis.

the class BatchExecutor method doUpdate.

@Override
public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
    final Configuration configuration = ms.getConfiguration();
    final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
    final BoundSql boundSql = handler.getBoundSql();
    final String sql = boundSql.getSql();
    final Statement stmt;
    if (sql.equals(currentSql) && ms.equals(currentStatement)) {
        int last = statementList.size() - 1;
        stmt = statementList.get(last);
        applyTransactionTimeout(stmt);
        //fix Issues 322
        handler.parameterize(stmt);
        BatchResult batchResult = batchResultList.get(last);
        batchResult.addParameterObject(parameterObject);
    } else {
        Connection connection = getConnection(ms.getStatementLog());
        stmt = handler.prepare(connection, transaction.getTimeout());
        //fix Issues 322
        handler.parameterize(stmt);
        currentSql = sql;
        currentStatement = ms;
        statementList.add(stmt);
        batchResultList.add(new BatchResult(ms, sql, parameterObject));
    }
    // handler.parameterize(stmt);
    handler.batch(stmt);
    return BATCH_UPDATE_RETURN_VALUE;
}
Also used : Configuration(org.apache.ibatis.session.Configuration) BoundSql(org.apache.ibatis.mapping.BoundSql) MappedStatement(org.apache.ibatis.mapping.MappedStatement) Statement(java.sql.Statement) StatementHandler(org.apache.ibatis.executor.statement.StatementHandler) Connection(java.sql.Connection)

Example 24 with BoundSql

use of org.apache.ibatis.mapping.BoundSql in project mybatis-3 by mybatis.

the class DefaultResultSetHandler method getNestedQueryMappingValue.

private Object getNestedQueryMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {
    final String nestedQueryId = propertyMapping.getNestedQueryId();
    final String property = propertyMapping.getProperty();
    final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
    final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
    final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, propertyMapping, nestedQueryParameterType, columnPrefix);
    Object value = null;
    if (nestedQueryParameterObject != null) {
        final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
        final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
        final Class<?> targetType = propertyMapping.getJavaType();
        if (executor.isCached(nestedQuery, key)) {
            executor.deferLoad(nestedQuery, metaResultObject, property, key, targetType);
            value = DEFERED;
        } else {
            final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
            if (propertyMapping.isLazy()) {
                lazyLoader.addLoader(property, metaResultObject, resultLoader);
                value = DEFERED;
            } else {
                value = resultLoader.loadResult();
            }
        }
    }
    return value;
}
Also used : ResultLoader(org.apache.ibatis.executor.loader.ResultLoader) BoundSql(org.apache.ibatis.mapping.BoundSql) MetaObject(org.apache.ibatis.reflection.MetaObject) MappedStatement(org.apache.ibatis.mapping.MappedStatement) CacheKey(org.apache.ibatis.cache.CacheKey)

Example 25 with BoundSql

use of org.apache.ibatis.mapping.BoundSql in project mybatis-3 by mybatis.

the class ReuseExecutor method prepareStatement.

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
    Statement stmt;
    BoundSql boundSql = handler.getBoundSql();
    String sql = boundSql.getSql();
    if (hasStatementFor(sql)) {
        stmt = getStatement(sql);
        applyTransactionTimeout(stmt);
    } else {
        Connection connection = getConnection(statementLog);
        stmt = handler.prepare(connection, transaction.getTimeout());
        putStatement(sql, stmt);
    }
    handler.parameterize(stmt);
    return stmt;
}
Also used : BoundSql(org.apache.ibatis.mapping.BoundSql) MappedStatement(org.apache.ibatis.mapping.MappedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection)

Aggregations

BoundSql (org.apache.ibatis.mapping.BoundSql)39 Test (org.junit.Test)24 BaseDataTest (org.apache.ibatis.BaseDataTest)23 DynamicSqlSource (org.apache.ibatis.scripting.xmltags.DynamicSqlSource)23 TextSqlNode (org.apache.ibatis.scripting.xmltags.TextSqlNode)23 Configuration (org.apache.ibatis.session.Configuration)18 IfSqlNode (org.apache.ibatis.scripting.xmltags.IfSqlNode)17 MappedStatement (org.apache.ibatis.mapping.MappedStatement)12 WhereSqlNode (org.apache.ibatis.scripting.xmltags.WhereSqlNode)10 CacheKey (org.apache.ibatis.cache.CacheKey)8 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 Executor (org.apache.ibatis.executor.Executor)5 MetaObject (org.apache.ibatis.reflection.MetaObject)5 RowBounds (org.apache.ibatis.session.RowBounds)5 ResultHandler (org.apache.ibatis.session.ResultHandler)4 Connection (java.sql.Connection)3 Map (java.util.Map)3 SqlSource (org.apache.ibatis.mapping.SqlSource)3 ChooseSqlNode (org.apache.ibatis.scripting.xmltags.ChooseSqlNode)3