Skip to content

Commit 31173b2

Browse files
committed
Polishing.
See #2409.
1 parent 993eeb5 commit 31173b2

19 files changed

+283
-196
lines changed

pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323

2424
<eclipselink>2.7.9</eclipselink>
2525
<hibernate>5.6.0.Final</hibernate>
26+
<jsqlparser>4.3</jsqlparser>
2627
<mysql-connector-java>8.0.23</mysql-connector-java>
2728
<postgresql>42.2.19</postgresql>
2829
<springdata.commons>2.7.0-SNAPSHOT</springdata.commons>
2930
<vavr>0.10.3</vavr>
30-
<jsqlparser.version>4.3</jsqlparser.version>
3131

3232
<hibernate.groupId>org.hibernate</hibernate.groupId>
3333

@@ -376,7 +376,7 @@
376376
<dependency>
377377
<groupId>com.github.jsqlparser</groupId>
378378
<artifactId>jsqlparser</artifactId>
379-
<version>${jsqlparser.version}</version>
379+
<version>${jsqlparser}</version>
380380
<scope>provided</scope>
381381
<optional>true</optional>
382382
</dependency>

src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public abstract class AbstractJpaQuery implements RepositoryQuery {
6969
private final PersistenceProvider provider;
7070
private final Lazy<JpaQueryExecution> execution;
7171

72-
final Lazy<ParameterBinder> parameterBinder = new Lazy<>(this::createBinder);
72+
final Lazy<ParameterBinder> parameterBinder = Lazy.of(this::createBinder);
7373

7474
/**
7575
* Creates a new {@link AbstractJpaQuery} from the given {@link JpaQueryMethod}.

src/main/java/org/springframework/data/jpa/repository/query/DefaultQueryEnhancer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
*/
1616
package org.springframework.data.jpa.repository.query;
1717

18-
import org.springframework.data.domain.Sort;
19-
2018
import java.util.Set;
2119

20+
import org.springframework.data.domain.Sort;
21+
2222
/**
2323
* The implementation of {@link QueryEnhancer} using {@link QueryUtils}.
2424
*
2525
* @author Diego Krupitza
26+
* @since 2.7.0
2627
*/
2728
public class DefaultQueryEnhancer implements QueryEnhancer {
2829

src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java

+29-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package org.springframework.data.jpa.repository.query;
1717

18+
import static org.springframework.data.jpa.repository.query.JSqlParserUtils.*;
19+
import static org.springframework.data.jpa.repository.query.QueryUtils.*;
20+
1821
import net.sf.jsqlparser.JSQLParserException;
1922
import net.sf.jsqlparser.expression.Alias;
2023
import net.sf.jsqlparser.expression.Expression;
@@ -24,24 +27,33 @@
2427
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
2528
import net.sf.jsqlparser.schema.Column;
2629
import net.sf.jsqlparser.schema.Table;
27-
import net.sf.jsqlparser.statement.select.*;
30+
import net.sf.jsqlparser.statement.select.OrderByElement;
31+
import net.sf.jsqlparser.statement.select.PlainSelect;
32+
import net.sf.jsqlparser.statement.select.Select;
33+
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
34+
import net.sf.jsqlparser.statement.select.SelectItem;
2835
import net.sf.jsqlparser.util.SelectUtils;
36+
37+
import java.util.ArrayList;
38+
import java.util.Collections;
39+
import java.util.HashSet;
40+
import java.util.List;
41+
import java.util.Objects;
42+
import java.util.Set;
43+
import java.util.stream.Collectors;
44+
2945
import org.springframework.data.domain.Sort;
3046
import org.springframework.data.util.Streamable;
3147
import org.springframework.util.Assert;
3248
import org.springframework.util.CollectionUtils;
3349
import org.springframework.util.StringUtils;
3450

35-
import java.util.*;
36-
import java.util.stream.Collectors;
37-
38-
import static org.springframework.data.jpa.repository.query.JSqlParserUtils.*;
39-
import static org.springframework.data.jpa.repository.query.QueryUtils.checkSortExpression;
40-
4151
/**
4252
* The implementation of {@link QueryEnhancer} using JSqlParser.
4353
*
4454
* @author Diego Krupitza
55+
* @author Greg Turnquist
56+
* @since 2.7.0
4557
*/
4658
public class JSqlParserQueryEnhancer implements QueryEnhancer {
4759

@@ -58,6 +70,7 @@ public JSqlParserQueryEnhancer(DeclaredQuery query) {
5870

5971
@Override
6072
public String getExistsQueryString(String entityName, String countQueryPlaceHolder, Iterable<String> idAttributes) {
73+
6174
final Table tableNameWithAlias = getTableWithAlias(entityName, DEFAULT_TABLE_ALIAS);
6275
Function jSqlCount = getJSqlCount(Collections.singletonList(countQueryPlaceHolder), false);
6376

@@ -74,6 +87,7 @@ public String getExistsQueryString(String entityName, String countQueryPlaceHold
7487
}).collect(Collectors.toList());
7588

7689
if (equalityExpressions.size() > 1) {
90+
7791
AndExpression rootOfWhereClause = concatenateWithAndExpression(equalityExpressions);
7892
selectBody.setWhere(rootOfWhereClause);
7993
} else if (equalityExpressions.size() == 1) {
@@ -85,12 +99,14 @@ public String getExistsQueryString(String entityName, String countQueryPlaceHold
8599

86100
@Override
87101
public String getQueryString(String template, String entityName) {
102+
88103
Assert.hasText(entityName, "Entity name must not be null or empty!");
89104
return String.format(template, entityName);
90105
}
91106

92107
@Override
93108
public String applySorting(Sort sort, String alias) {
109+
94110
String queryString = query.getQueryString();
95111
Assert.hasText(queryString, "Query must not be null or empty!");
96112

@@ -145,6 +161,7 @@ private Set<String> getSelectionAliases(PlainSelect selectBody) {
145161
* @return a {@literal Set} containing all found aliases. Guaranteed to be not {@literal null}.
146162
*/
147163
Set<String> getSelectionAliases() {
164+
148165
Select selectStatement = parseSelectStatement(this.query.getQueryString());
149166
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
150167
return this.getSelectionAliases(selectBody);
@@ -234,6 +251,7 @@ public String detectAlias() {
234251
* @return Might return {@literal null}.
235252
*/
236253
private String detectAlias(String query) {
254+
237255
Select selectStatement = parseSelectStatement(query);
238256
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
239257
return detectAlias(selectBody);
@@ -247,6 +265,7 @@ private String detectAlias(String query) {
247265
* @return Might return {@literal null}.
248266
*/
249267
private static String detectAlias(PlainSelect selectBody) {
268+
250269
Alias alias = selectBody.getFromItem().getAlias();
251270
return alias == null ? null : alias.getName();
252271
}
@@ -298,6 +317,7 @@ public String createCountQueryFor(String countProjection) {
298317

299318
@Override
300319
public String getProjection() {
320+
301321
Assert.hasText(query.getQueryString(), "Query must not be null or empty!");
302322

303323
Select selectStatement = parseSelectStatement(query.getQueryString());
@@ -321,6 +341,7 @@ public Set<String> getJoinAliases() {
321341
* @return the parsed query
322342
*/
323343
private static Select parseSelectStatement(String query) {
344+
324345
try {
325346
return (Select) CCJSqlParserUtil.parse(query);
326347
} catch (JSQLParserException e) {
@@ -335,6 +356,7 @@ private static Select parseSelectStatement(String query) {
335356
* @return <code>true</code> when the projection only contains a single column definition otherwise <code>false</code>
336357
*/
337358
private boolean onlyASingleColumnProjection(List<SelectItem> projection) {
359+
338360
// this is unfortunately the only way to check without any hacky & hard string regex magic
339361
return projection.size() == 1 && projection.get(0) instanceof SelectExpressionItem
340362
&& (((SelectExpressionItem) projection.get(0)).getExpression()) instanceof Column;

src/main/java/org/springframework/data/jpa/repository/query/JSqlParserUtils.java

+20-8
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,24 @@
2222
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
2323
import net.sf.jsqlparser.schema.Column;
2424
import net.sf.jsqlparser.schema.Table;
25-
import org.springframework.util.CollectionUtils;
26-
import org.springframework.util.StringUtils;
2725

2826
import java.util.Collections;
2927
import java.util.List;
3028
import java.util.stream.Collectors;
3129

30+
import org.springframework.util.CollectionUtils;
31+
import org.springframework.util.StringUtils;
32+
3233
/**
3334
* A utility class for JSqlParser.
3435
*
3536
* @author Diego Krupitza
37+
* @author Greg Turnquist
38+
* @since 2.7.0
3639
*/
3740
public final class JSqlParserUtils {
3841

39-
private JSqlParserUtils() {
40-
}
42+
private JSqlParserUtils() {}
4143

4244
/**
4345
* Generates a JSqlParser table from an entity name and an optional alias name
@@ -47,8 +49,12 @@ private JSqlParserUtils() {
4749
* @return the newly generated table
4850
*/
4951
public static Table getTableWithAlias(String entityName, String alias) {
52+
5053
Table table = new Table(entityName);
51-
return StringUtils.hasText(alias) ? table.withAlias(new Alias(alias)) : table;
54+
55+
return StringUtils.hasText(alias) //
56+
? table.withAlias(new Alias(alias)) //
57+
: table;
5258
}
5359

5460
/**
@@ -67,14 +73,17 @@ public static AndExpression concatenateWithAndExpression(List<Expression> expres
6773
AndExpression rootAndExpression = new AndExpression();
6874
AndExpression currentLocation = rootAndExpression;
6975

70-
// traverse the list with looking 1 element ahead
76+
// traverse the list, looking 1 element ahead
7177
for (int i = 0; i < expressions.size(); i++) {
78+
7279
Expression currentExpression = expressions.get(i);
80+
7381
if (currentLocation.getLeftExpression() == null) {
7482
currentLocation.setLeftExpression(currentExpression);
75-
} else if (currentLocation.getRightExpression() == null && i == expressions.size() - 1) {
83+
} else if (currentLocation.getRightExpression() == null && i == (expressions.size() - 1)) {
7684
currentLocation.setRightExpression(currentExpression);
7785
} else {
86+
7887
AndExpression nextAndExpression = new AndExpression();
7988
nextAndExpression.setLeftExpression(currentExpression);
8089

@@ -94,12 +103,14 @@ public static AndExpression concatenateWithAndExpression(List<Expression> expres
94103
* @return the generated count function call
95104
*/
96105
public static Function getJSqlCount(final List<String> countFields, final boolean distinct) {
106+
97107
List<Expression> countColumns = countFields //
98108
.stream() //
99109
.map(Column::new) //
100110
.collect(Collectors.toList());
101111

102112
ExpressionList countExpression = new ExpressionList(countColumns);
113+
103114
return new Function() //
104115
.withName("count") //
105116
.withParameters(countExpression) //
@@ -113,11 +124,12 @@ public static Function getJSqlCount(final List<String> countFields, final boolea
113124
* @return the generated lower function call
114125
*/
115126
public static Function getJSqlLower(String column) {
127+
116128
List<Expression> expressions = Collections.singletonList(new Column(column));
117129
ExpressionList lowerParamExpression = new ExpressionList(expressions);
130+
118131
return new Function() //
119132
.withName("lower") //
120133
.withParameters(lowerParamExpression);
121134
}
122-
123135
}

0 commit comments

Comments
 (0)