private Class<?> getParameterType(Method method) { Class<?> parameterType = null; Class<?>[] parameterTypes = method.getParameterTypes(); for (Class<?> currentParameterType : parameterTypes) { if (!RowBounds.class.isAssignableFrom(currentParameterType) && !ResultHandler.class.isAssignableFrom(currentParameterType)) { if (parameterType == null) { parameterType = currentParameterType; } else { // issue #135 parameterType = ParamMap.class; } } } return parameterType; }
@Override public List<NodePropertyEntity> selectNodePropertiesByTypes(Set<QName> qnames) { final List<NodePropertyEntity> properties = new ArrayList<NodePropertyEntity>(); // qnames of properties that are encrypted Set<Long> qnameIds = qnameDAO.convertQNamesToIds(qnames, false); if(qnameIds.size() > 0) { IdsEntity param = new IdsEntity(); param.setIds(new ArrayList<Long>(qnameIds)); // TODO - use a callback approach template.select(SELECT_PROPERTIES_BY_TYPES, param, new ResultHandler() { @Override public void handleResult(ResultContext context) { properties.add((NodePropertyEntity)context.getResultObject()); } }); } return properties; }
@Override public List<NodePropertyEntity> selectNodePropertiesByDataType(QName dataType, long minNodeId, long maxNodeId) { int typeOrdinal = NodePropertyValue.convertToTypeOrdinal(dataType); IdsEntity ids = new IdsEntity(); ids.setIdOne((long)typeOrdinal); ids.setIdTwo(minNodeId); ids.setIdThree(maxNodeId); final List<NodePropertyEntity> properties = new ArrayList<NodePropertyEntity>(); template.select(SELECT_PROPERTIES_BY_ACTUAL_TYPE, ids, new ResultHandler() { @Override public void handleResult(ResultContext context) { properties.add((NodePropertyEntity)context.getResultObject()); } }); return properties; }
@Override protected void selectNodesWithAspects( List<Long> qnameIds, Long minNodeId, Long maxNodeId, final NodeRefQueryCallback resultsCallback) { ResultHandler resultHandler = new ResultHandler() { public void handleResult(ResultContext context) { NodeEntity entity = (NodeEntity) context.getResultObject(); Pair<Long, NodeRef> nodePair = new Pair<Long, NodeRef>(entity.getId(), entity.getNodeRef()); resultsCallback.handle(nodePair); } }; IdsEntity parameters = new IdsEntity(); parameters.setIdOne(minNodeId); parameters.setIdTwo(maxNodeId); parameters.setIds(qnameIds); template.select(SELECT_NODES_WITH_ASPECT_IDS, parameters, resultHandler); }
/** * @param keyProperties the properties that make up the unique key * @param collectionProperty the property mapped using a nested <b>ResultMap</b> * @param resultHandler the result handler that will receive the rolled-up results * @param maxResults the maximum number of results to retrieve (-1 for no limit). * Make sure that the query result limit is large enough to produce this * at least this number of results */ public RollupResultHandler(Configuration configuration, String[] keyProperties, String collectionProperty, ResultHandler resultHandler, int maxResults) { if (keyProperties == null || keyProperties.length == 0) { throw new IllegalArgumentException("RollupRowHandler can only be used with at least one key property."); } if (collectionProperty == null) { throw new IllegalArgumentException("RollupRowHandler must have a collection property."); } this.configuration = configuration; this.keyProperties = keyProperties; this.collectionProperty = collectionProperty; this.resultHandler = resultHandler; this.maxResults = maxResults; this.rawResults = new ArrayList<Object>(100); }
/** * 通过Mapper接口和方法名 * @param session * @param mapperInterface * @param methodName * @param args * @return */ public static String getMapperSql(SqlSession session, Class mapperInterface, String methodName, Object... args) { String fullMapperMethodName = mapperInterface.getCanonicalName() + "." + methodName; if (args == null || args.length == 0) { return getNamespaceSql(session, fullMapperMethodName, null); } Method method = getDeclaredMethods(mapperInterface, methodName); Map params = new HashMap(); final Class<?>[] argTypes = method.getParameterTypes(); for (int i = 0; i < argTypes.length; i++) { if (!RowBounds.class.isAssignableFrom(argTypes[i]) && !ResultHandler.class.isAssignableFrom(argTypes[i])) { String paramName = "param" + String.valueOf(params.size() + 1); paramName = getParamNameFromAnnotation(method, i, paramName); params.put(paramName, i >= args.length ? null : args[i]); } } if (useParameter(method, args)) { return getNamespaceSql(session, fullMapperMethodName, args[0]); } return getNamespaceSql(session, fullMapperMethodName, params); }
@SuppressWarnings("rawtypes") private Long executeQueryCount(Executor executor, MappedStatement countMs, Object parameter, BoundSql boundSql, RowBounds rowBounds, ResultHandler resultHandler) throws IllegalAccessException, SQLException { CacheKey countKey = executor.createCacheKey(countMs, parameter, RowBounds.DEFAULT, boundSql); String orignSql = boundSql.getSql().replaceAll(";$", ""); // count sql String countSql = PageSqlUtils.getCountSql(orignSql); BoundSql countBoundSql = new BoundSql(countMs.getConfiguration(), countSql, boundSql.getParameterMappings(), parameter); // 执行 count 查询 Object countResultList = executor.query(countMs, parameter, RowBounds.DEFAULT, resultHandler, countKey, countBoundSql); Long count = (Long) ((List) countResultList).get(0); return count; }
public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) { Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface); if (resolvedReturnType instanceof Class<?>) { this.returnType = (Class<?>) resolvedReturnType; } else if (resolvedReturnType instanceof ParameterizedType) { this.returnType = (Class<?>) ((ParameterizedType) resolvedReturnType).getRawType(); } else { this.returnType = method.getReturnType(); } this.returnsVoid = void.class.equals(this.returnType); this.returnsMany = (configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray()); this.returnsCursor = Cursor.class.equals(this.returnType); this.mapKey = getMapKey(method); this.returnsMap = (this.mapKey != null); this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class); this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class); this.paramNameResolver = new ParamNameResolver(configuration, method); }
@Override public <E> List<E> doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Statement stmt = null; try { flushStatements(); Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql); Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection, transaction.getTimeout()); handler.parameterize(stmt); return handler.<E>query(stmt, resultHandler); } finally { closeStatement(stmt); } }
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { switch (ms.getStatementType()) { case STATEMENT: delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; case PREPARED: delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; case CALLABLE: delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; default: throw new ExecutorException("Unknown statement type: " + ms.getStatementType()); } }
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { this.configuration = mappedStatement.getConfiguration(); this.executor = executor; this.mappedStatement = mappedStatement; this.rowBounds = rowBounds; this.typeHandlerRegistry = configuration.getTypeHandlerRegistry(); this.objectFactory = configuration.getObjectFactory(); if (boundSql == null) { // issue #435, get the key before calculating the statement generateKeys(parameterObject); boundSql = mappedStatement.getBoundSql(parameterObject); } this.boundSql = boundSql; this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql); this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql); }
@Override public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { Cache cache = ms.getCache(); if (cache != null) { flushCacheIfRequired(ms); if (ms.isUseCache() && resultHandler == null) { ensureNoOutParams(ms, parameterObject, boundSql); @SuppressWarnings("unchecked") List<E> list = (List<E>) tcm.getObject(cache, key); if (list == null) { list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); tcm.putObject(cache, key, list); // issue #578 and #116 } return list; } } return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }
@Test public void testDeferLoadDuringResultHandler() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { class MyResultHandler implements ResultHandler { @Override public void handleResult(ResultContext context) { Child child = (Child)context.getResultObject(); assertNotNull(child.getFather()); } }; sqlSession.select("org.apache.ibatis.submitted.deferload_common_property.ChildMapper.selectAll", new MyResultHandler()); } finally { sqlSession.close(); } }
@Test public void testDeferLoadDuringResultHandlerWithLazyLoad() { SqlSession sqlSession = lazyLoadSqlSessionFactory.openSession(); try { class MyResultHandler implements ResultHandler { @Override public void handleResult(ResultContext context) { Child child = (Child)context.getResultObject(); assertNotNull(child.getFather()); } }; sqlSession.select("org.apache.ibatis.submitted.deferload_common_property.ChildMapper.selectAll", new MyResultHandler()); } finally { sqlSession.close(); } }
@Test(expected=PersistenceException.class) public void testUnorderedGetPersonWithHandler() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.select("getPersonsWithItemsOrdered", new ResultHandler() { public void handleResult(ResultContext context) { Person person = (Person) context.getResultObject(); if ("grandma".equals(person.getName())) { Assert.assertEquals(2, person.getItems().size()); } } }); } finally { sqlSession.close(); } }
@Test public void shouldHandleRowBounds() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); Date targetMonth = fmt.parse("2014-01-01"); final List<Account> accounts = new ArrayList<Account>(); try { sqlSession.select("collectPageByBirthMonth", targetMonth, new RowBounds(1, 2), new ResultHandler() { @Override public void handleResult(ResultContext context) { Account account = (Account) context.getResultObject(); accounts.add(account); } }); } finally { sqlSession.close(); } assertEquals(2, accounts.size()); assertEquals("Bob2", accounts.get(0).getAccountName()); assertEquals("Bob3", accounts.get(1).getAccountName()); }
@Test public void shouldHandleStop() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); final List<Account> accounts = new ArrayList<Account>(); try { Date targetMonth = fmt.parse("2014-01-01"); sqlSession.select("collectPageByBirthMonth", targetMonth, new ResultHandler() { @Override public void handleResult(ResultContext context) { Account account = (Account) context.getResultObject(); accounts.add(account); if (accounts.size() > 1) context.stop(); } }); } finally { sqlSession.close(); } assertEquals(2, accounts.size()); assertEquals("Bob1", accounts.get(0).getAccountName()); assertEquals("Bob2", accounts.get(1).getAccountName()); }
public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) { Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface); if (resolvedReturnType instanceof Class<?>) { this.returnType = (Class<?>) resolvedReturnType; } else if (resolvedReturnType instanceof ParameterizedType) { this.returnType = (Class<?>) ((ParameterizedType) resolvedReturnType).getRawType(); } else { this.returnType = method.getReturnType(); } this.returnsVoid = void.class.equals(this.returnType); this.returnsMany = (configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray()); this.returnsCursor = Cursor.class.equals(this.returnType); this.mapKey = getMapKey(method); this.returnsMap = (this.mapKey != null); this.hasNamedParameters = hasNamedParams(method); this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class); this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class); this.params = Collections.unmodifiableSortedMap(getParams(method, this.hasNamedParameters)); }
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; // 源码解析: 填充本地缓存 localCache.putObject(key, EXECUTION_PLACEHOLDER); try { // 源码解析: 查询结果集 list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { // 源码解析: 清除本地缓存 localCache.removeObject(key); } // 源码解析: 查询结果集放入本地缓存 localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
@Test // issue #542 public void testGetPersonWithHandler() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.select("getPersons", new ResultHandler() { public void handleResult(ResultContext context) { Person person = (Person) context.getResultObject(); if ("grandma".equals(person.getName())) { Assert.assertEquals(2, person.getItems().size()); } } }); } finally { sqlSession.close(); } }
@Override protected void findPropertiesByIds(List<Long> ids, final PropertyFinderCallback callback) { ResultHandler valueResultHandler = new ResultHandler() { public void handleResult(ResultContext context) { PropertyIdQueryResult result = (PropertyIdQueryResult) context.getResultObject(); Long id = result.getPropId(); // Make the serializable value List<PropertyIdSearchRow> rows = result.getPropValues(); Serializable value = convertPropertyIdSearchRows(rows); callback.handleProperty(id, value); } }; // A row handler to roll up individual rows Configuration configuration = template.getConfiguration(); RollupResultHandler rollupResultHandler = new RollupResultHandler( configuration, KEY_COLUMNS_FINDBYIDS, "propValues", valueResultHandler); // Query using the IDs PropertyIdQueryParameter params = new PropertyIdQueryParameter(); params.setRootPropIds(ids); template.select(SELECT_PROPERTIES_BY_IDS, params, rollupResultHandler); // Process any remaining results rollupResultHandler.processLastResults(); // Done }
@Override public Pair<Long, Long> getNodeIdsIntervalForType(QName type, Long startTxnTime, Long endTxnTime) { final Pair<Long, Long> intervalPair = new Pair<Long, Long>(LONG_ZERO, LONG_ZERO); Pair<Long, QName> typePair = qnameDAO.getQName(type); if (typePair == null) { // Return default return intervalPair; } TransactionQueryEntity txnQuery = new TransactionQueryEntity(); txnQuery.setTypeQNameId(typePair.getFirst()); txnQuery.setMinCommitTime(startTxnTime); txnQuery.setMaxCommitTime(endTxnTime); ResultHandler resultHandler = new ResultHandler() { @SuppressWarnings("unchecked") public void handleResult(ResultContext context) { Map<Long, Long> result = (Map<Long, Long>) context.getResultObject(); if (result != null) { intervalPair.setFirst(result.get("minId")); intervalPair.setSecond(result.get("maxId")); } } }; template.select(SELECT_NODE_INTERVAL_BY_TYPE, txnQuery, resultHandler); return intervalPair; }
@Override public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) { try { MappedStatement ms = configuration.getMappedStatement(statement); executor.query(ms, wrapCollection(parameter), rowBounds, handler); } catch (Exception e) { throw SQLExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
@SuppressWarnings("unchecked") @Override public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if (closed) { throw new ExecutorException("Executor was closed."); } if (queryStack == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List<E> list; try { queryStack++; list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; if (list != null) { handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } // issue #601 deferredLoads.clear(); if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { // issue #482 clearLocalCache(); } } return list; }
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql, RowBounds rowBounds) { this.executor = executor; this.configuration = mappedStatement.getConfiguration(); this.mappedStatement = mappedStatement; this.rowBounds = rowBounds; this.parameterHandler = parameterHandler; this.boundSql = boundSql; this.typeHandlerRegistry = configuration.getTypeHandlerRegistry(); this.objectFactory = configuration.getObjectFactory(); this.reflectorFactory = configuration.getReflectorFactory(); this.resultHandler = resultHandler; }
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException { if (resultMap.hasNestedResultMaps()) { ensureNoRowBounds(); checkResultHandler(); handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping); } else { handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping); } }
private void storeObject(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue, ResultMapping parentMapping, ResultSet rs) throws SQLException { if (parentMapping != null) { linkToParents(rs, parentMapping, rowValue); } else { callResultHandler(resultHandler, resultContext, rowValue); } }
@Override public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql); Statement stmt = prepareStatement(handler, ms.getStatementLog()); return handler.<E>query(stmt, resultHandler); }