private void pagination(Invocation invocation, StatementHandler target) throws SQLException {
   final MetaObject metaStatementHandler = getMetaObject(target);
   final BoundSql boundSql = target.getBoundSql();
   Page<?> page = PAGE_THREAD_LOCAL.get();
   if (page == null) {
     page = findPageParameter(boundSql.getParameterObject());
   }
   // 如果传入的参数中有分页对象且sql语句中有select,才做分页处理
   String sql = boundSql.getSql().toLowerCase();
   if (sql.startsWith("select") && page != null) {
     // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
     metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
     metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
     // 设置分页对象里的总记录数和总页数
     Connection connection = (Connection) invocation.getArgs()[0];
     MappedStatement mappedStatement =
         (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
     if (page.isCountTotal()) {
       int recordsTotal = getTotalCount(sql, connection, mappedStatement, boundSql);
       page.setTotalNum(recordsTotal);
     }
     // 最后重写sql
     String pageSql = buildPageSql(sql, page);
     metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
   }
 }
 private boolean applyNestedResultMappings(
     ResultSetWrapper rsw,
     ResultMap resultMap,
     MetaObject metaObject,
     String parentPrefix,
     CacheKey parentRowKey,
     boolean newObject) {
   boolean foundValues = false;
   for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
     final String nestedResultMapId = resultMapping.getNestedResultMapId();
     if (nestedResultMapId != null && resultMapping.getResultSet() == null) {
       try {
         final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
         final ResultMap nestedResultMap =
             getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
         CacheKey rowKey = null;
         Object ancestorObject = null;
         if (ancestorColumnPrefix.containsKey(nestedResultMapId)) {
           rowKey =
               createRowKey(nestedResultMap, rsw, ancestorColumnPrefix.get(nestedResultMapId));
           ancestorObject = ancestorObjects.get(rowKey);
         }
         if (ancestorObject != null) {
           if (newObject) metaObject.setValue(resultMapping.getProperty(), ancestorObject);
         } else {
           rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
           final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
           Object rowValue = nestedResultObjects.get(combinedKey);
           boolean knownValue = (rowValue != null);
           final Object collectionProperty =
               instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
           if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) {
             rowValue =
                 getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue);
             if (rowValue != null && !knownValue) {
               if (collectionProperty != null) {
                 final MetaObject targetMetaObject =
                     configuration.newMetaObject(collectionProperty);
                 targetMetaObject.add(rowValue);
               } else {
                 metaObject.setValue(resultMapping.getProperty(), rowValue);
               }
               foundValues = true;
             }
           }
         }
       } catch (SQLException e) {
         throw new ExecutorException(
             "Error getting nested result map values for '"
                 + resultMapping.getProperty()
                 + "'.  Cause: "
                 + e,
             e);
       }
     }
   }
   return foundValues;
 }
예제 #3
0
 private void setCacheProperties(Cache cache) {
   if (properties != null) {
     MetaObject metaCache = SystemMetaObject.forObject(cache);
     for (Map.Entry<Object, Object> entry : properties.entrySet()) {
       String name = (String) entry.getKey();
       String value = (String) entry.getValue();
       if (metaCache.hasSetter(name)) {
         Class<?> type = metaCache.getSetterType(name);
         if (String.class == type) {
           metaCache.setValue(name, value);
         } else if (int.class == type || Integer.class == type) {
           metaCache.setValue(name, Integer.valueOf(value));
         } else if (long.class == type || Long.class == type) {
           metaCache.setValue(name, Long.valueOf(value));
         } else if (short.class == type || Short.class == type) {
           metaCache.setValue(name, Short.valueOf(value));
         } else if (byte.class == type || Byte.class == type) {
           metaCache.setValue(name, Byte.valueOf(value));
         } else if (float.class == type || Float.class == type) {
           metaCache.setValue(name, Float.valueOf(value));
         } else if (boolean.class == type || Boolean.class == type) {
           metaCache.setValue(name, Boolean.valueOf(value));
         } else if (double.class == type || Double.class == type) {
           metaCache.setValue(name, Double.valueOf(value));
         } else {
           throw new CacheException(
               "Unsupported property type for cache: '" + name + "' of type " + type);
         }
       }
     }
   }
 }
예제 #4
0
 private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
   try {
     if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
       String keyProperty =
           keyStatement.getKeyProperties()[0]; // just one key property is supported
       final Configuration configuration = ms.getConfiguration();
       final MetaObject metaParam = configuration.newMetaObject(parameter);
       if (keyProperty != null && metaParam.hasSetter(keyProperty)) {
         // Do not close keyExecutor.
         // The transaction will be closed by parent executor.
         Executor keyExecutor =
             configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
         List<Object> values =
             keyExecutor.query(
                 keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
         if (values.size() == 0) {
           throw new ExecutorException("SelectKey returned no data.");
         } else if (values.size() > 1) {
           throw new ExecutorException("SelectKey returned more than one value.");
         } else {
           metaParam.setValue(keyProperty, values.get(0));
         }
       }
     }
   } catch (ExecutorException e) {
     throw e;
   } catch (Exception e) {
     throw new ExecutorException(
         "Error selecting key or setting result to parameter object. Cause: " + e, e);
   }
 }
 private Object instantiateCollectionPropertyIfAppropriate(
     ResultMapping resultMapping, MetaObject metaObject) {
   final String propertyName = resultMapping.getProperty();
   Object propertyValue = metaObject.getValue(propertyName);
   if (propertyValue == null) {
     Class<?> type = resultMapping.getJavaType();
     if (type == null) {
       type = metaObject.getSetterType(propertyName);
     }
     try {
       if (objectFactory.isCollection(type)) {
         propertyValue = objectFactory.create(type);
         metaObject.setValue(propertyName, propertyValue);
         return propertyValue;
       }
     } catch (Exception e) {
       throw new ExecutorException(
           "Error instantiating collection property for result '"
               + resultMapping.getProperty()
               + "'.  Cause: "
               + e,
           e);
     }
   } else if (objectFactory.isCollection(propertyValue.getClass())) {
     return propertyValue;
   }
   return null;
 }
 private boolean applyAutomaticMappings(
     ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix)
     throws SQLException {
   final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
   boolean foundValues = false;
   for (String columnName : unmappedColumnNames) {
     String propertyName = columnName;
     if (columnPrefix != null && columnPrefix.length() > 0) {
       // When columnPrefix is specified,
       // ignore columns without the prefix.
       if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
         propertyName = columnName.substring(columnPrefix.length());
       } else {
         continue;
       }
     }
     final String property =
         metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
     if (property != null && metaObject.hasSetter(property)) {
       final Class<?> propertyType = metaObject.getSetterType(property);
       if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
         final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
         final Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
         if (value != null
             || configuration.isCallSettersOnNulls()) { // issue #377, call setter on nulls
           if (value != null || !propertyType.isPrimitive()) {
             metaObject.setValue(property, value);
           }
           foundValues = true;
         }
       }
     }
   }
   return foundValues;
 }
예제 #7
0
 @Test
 public void shouldGetAndSetNestedProperty() {
   RichType rich = new RichType();
   MetaObject meta = SystemMetaObject.forObject(rich);
   meta.setValue("richType.richProperty", "foo");
   assertEquals("foo", meta.getValue("richType.richProperty"));
 }
 private boolean applyPropertyMappings(
     ResultSetWrapper rsw,
     ResultMap resultMap,
     MetaObject metaObject,
     ResultLoaderMap lazyLoader,
     String columnPrefix)
     throws SQLException {
   final List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
   boolean foundValues = false;
   final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
   for (ResultMapping propertyMapping : propertyMappings) {
     final String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
     if (propertyMapping.isCompositeResult()
         || (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH)))
         || propertyMapping.getResultSet() != null) {
       Object value =
           getPropertyMappingValue(
               rsw.getResultSet(), metaObject, propertyMapping, lazyLoader, columnPrefix);
       final String property = propertyMapping.getProperty(); // issue #541 make property optional
       if (value != NO_VALUE
           && property != null
           && (value != null
               || configuration.isCallSettersOnNulls())) { // issue #377, call setter on nulls
         if (value != null || !metaObject.getSetterType(property).isPrimitive()) {
           metaObject.setValue(property, value);
         }
         foundValues = true;
       }
     }
   }
   return foundValues;
 }
예제 #9
0
 @Test
 public void shouldGetAndSetMapPair() {
   RichType rich = new RichType();
   MetaObject meta = SystemMetaObject.forObject(rich);
   meta.setValue("richMap.key", "foo");
   assertEquals("foo", meta.getValue("richMap.key"));
 }
예제 #10
0
 @Test
 public void shouldGetAndSetNestedMapPairUsingArraySyntax() {
   RichType rich = new RichType();
   MetaObject meta = SystemMetaObject.forObject(rich);
   meta.setValue("richType.richMap[key]", "foo");
   assertEquals("foo", meta.getValue("richType.richMap[key]"));
 }
  public Object intercept(Invocation invocation) throws Throwable {

    StatementHandler handler = (StatementHandler) invocation.getTarget();
    MetaObject metaObject = MetaObject.forObject(handler);

    Page page = pageByMetaObject(metaObject);
    if (page == null || (page.getPageCount() == 0 && page.getPageSize() == 0))
      return invocation.proceed();

    Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration");
    BoundSql orgBoundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
    if (page.getCount() == 0) {
      MappedStatement mappedStatement =
          (MappedStatement) metaObject.getValue("delegate.mappedStatement");
      page.setCount(
          totalCount(
              (Connection) invocation.getArgs()[0], orgBoundSql, configuration, mappedStatement));
    }

    metaObject.setValue(
        "delegate.boundSql.sql",
        searchDialectByDbTypeEnum(configuration, page)
            .spellPageSql(orgBoundSql.getSql(), page.getOffset(), page.getLimit()));
    logger.debug("pagination sql : {}", handler.getBoundSql().getSql());

    return invocation.proceed();
  }
예제 #12
0
 @Test
 public void shouldSetAndGetSelfListItem() {
   RichType rich = new RichType();
   MetaObject meta = SystemMetaObject.forObject(rich);
   meta.setValue("richList[0]", "foo");
   assertEquals("foo", meta.getValue("richList[0]"));
 }
예제 #13
0
  @Test
  public void shouldDemonstrateDeeplyNestedMapProperties() {
    HashMap<String, String> map = new HashMap<String, String>();
    MetaObject metaMap = SystemMetaObject.forObject(map);

    assertTrue(metaMap.hasSetter("id"));
    assertTrue(metaMap.hasSetter("name.first"));
    assertTrue(metaMap.hasSetter("address.street"));

    assertFalse(metaMap.hasGetter("id"));
    assertFalse(metaMap.hasGetter("name.first"));
    assertFalse(metaMap.hasGetter("address.street"));

    metaMap.setValue("id", "100");
    metaMap.setValue("name.first", "Clinton");
    metaMap.setValue("name.last", "Begin");
    metaMap.setValue("address.street", "1 Some Street");
    metaMap.setValue("address.city", "This City");
    metaMap.setValue("address.province", "A Province");
    metaMap.setValue("address.postal_code", "1A3 4B6");

    assertTrue(metaMap.hasGetter("id"));
    assertTrue(metaMap.hasGetter("name.first"));
    assertTrue(metaMap.hasGetter("address.street"));

    assertEquals(3, metaMap.getGetterNames().length);
    assertEquals(3, metaMap.getSetterNames().length);

    Map<String, String> name = (Map<String, String>) metaMap.getValue("name");
    Map<String, String> address = (Map<String, String>) metaMap.getValue("address");

    assertEquals("Clinton", name.get("first"));
    assertEquals("1 Some Street", address.get("street"));
  }
예제 #14
0
  @Test
  public void shouldDemonstrateNullValueInMap() {
    HashMap<String, String> map = new HashMap<String, String>();
    MetaObject metaMap = SystemMetaObject.forObject(map);
    assertFalse(metaMap.hasGetter("phone.home"));

    metaMap.setValue("phone", null);
    assertTrue(metaMap.hasGetter("phone"));
    // hasGetter returns true if the parent exists and is null.
    assertTrue(metaMap.hasGetter("phone.home"));
    assertTrue(metaMap.hasGetter("phone.home.ext"));
    assertNull(metaMap.getValue("phone"));
    assertNull(metaMap.getValue("phone.home"));
    assertNull(metaMap.getValue("phone.home.ext"));

    metaMap.setValue("phone.office", "789");
    assertFalse(metaMap.hasGetter("phone.home"));
    assertFalse(metaMap.hasGetter("phone.home.ext"));
    assertEquals("789", metaMap.getValue("phone.office"));
    assertNotNull(metaMap.getValue("phone"));
    assertNull(metaMap.getValue("phone.home"));
  }
 private void handleRefCursorOutputParameter(
     ResultSet rs, ParameterMapping parameterMapping, MetaObject metaParam) throws SQLException {
   try {
     final String resultMapId = parameterMapping.getResultMapId();
     final ResultMap resultMap = configuration.getResultMap(resultMapId);
     final DefaultResultHandler resultHandler = new DefaultResultHandler(objectFactory);
     final ResultSetWrapper rsw = new ResultSetWrapper(rs, configuration);
     handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
     metaParam.setValue(parameterMapping.getProperty(), resultHandler.getResultList());
   } finally {
     closeResultSet(rs); // issue #228 (close resultsets)
   }
 }
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    ParameterHandler parameterHandler = statementHandler.getParameterHandler();
    BoundSql boundSql = statementHandler.getBoundSql();

    MetaObject metaStatementHandler =
        MetaObject.forObject(
            statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
    RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
    // 没有分页参数
    if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
      return invocation.proceed();
    }

    Configuration configuration =
        (Configuration) metaStatementHandler.getValue("delegate.configuration");
    Dialect dialect = DialectFactory.buildDialect(configuration);
    String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
    // 获取总记录数
    Page<?> page = (Page<?>) rowBounds;
    String countSql = dialect.getCountString(originalSql);
    Connection connection = (Connection) invocation.getArgs()[0];
    int total = getTotal(parameterHandler, connection, countSql);
    page.setTotalCount(total);

    // 设置物理分页语句
    metaStatementHandler.setValue(
        "delegate.boundSql.sql",
        dialect.getLimitString(originalSql, page.getOffset(), page.getLimit()));
    // 屏蔽mybatis原有分页
    metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
    metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
    if (logger.isDebugEnabled()) {
      logger.debug("分页SQL : " + boundSql.getSql());
    }
    return invocation.proceed();
  }
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    FastResultSetHandler resultSetHandler = (FastResultSetHandler) invocation.getTarget();
    MetaObject metaStatementHandler =
        MetaObject.forObject(
            resultSetHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
    RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("rowBounds");

    Object result = invocation.proceed();

    if (rowBounds instanceof Page) {
      metaStatementHandler.setValue("rowBounds.result", result);
    }
    return result;
  }
예제 #18
0
 private void handleLocallyCachedOutputParameters(
     MappedStatement ms, CacheKey key, Object parameter, BoundSql boundSql) {
   if (ms.getStatementType() == StatementType.CALLABLE) {
     final Object cachedParameter = localOutputParameterCache.getObject(key);
     if (cachedParameter != null && parameter != null) {
       final MetaObject metaCachedParameter = MetaObject.forObject(cachedParameter);
       final MetaObject metaParameter = MetaObject.forObject(parameter);
       for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
         if (parameterMapping.getMode() != ParameterMode.IN) {
           final String parameterName = parameterMapping.getProperty();
           final Object cachedValue = metaCachedParameter.getValue(parameterName);
           metaParameter.setValue(parameterName, cachedValue);
         }
       }
     }
   }
 }
예제 #19
0
 public void setValue(String name, Object value) {
   PropertyTokenizer prop = new PropertyTokenizer(name);
   if (prop.hasNext()) {
     org.apache.ibatis.reflection.MetaObject metaValue =
         metaObjectForProperty(prop.getIndexedName());
     if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
       if (value == null && prop.getChildren() != null) {
         return; // don't instantiate child path if value is null
       } else {
         metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
       }
     }
     metaValue.setValue(prop.getChildren(), value);
   } else {
     objectWrapper.set(prop, value);
   }
 }
 private Object prepareCompositeKeyParameter(
     ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix)
     throws SQLException {
   final Object parameterObject = instantiateParameterObject(parameterType);
   final MetaObject metaObject = configuration.newMetaObject(parameterObject);
   boolean foundValues = false;
   for (ResultMapping innerResultMapping : resultMapping.getComposites()) {
     final Class<?> propType = metaObject.getSetterType(innerResultMapping.getProperty());
     final TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(propType);
     final Object propValue =
         typeHandler.getResult(rs, prependPrefix(innerResultMapping.getColumn(), columnPrefix));
     if (propValue != null) { // issue #353 & #560 do not execute nested query if key is null
       metaObject.setValue(innerResultMapping.getProperty(), propValue);
       foundValues = true;
     }
   }
   return foundValues ? parameterObject : null;
 }
 public void handleOutputParameters(CallableStatement cs) throws SQLException {
   final Object parameterObject = parameterHandler.getParameterObject();
   final MetaObject metaParam = configuration.newMetaObject(parameterObject);
   final List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
   for (int i = 0; i < parameterMappings.size(); i++) {
     final ParameterMapping parameterMapping = parameterMappings.get(i);
     if (parameterMapping.getMode() == ParameterMode.OUT
         || parameterMapping.getMode() == ParameterMode.INOUT) {
       if (ResultSet.class.equals(parameterMapping.getJavaType())) {
         handleRefCursorOutputParameter(
             (ResultSet) cs.getObject(i + 1), parameterMapping, metaParam);
       } else {
         final TypeHandler<?> typeHandler = parameterMapping.getTypeHandler();
         metaParam.setValue(parameterMapping.getProperty(), typeHandler.getResult(cs, i + 1));
       }
     }
   }
 }
예제 #22
0
 private Cache setStandardDecorators(Cache cache) {
   try {
     MetaObject metaCache = SystemMetaObject.forObject(cache);
     if (size != null && metaCache.hasSetter("size")) {
       metaCache.setValue("size", size);
     }
     if (clearInterval != null) {
       cache = new ScheduledCache(cache);
       ((ScheduledCache) cache).setClearInterval(clearInterval);
     }
     if (readWrite) {
       cache = new SerializedCache(cache);
     }
     cache = new LoggingCache(cache);
     cache = new SynchronizedCache(cache);
     return cache;
   } catch (Exception e) {
     throw new CacheException("Error building standard cache decorators.  Cause: " + e, e);
   }
 }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private void autoMap(Invocation invocation, String name) throws ClassNotFoundException {
    final Object[] queryArgs = invocation.getArgs();
    final MappedStatement ms = (MappedStatement) queryArgs[0];
    final Object parameter = queryArgs[1];
    String statementId = ms.getId();
    MapperMeta meta = getMapperMeta(ms.getConfiguration(), statementId);
    if (meta.isFillEntity()) {
      // 将泛型类加入到参数中供CrudTemplate使用
      if (parameter != null) {
        Map map;
        if (parameter instanceof Map) {
          map = (HashMap) parameter;
          map.put(CrudProvider.CLASS_KEY, meta.getEntity());
        } else {
          map = new HashMap();
          map.put(CrudProvider.PARA_KEY, parameter);
          map.put(CrudProvider.CLASS_KEY, meta.getEntity());
        }
        queryArgs[1] = map;
      } else {
        queryArgs[1] = meta.getEntity();
      }
    }

    if (meta.isFillResultMap()) {
      MetaObject metaMappedStatement = getMetaObject(ms);
      metaMappedStatement.setValue("resultMaps", meta.getResultMaps());
    }

    if (name.equals("query")) {
      final RowBounds rowBounds = (RowBounds) queryArgs[2];
      if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
        Page p = findPageParameter(queryArgs[1]);
        if (p != null) {
          queryArgs[2] = new RowBounds(p.getOffset(), p.getLimit());
        }
      }
    }
  }
예제 #24
0
 /**
  * 修改SqlSource
  *
  * @param ms
  * @param parser
  * @throws Throwable
  */
 public static void processMappedStatement(MappedStatement ms, Parser parser) throws Throwable {
   SqlSource sqlSource = ms.getSqlSource();
   MetaObject msObject = SystemMetaObject.forObject(ms);
   SqlSource tempSqlSource = sqlSource;
   if (sqlSource instanceof OrderBySqlSource) {
     tempSqlSource = ((OrderBySqlSource) tempSqlSource).getOriginal();
   }
   SqlSource pageSqlSource;
   if (tempSqlSource instanceof StaticSqlSource) {
     pageSqlSource = new PageStaticSqlSource((StaticSqlSource) tempSqlSource, parser);
   } else if (tempSqlSource instanceof RawSqlSource) {
     pageSqlSource = new PageRawSqlSource((RawSqlSource) tempSqlSource, parser);
   } else if (tempSqlSource instanceof ProviderSqlSource) {
     pageSqlSource = new PageProviderSqlSource((ProviderSqlSource) tempSqlSource, parser);
   } else if (tempSqlSource instanceof DynamicSqlSource) {
     pageSqlSource = new PageDynamicSqlSource((DynamicSqlSource) tempSqlSource, parser);
   } else {
     throw new RuntimeException("无法处理该类型[" + sqlSource.getClass() + "]的SqlSource");
   }
   msObject.setValue("sqlSource", pageSqlSource);
   // 由于count查询需要修改返回值,因此这里要创建一个Count查询的MS
   msCountMap.put(ms.getId(), MSUtils.newCountMappedStatement(ms));
 }
예제 #25
0
 public void load() {
   Object value = null;
   @SuppressWarnings("unchecked") // we suppose we get back a List
   List<Object> list = (List<Object>) localCache.getObject(key);
   Class<?> targetType = resultObject.getSetterType(property);
   if (targetType.isAssignableFrom(list.getClass())) {
     value = list;
   } else if (objectFactory.isCollection(targetType)) {
     value = objectFactory.create(targetType);
     MetaObject metaObject = configuration.newMetaObject(value);
     metaObject.addAll(list);
   } else if (targetType.isArray()) {
     Object[] array = (Object[]) Array.newInstance(targetType.getComponentType(), list.size());
     value = list.toArray(array);
   } else {
     if (list != null && list.size() > 1) {
       throw new ExecutorException(
           "Statement returned more than one row, where no more than one was expected.");
     } else if (list != null && list.size() == 1) {
       value = list.get(0);
     }
   }
   resultObject.setValue(property, value);
 }
예제 #26
0
 @Test
 public void shouldSetAndGetProperties() {
   MetaObject object = SystemMetaObject.forObject(new Author());
   object.setValue("email", "test");
   assertEquals("test", object.getValue("email"));
 }
예제 #27
0
 @Test
 public void shouldSetPropertyOfNullNestedPropertyWithNull() {
   MetaObject richWithNull = SystemMetaObject.forObject(new RichType());
   richWithNull.setValue("richType.richProperty", null);
   assertEquals(null, richWithNull.getValue("richType.richProperty"));
 }
예제 #28
0
 @Override
 public Object intercept(Invocation invocation) throws Throwable {
   StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
   MetaObject metaStatementHandler =
       MetaObject.forObject(
           statementHandler,
           DEFAULT_OBJECT_FACTORY,
           DEFAULT_OBJECT_WRAPPER_FACTORY,
           DEFAULT_REFLECTOR_FACTORY);
   // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环
   // 可以分离出最原始的的目标类)
   while (metaStatementHandler.hasGetter("h")) {
     Object object = metaStatementHandler.getValue("h");
     metaStatementHandler =
         MetaObject.forObject(
             object,
             DEFAULT_OBJECT_FACTORY,
             DEFAULT_OBJECT_WRAPPER_FACTORY,
             DEFAULT_REFLECTOR_FACTORY);
   }
   // 分离最后一个代理对象的目标类
   while (metaStatementHandler.hasGetter("target")) {
     Object object = metaStatementHandler.getValue("target");
     metaStatementHandler =
         MetaObject.forObject(
             object,
             DEFAULT_OBJECT_FACTORY,
             DEFAULT_OBJECT_WRAPPER_FACTORY,
             DEFAULT_REFLECTOR_FACTORY);
   }
   if (null == dialect || "".equals(dialect)) {
     logger.warn("Property dialect is not setted,use default 'mysql' ");
     dialect = defaultDialect;
   }
   if (null == pageSqlId || "".equals(pageSqlId)) {
     logger.warn("Property pageSqlId is not setted,use default '.*Page$' ");
     pageSqlId = defaultPageSqlId;
   }
   MappedStatement mappedStatement =
       (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
   PageParameter page = null;
   Object type = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
   if (PageParameter.class.isInstance(type)) {
     page = (PageParameter) type;
   }
   // 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的
   // MappedStatement的sql
   if (mappedStatement.getId().matches(pageSqlId) && page != null && page.getLimit() > 0) {
     BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
     Object parameterObject = boundSql.getParameterObject();
     if (parameterObject == null) {
       throw new NullPointerException("parameterObject is null!");
     } else {
       // 分页参数作为参数对象parameterObject的一个属性
       String sql = boundSql.getSql();
       // 重写sql
       String pageSql = buildPageSql(sql, page, dialect);
       metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
       // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
       metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
       metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
       Connection connection = (Connection) invocation.getArgs()[0];
       // 重设分页参数里的总页数等
       setPageParameter(sql, connection, mappedStatement, boundSql, page);
     }
   }
   // 将执行权交给下一个拦截器
   return invocation.proceed();
 }
  public Object intercept(Invocation invocation) throws Throwable {

    RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
    BoundSql boundSql = statementHandler.getBoundSql();
    MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);

    BaseStatementHandler delegate =
        (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
    MappedStatement mappedStatement =
        (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");
    Connection connection = (Connection) invocation.getArgs()[0];

    // 获取当前准备执行的行边界
    RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");

    // 判断是否设置分页
    if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
      return invocation.proceed();
    }

    Configuration configuration =
        (Configuration) metaStatementHandler.getValue("delegate.configuration");
    Dialect.Type databaseType = null;
    // 获取当前的数据库方言
    try {

      databaseType =
          Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());

    } catch (Exception e) {
      // ignore
      throw e;
    }

    if (databaseType == null) {
      throw new RuntimeException(
          "the value of the dialect property in configuration.xml is not defined : "
              + configuration.getVariables().getProperty("dialect"));
    }

    Dialect dialect = null;
    // 判断数据库方言
    switch (databaseType) {
      case ORACLE:
        dialect = new OracleDialect();
    }
    // 原始sql
    String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
    // 统计总数
    int count = getCount(connection, boundSql, configuration, mappedStatement);
    Object obj = boundSql.getParameterObject();
    if (null != obj && obj instanceof Map) {
      Map parameterObject = (Map) boundSql.getParameterObject();
      parameterObject.put("_dataCount", count);
    } else {
      throw new NullPointerException("service中getGridData的condition参数不能为空!");
    }
    // 设置拼接好的分页sql
    metaStatementHandler.setValue(
        "delegate.boundSql.sql",
        dialect.getPageSql(originalSql, rowBounds.getOffset(), rowBounds.getLimit()));

    // 重置行边界
    metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);

    metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);

    if (log.isDebugEnabled()) {
      log.debug("生成分页SQL : " + boundSql.getSql());
    }

    return invocation.proceed();
  }