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();
}
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());
}
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;
}
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;
}
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;
}
Aggregations