Skip to content

Commit

Permalink
Merge pull request #1056 from kazuki43zoo/default-resultset-type
Browse files Browse the repository at this point in the history
Add defaultResultSetType as global configuration
  • Loading branch information
kazuki43zoo committed Jul 7, 2019
2 parents 0fa5395 + 7765a86 commit 6e9e4c2
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 2 deletions.
Expand Up @@ -306,7 +306,7 @@ void parseStatement(Method method) {
Integer fetchSize = null;
Integer timeout = null;
StatementType statementType = StatementType.PREPARED;
ResultSetType resultSetType = null;
ResultSetType resultSetType = configuration.getDefaultResultSetType();
SqlCommandType sqlCommandType = getSqlCommandType(method);
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = !isSelect;
Expand Down Expand Up @@ -342,7 +342,9 @@ void parseStatement(Method method) {
fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348
timeout = options.timeout() > -1 ? options.timeout() : null;
statementType = options.statementType();
resultSetType = options.resultSetType();
if (options.resultSetType() != ResultSetType.DEFAULT) {
resultSetType = options.resultSetType();
}
}

String resultMapId = null;
Expand Down
Expand Up @@ -253,6 +253,7 @@ private void settingsElement(Properties props) {
configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
configuration.setDefaultResultSetType(resolveResultSetType(props.getProperty("defaultResultSetType")));
configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
Expand Down
Expand Up @@ -103,6 +103,9 @@ public void parseStatementNode() {
String resultMap = context.getStringAttribute("resultMap");
String resultSetType = context.getStringAttribute("resultSetType");
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
if (resultSetTypeEnum == null) {
resultSetTypeEnum = configuration.getDefaultResultSetType();
}
String keyProperty = context.getStringAttribute("keyProperty");
String keyColumn = context.getStringAttribute("keyColumn");
String resultSets = context.getStringAttribute("resultSets");
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/apache/ibatis/session/Configuration.java
Expand Up @@ -71,6 +71,7 @@
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultSetType;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.plugin.Interceptor;
Expand Down Expand Up @@ -121,6 +122,7 @@ public class Configuration {
protected Set<String> lazyLoadTriggerMethods = new HashSet<>(Arrays.asList("equals", "clone", "hashCode", "toString"));
protected Integer defaultStatementTimeout;
protected Integer defaultFetchSize;
protected ResultSetType defaultResultSetType;
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
Expand Down Expand Up @@ -431,6 +433,20 @@ public void setDefaultFetchSize(Integer defaultFetchSize) {
this.defaultFetchSize = defaultFetchSize;
}

/**
* @since 3.5.2
*/
public ResultSetType getDefaultResultSetType() {
return defaultResultSetType;
}

/**
* @since 3.5.2
*/
public void setDefaultResultSetType(ResultSetType defaultResultSetType) {
this.defaultResultSetType = defaultResultSetType;
}

public boolean isUseColumnLabel() {
return useColumnLabel;
}
Expand Down
14 changes: 14 additions & 0 deletions src/site/es/xdoc/configuration.xml
Expand Up @@ -298,6 +298,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
Sin valor (null)
</td>
</tr>
<tr>
<td>
defaultResultSetType
</td>
<td>
Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)
</td>
<td>
FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')
</td>
<td>
Not Set (null)
</td>
</tr>
<tr>
<td>
safeRowBoundsEnabled
Expand Down
14 changes: 14 additions & 0 deletions src/site/ja/xdoc/configuration.xml
Expand Up @@ -327,6 +327,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
なし (null)
</td>
</tr>
<tr>
<td>
defaultResultSetType
</td>
<td>
ステートメント毎の設定を省略した場合のスクロール方法を指定します。 (導入されたバージョン: 3.5.2)
</td>
<td>
FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(指定しない時と同じ動作)
</td>
<td>
なし (null)
</td>
</tr>
<tr>
<td>
safeRowBoundsEnabled
Expand Down
14 changes: 14 additions & 0 deletions src/site/ko/xdoc/configuration.xml
Expand Up @@ -307,6 +307,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
셋팅되지 않음(null)
</td>
</tr>
<tr>
<td>
defaultResultSetType
</td>
<td>
Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)
</td>
<td>
FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')
</td>
<td>
Not Set (null)
</td>
</tr>
<tr>
<td>
safeRowBoundsEnabled
Expand Down
14 changes: 14 additions & 0 deletions src/site/xdoc/configuration.xml
Expand Up @@ -383,6 +383,20 @@ SqlSessionFactory factory =
Not Set (null)
</td>
</tr>
<tr>
<td>
defaultResultSetType
</td>
<td>
Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)
</td>
<td>
FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')
</td>
<td>
Not Set (null)
</td>
</tr>
<tr>
<td>
safeRowBoundsEnabled
Expand Down
14 changes: 14 additions & 0 deletions src/site/zh/xdoc/configuration.xml
Expand Up @@ -316,6 +316,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
未设置 (null)
</td>
</tr>
<tr>
<td>
defaultResultSetType
</td>
<td>
Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)
</td>
<td>
FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')
</td>
<td>
Not Set (null)
</td>
</tr>
<tr>
<td>
safeRowBoundsEnabled
Expand Down
@@ -0,0 +1,116 @@
/**
* Copyright 2009-2019 the original author or authors.
*
* 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 org.apache.ibatis.builder;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultSetType;
import org.apache.ibatis.mapping.StatementType;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class AnnotationMapperBuilderTest {

@Test
void withOptions() {
Configuration configuration = new Configuration();
MapperAnnotationBuilder builder = new MapperAnnotationBuilder(configuration, Mapper.class);
builder.parse();

MappedStatement mappedStatement = configuration.getMappedStatement("selectWithOptions");
assertThat(mappedStatement.getFetchSize()).isEqualTo(200);
assertThat(mappedStatement.getTimeout()).isEqualTo(10);
assertThat(mappedStatement.getStatementType()).isEqualTo(StatementType.STATEMENT);
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.SCROLL_INSENSITIVE);
assertThat(mappedStatement.isFlushCacheRequired()).isTrue();
assertThat(mappedStatement.isUseCache()).isFalse();
assertThat(mappedStatement.getResultSets()).containsExactly("resultSets");

mappedStatement = configuration.getMappedStatement("insertWithOptions");
assertThat(mappedStatement.getKeyGenerator()).isInstanceOf(Jdbc3KeyGenerator.class);
assertThat(mappedStatement.getKeyColumns()).containsExactly("key_column");
assertThat(mappedStatement.getKeyProperties()).containsExactly("keyProperty");
}

@Test
void withOptionsAndWithoutOptionsAttributesWhenSpecifyDefaultValue() {
Configuration configuration = new Configuration();
configuration.setDefaultResultSetType(ResultSetType.SCROLL_INSENSITIVE);
MapperAnnotationBuilder builder = new MapperAnnotationBuilder(configuration, Mapper.class);
builder.parse();

MappedStatement mappedStatement = configuration.getMappedStatement("selectWithOptionsAndWithoutOptionsAttributes");
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.SCROLL_INSENSITIVE);
}


@Test
void withOptionsAndWithoutOptionsAttributesWhenNotSpecifyDefaultValue() {
Configuration configuration = new Configuration();
MapperAnnotationBuilder builder = new MapperAnnotationBuilder(configuration, Mapper.class);
builder.parse();

MappedStatement mappedStatement = configuration.getMappedStatement("selectWithOptionsAndWithoutOptionsAttributes");
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.DEFAULT);
}

@Test
void withoutOptionsWhenSpecifyDefaultValue() {
Configuration configuration = new Configuration();
configuration.setDefaultResultSetType(ResultSetType.SCROLL_INSENSITIVE);
MapperAnnotationBuilder builder = new MapperAnnotationBuilder(configuration, Mapper.class);
builder.parse();

MappedStatement mappedStatement = configuration.getMappedStatement("selectWithoutOptions");
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.SCROLL_INSENSITIVE);
}

@Test
void withoutOptionsWhenNotSpecifyDefaultValue() {
Configuration configuration = new Configuration();
MapperAnnotationBuilder builder = new MapperAnnotationBuilder(configuration, Mapper.class);
builder.parse();

MappedStatement mappedStatement = configuration.getMappedStatement("selectWithoutOptions");
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.DEFAULT);
}

interface Mapper {

@Insert("insert into test (name) values(#{name})")
@Options(useGeneratedKeys = true, keyColumn = "key_column", keyProperty = "keyProperty")
void insertWithOptions(String name);

@Select("select * from test")
@Options(fetchSize = 200, timeout = 10, statementType = StatementType.STATEMENT, resultSetType = ResultSetType.SCROLL_INSENSITIVE, flushCache = Options.FlushCachePolicy.TRUE, useCache = false, resultSets = "resultSets")
String selectWithOptions(Integer id);

@Select("select * from test")
@Options
String selectWithOptionsAndWithoutOptionsAttributes(Integer id);

@Select("select * from test")
String selectWithoutOptions(Integer id);

}

}
Expand Up @@ -40,6 +40,7 @@
<setting name="defaultExecutorType" value="BATCH"/>
<setting name="defaultStatementTimeout" value="10"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="defaultResultSetType" value="SCROLL_INSENSITIVE"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="safeRowBoundsEnabled" value="true"/>
<setting name="localCacheScope" value="STATEMENT"/>
Expand Down
Expand Up @@ -41,6 +41,7 @@
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.ResultSetType;
import org.apache.ibatis.scripting.defaults.RawLanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.AutoMappingBehavior;
Expand Down Expand Up @@ -86,6 +87,7 @@ void shouldSuccessfullyLoadMinimalXMLConfigFile() throws Exception {
assertThat(config.getDefaultExecutorType()).isEqualTo(ExecutorType.SIMPLE);
assertNull(config.getDefaultStatementTimeout());
assertNull(config.getDefaultFetchSize());
assertNull(config.getDefaultResultSetType());
assertThat(config.isMapUnderscoreToCamelCase()).isFalse();
assertThat(config.isSafeRowBoundsEnabled()).isFalse();
assertThat(config.getLocalCacheScope()).isEqualTo(LocalCacheScope.SESSION);
Expand Down Expand Up @@ -179,6 +181,7 @@ void shouldSuccessfullyLoadXMLConfigFile() throws Exception {
assertThat(config.getDefaultExecutorType()).isEqualTo(ExecutorType.BATCH);
assertThat(config.getDefaultStatementTimeout()).isEqualTo(10);
assertThat(config.getDefaultFetchSize()).isEqualTo(100);
assertThat(config.getDefaultResultSetType()).isEqualTo(ResultSetType.SCROLL_INSENSITIVE);
assertThat(config.isMapUnderscoreToCamelCase()).isTrue();
assertThat(config.isSafeRowBoundsEnabled()).isTrue();
assertThat(config.getLocalCacheScope()).isEqualTo(LocalCacheScope.STATEMENT);
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/org/apache/ibatis/builder/XmlMapperBuilderTest.java
Expand Up @@ -63,6 +63,20 @@ void mappedStatementWithOptions() throws Exception {
}
}

@Test
void mappedStatementWithoutOptionsWhenSpecifyDefaultValue() throws Exception {
Configuration configuration = new Configuration();
configuration.setDefaultResultSetType(ResultSetType.SCROLL_INSENSITIVE);
String resource = "org/apache/ibatis/builder/AuthorMapper.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder builder = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
builder.parse();
inputStream.close();

MappedStatement mappedStatement = configuration.getMappedStatement("selectAuthor");
assertThat(mappedStatement.getResultSetType()).isEqualTo(ResultSetType.SCROLL_INSENSITIVE);
}

@Test
void parseExpression() {
BaseBuilder builder = new BaseBuilder(new Configuration()){{}};
Expand Down

0 comments on commit 6e9e4c2

Please sign in to comment.