Skip to content

Commit

Permalink
Merge pull request #1901 from elfhazard/feature/minifysql
Browse files Browse the repository at this point in the history
A new option `shrinkWhitespacesInSql` that removes extra whitespaces from SQL
  • Loading branch information
harawata committed May 18, 2020
2 parents 89a7133 + 6df767d commit 63785f2
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 21 deletions.
24 changes: 22 additions & 2 deletions src/main/java/org/apache/ibatis/builder/SqlSourceBuilder.java
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 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.
Expand All @@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
Expand All @@ -42,10 +43,29 @@ public SqlSourceBuilder(Configuration configuration) {
public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {
ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);
GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
String sql = parser.parse(originalSql);
String sql;
if (configuration.isShrinkWhitespacesInSql()) {
sql = parser.parse(removeExtraWhitespaces(originalSql));
} else {
sql = parser.parse(originalSql);
}
return new StaticSqlSource(configuration, sql, handler.getParameterMappings());
}

public static String removeExtraWhitespaces(String original) {
StringTokenizer tokenizer = new StringTokenizer(original);
StringBuilder builder = new StringBuilder();
boolean hasMoreTokens = tokenizer.hasMoreTokens();
while (hasMoreTokens) {
builder.append(tokenizer.nextToken());
hasMoreTokens = tokenizer.hasMoreTokens();
if (hasMoreTokens) {
builder.append(' ');
}
}
return builder.toString();
}

private static class ParameterMappingTokenHandler extends BaseBuilder implements TokenHandler {

private List<ParameterMapping> parameterMappings = new ArrayList<>();
Expand Down
Expand Up @@ -268,6 +268,7 @@ private void settingsElement(Properties props) {
configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false));
configuration.setLogPrefix(props.getProperty("logPrefix"));
configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
configuration.setShrinkWhitespacesInSql(booleanValueOf(props.getProperty("shrinkWhitespacesInSql"), false));
}

private void environmentsElement(XNode context) throws Exception {
Expand Down
14 changes: 4 additions & 10 deletions src/main/java/org/apache/ibatis/logging/jdbc/BaseJdbcLogger.java
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 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.
Expand All @@ -26,9 +26,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.reflection.ArrayUtil;

Expand Down Expand Up @@ -120,14 +120,8 @@ protected void clearColumnInfo() {
columnValues.clear();
}

protected String removeBreakingWhitespace(String original) {
StringTokenizer whitespaceStripper = new StringTokenizer(original);
StringBuilder builder = new StringBuilder();
while (whitespaceStripper.hasMoreTokens()) {
builder.append(whitespaceStripper.nextToken());
builder.append(" ");
}
return builder.toString();
protected String removeExtraWhitespace(String original) {
return SqlSourceBuilder.removeExtraWhitespaces(original);
}

protected boolean isDebugEnabled() {
Expand Down
Expand Up @@ -50,7 +50,7 @@ public Object invoke(Object proxy, Method method, Object[] params)
}
if ("prepareStatement".equals(method.getName()) || "prepareCall".equals(method.getName())) {
if (isDebugEnabled()) {
debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
debug(" Preparing: " + removeExtraWhitespace((String) params[0]), true);
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
Expand Down
Expand Up @@ -48,7 +48,7 @@ public Object invoke(Object proxy, Method method, Object[] params) throws Throwa
}
if (EXECUTE_METHODS.contains(method.getName())) {
if (isDebugEnabled()) {
debug(" Executing: " + removeBreakingWhitespace((String) params[0]), true);
debug(" Executing: " + removeExtraWhitespace((String) params[0]), true);
}
if ("executeQuery".equals(method.getName())) {
ResultSet rs = (ResultSet) method.invoke(statement, params);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/apache/ibatis/session/Configuration.java
Expand Up @@ -113,6 +113,7 @@ public class Configuration {
protected boolean callSettersOnNulls;
protected boolean useActualParamName = true;
protected boolean returnInstanceForEmptyRow;
protected boolean shrinkWhitespacesInSql;

protected String logPrefix;
protected Class<? extends Log> logImpl;
Expand Down Expand Up @@ -266,6 +267,14 @@ public void setReturnInstanceForEmptyRow(boolean returnEmptyInstance) {
this.returnInstanceForEmptyRow = returnEmptyInstance;
}

public boolean isShrinkWhitespacesInSql() {
return shrinkWhitespacesInSql;
}

public void setShrinkWhitespacesInSql(boolean shrinkWhitespacesInSql) {
this.shrinkWhitespacesInSql = shrinkWhitespacesInSql;
}

public String getDatabaseId() {
return databaseId;
}
Expand Down
16 changes: 15 additions & 1 deletion src/site/es/xdoc/configuration.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -547,6 +547,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
Not set
</td>
</tr>
<tr>
<td>
shrinkWhitespacesInSql
</td>
<td>
Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. (Since 3.5.5)
</td>
<td>
true | false
</td>
<td>
false
</td>
</tr>
</tbody>
</table>
<p>
Expand Down
16 changes: 15 additions & 1 deletion src/site/ja/xdoc/configuration.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -572,6 +572,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
未指定
</td>
</tr>
<tr>
<td>
shrinkWhitespacesInSql
</td>
<td>
SQL 内の余分な空白文字を削除します。リテラル文字列も対象となる点に注意してください。(導入されたバージョン: 3.5.5)
</td>
<td>
true | false
</td>
<td>
false
</td>
</tr>
</tbody>
</table>
<p>
Expand Down
16 changes: 15 additions & 1 deletion src/site/ko/xdoc/configuration.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -555,6 +555,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
설정하지 않음
</td>
</tr>
<tr>
<td>
shrinkWhitespacesInSql
</td>
<td>
SQL에서 여분의 whitespace 문자들을 삭제한다. 이는 SQL의 리터럴 문자열에도 영향을 미친다. (Since 3.5.5)
</td>
<td>
true | false
</td>
<td>
false
</td>
</tr>
</tbody>
</table>
<p>위 설정을 모두 사용한 setting 엘리먼트의 예제이다:</p>
Expand Down
18 changes: 16 additions & 2 deletions src/site/xdoc/configuration.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -634,6 +634,20 @@ SqlSessionFactory factory =
Not set
</td>
</tr>
<tr>
<td>
shrinkWhitespacesInSql
</td>
<td>
Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. (Since 3.5.5)
</td>
<td>
true | false
</td>
<td>
false
</td>
</tr>
</tbody>
</table>
<p>
Expand Down
14 changes: 14 additions & 0 deletions src/site/zh/xdoc/configuration.xml
Expand Up @@ -565,6 +565,20 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
未设置
</td>
</tr>
<tr>
<td>
shrinkWhitespacesInSql
</td>
<td>
Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. (Since 3.5.5)
</td>
<td>
true | false
</td>
<td>
false
</td>
</tr>
</tbody>
</table>
<p>
Expand Down
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -54,6 +54,7 @@
<setting name="vfsImpl" value="org.apache.ibatis.io.JBoss6VFS"/>
<setting name="configurationFactory" value="java.lang.String"/>
<setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
<setting name="shrinkWhitespacesInSql" value="true"/>
</settings>

<typeAliases>
Expand Down
56 changes: 56 additions & 0 deletions src/test/java/org/apache/ibatis/builder/SqlSourceBuilderTest.java
@@ -0,0 +1,56 @@
/**
* Copyright 2009-2020 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.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class SqlSourceBuilderTest {

private static Configuration configuration;
private static SqlSourceBuilder sqlSourceBuilder;
private final String sqlFromXml = "\t\n\n SELECT * \n FROM user\n \t WHERE user_id = 1\n\t ";

@BeforeEach
void setUp() {
configuration = new Configuration();

sqlSourceBuilder = new SqlSourceBuilder(configuration);
}

@Test
void testShrinkWhitespacesInSqlIsFalse() {
SqlSource sqlSource = sqlSourceBuilder.parse(sqlFromXml, null, null);
BoundSql boundSql = sqlSource.getBoundSql(null);
String actual = boundSql.getSql();
Assertions.assertEquals(sqlFromXml, actual);
}

@Test
void testShrinkWhitespacesInSqlIsTrue() {
configuration.setShrinkWhitespacesInSql(true);
SqlSource sqlSource = sqlSourceBuilder.parse(sqlFromXml, null, null);
BoundSql boundSql = sqlSource.getBoundSql(null);
String actual = boundSql.getSql();

String shrankWhitespacesInSql = "SELECT * FROM user WHERE user_id = 1";
Assertions.assertEquals(shrankWhitespacesInSql, actual);
}
}
Expand Up @@ -100,6 +100,7 @@ void shouldSuccessfullyLoadMinimalXMLConfigFile() throws Exception {
assertNull(config.getLogImpl());
assertNull(config.getConfigurationFactory());
assertThat(config.getTypeHandlerRegistry().getTypeHandler(RoundingMode.class)).isInstanceOf(EnumTypeHandler.class);
assertThat(config.isShrinkWhitespacesInSql()).isFalse();
}
}

Expand Down Expand Up @@ -194,6 +195,7 @@ void shouldSuccessfullyLoadXMLConfigFile() throws Exception {
assertThat(config.getLogImpl().getName()).isEqualTo(Slf4jImpl.class.getName());
assertThat(config.getVfsImpl().getName()).isEqualTo(JBoss6VFS.class.getName());
assertThat(config.getConfigurationFactory().getName()).isEqualTo(String.class.getName());
assertThat(config.isShrinkWhitespacesInSql()).isTrue();

assertThat(config.getTypeAliasRegistry().getTypeAliases().get("blogauthor")).isEqualTo(Author.class);
assertThat(config.getTypeAliasRegistry().getTypeAliases().get("blog")).isEqualTo(Blog.class);
Expand Down
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2009-2019 the original author or authors.
Copyright 2009-2020 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.
Expand Down Expand Up @@ -50,6 +50,7 @@
<setting name="logImpl" value="SLF4J"/>
<setting name="vfsImpl" value="org.apache.ibatis.io.JBoss6VFS"/>
<setting name="configurationFactory" value="java.lang.String"/>
<setting name="shrinkWhitespacesInSql" value="true"/>
</settings>

<typeAliases>
Expand Down
Expand Up @@ -84,6 +84,7 @@ void shouldSuccessfullyLoadMinimalXMLConfigFile() throws Exception {
assertNull(config.getLogPrefix());
assertNull(config.getLogImpl());
assertNull(config.getConfigurationFactory());
assertFalse(config.isShrinkWhitespacesInSql());
} finally {
// System.clearProperty(XPathParser.KEY_USE_XSD);
}
Expand Down Expand Up @@ -121,6 +122,7 @@ void shouldSuccessfullyLoadXMLConfigFile() throws Exception {
assertEquals(Slf4jImpl.class.getName(), config.getLogImpl().getName());
assertEquals(JBoss6VFS.class.getName(), config.getVfsImpl().getName());
assertEquals(String.class.getName(), config.getConfigurationFactory().getName());
assertTrue(config.isShrinkWhitespacesInSql());

assertEquals(Author.class, config.getTypeAliasRegistry().getTypeAliases().get("blogauthor"));
assertEquals(Blog.class, config.getTypeAliasRegistry().getTypeAliases().get("blog"));
Expand Down

0 comments on commit 63785f2

Please sign in to comment.