Skip to content

Commit d3b332b

Browse files
committed
Add ability to specify a custom parameter name for stand alone where
1 parent c6f0b4a commit d3b332b

File tree

6 files changed

+129
-22
lines changed

6 files changed

+129
-22
lines changed

src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.ArrayList;
1919
import java.util.List;
20+
import java.util.Optional;
2021
import java.util.concurrent.atomic.AtomicInteger;
2122
import java.util.function.Function;
2223
import java.util.stream.Stream;
@@ -45,16 +46,32 @@ public <R> Stream<R> mapCriteria(Function<SqlCriterion<?>, R> mapper) {
4546
* @return rendered where clause
4647
*/
4748
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy) {
48-
return render(renderingStrategy, TableAliasCalculator.empty());
49+
return render(renderingStrategy, TableAliasCalculator.empty(), Optional.empty());
4950
}
5051

5152
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy,
5253
TableAliasCalculator tableAliasCalculator) {
54+
return render(renderingStrategy, tableAliasCalculator, Optional.empty());
55+
}
56+
57+
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy,
58+
String parameterName) {
59+
return render(renderingStrategy, TableAliasCalculator.empty(), Optional.of(parameterName));
60+
}
61+
62+
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy,
63+
TableAliasCalculator tableAliasCalculator, String parameterName) {
64+
return render(renderingStrategy, tableAliasCalculator, Optional.of(parameterName));
65+
}
66+
67+
private WhereClauseAndParameters render(RenderingStrategy renderingStrategy,
68+
TableAliasCalculator tableAliasCalculator, Optional<String> parameterName) {
5369
return new WhereRenderer.Builder()
5470
.withWhereModel(this)
5571
.withRenderingStrategy(renderingStrategy)
5672
.withSequence(new AtomicInteger(1))
5773
.withTableAliasCalculator(tableAliasCalculator)
74+
.withParameterName(parameterName)
5875
.build()
5976
.render();
6077
}

src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;
2020

2121
import java.util.Objects;
22+
import java.util.Optional;
2223
import java.util.concurrent.atomic.AtomicInteger;
2324
import java.util.stream.Collectors;
2425

@@ -33,11 +34,13 @@ public class CriterionRenderer {
3334
private AtomicInteger sequence;
3435
private RenderingStrategy renderingStrategy;
3536
private TableAliasCalculator tableAliasCalculator;
37+
private Optional<String> parameterName = Optional.empty();
3638

3739
private CriterionRenderer(Builder builder) {
3840
sequence = Objects.requireNonNull(builder.sequence);
3941
renderingStrategy = Objects.requireNonNull(builder.renderingStrategy);
4042
tableAliasCalculator = Objects.requireNonNull(builder.tableAliasCalculator);
43+
parameterName = Objects.requireNonNull(builder.parameterName);
4144
}
4245

4346
public <T> FragmentAndParameters render(SqlCriterion<T> criterion) {
@@ -107,6 +110,7 @@ private <T> FragmentAndParameters renderCondition(SqlCriterion<T> criterion) {
107110
.withSequence(sequence)
108111
.withColumn(criterion.column())
109112
.withTableAliasCalculator(tableAliasCalculator)
113+
.withParameterName(parameterName)
110114
.build();
111115
return criterion.condition().accept(visitor);
112116
}
@@ -115,6 +119,7 @@ public static class Builder {
115119
private AtomicInteger sequence;
116120
private RenderingStrategy renderingStrategy;
117121
private TableAliasCalculator tableAliasCalculator;
122+
private Optional<String> parameterName = Optional.empty();
118123

119124
public Builder withSequence(AtomicInteger sequence) {
120125
this.sequence = sequence;
@@ -130,6 +135,11 @@ public Builder withTableAliasCalculator(TableAliasCalculator tableAliasCalculato
130135
this.tableAliasCalculator = tableAliasCalculator;
131136
return this;
132137
}
138+
139+
public Builder withParameterName(Optional<String> parameterName) {
140+
this.parameterName = parameterName;
141+
return this;
142+
}
133143

134144
public CriterionRenderer build() {
135145
return new CriterionRenderer(this);

src/main/java/org/mybatis/dynamic/sql/where/render/WhereConditionVisitor.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.mybatis.dynamic.sql.where.render;
1717

1818
import java.util.Objects;
19+
import java.util.Optional;
1920
import java.util.concurrent.atomic.AtomicInteger;
2021

2122
import org.mybatis.dynamic.sql.AbstractListValueCondition;
@@ -34,17 +35,19 @@
3435

3536
public class WhereConditionVisitor<T> implements ConditionVisitor<T, FragmentAndParameters> {
3637

37-
private static final String PARAMETERS_PREFIX = "parameters"; //$NON-NLS-1$
3838
private RenderingStrategy renderingStrategy;
3939
private AtomicInteger sequence;
4040
private BindableColumn<T> column;
4141
private TableAliasCalculator tableAliasCalculator;
42+
private String parameterPrefix;
4243

4344
private WhereConditionVisitor(Builder<T> builder) {
4445
renderingStrategy = Objects.requireNonNull(builder.renderingStrategy);
4546
sequence = Objects.requireNonNull(builder.sequence);
4647
column = Objects.requireNonNull(builder.column);
4748
tableAliasCalculator = Objects.requireNonNull(builder.tableAliasCalculator);
49+
parameterPrefix = builder.parameterName.map(name -> name + ".parameters") //$NON-NLS-1$
50+
.orElse("parameters"); //$NON-NLS-1$
4851
}
4952

5053
@Override
@@ -122,7 +125,7 @@ private String formatParameterMapKey(int number) {
122125
}
123126

124127
private String getFormattedJdbcPlaceholder(String mapKey) {
125-
return renderingStrategy.getFormattedJdbcPlaceholder(column, PARAMETERS_PREFIX, mapKey);
128+
return renderingStrategy.getFormattedJdbcPlaceholder(column, parameterPrefix, mapKey);
126129
}
127130

128131
private String columnName() {
@@ -134,6 +137,7 @@ public static class Builder<T> {
134137
private AtomicInteger sequence;
135138
private BindableColumn<T> column;
136139
private TableAliasCalculator tableAliasCalculator;
140+
private Optional<String> parameterName = Optional.empty();
137141

138142
public Builder<T> withSequence(AtomicInteger sequence) {
139143
this.sequence = sequence;
@@ -154,6 +158,11 @@ public Builder<T> withTableAliasCalculator(TableAliasCalculator tableAliasCalcul
154158
this.tableAliasCalculator = tableAliasCalculator;
155159
return this;
156160
}
161+
162+
public Builder<T> withParameterName(Optional<String> parameterName) {
163+
this.parameterName = parameterName;
164+
return this;
165+
}
157166

158167
public WhereConditionVisitor<T> build() {
159168
return new WhereConditionVisitor<>(this);

src/main/java/org/mybatis/dynamic/sql/where/render/WhereRenderer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.mybatis.dynamic.sql.where.render;
1717

1818
import java.util.Objects;
19+
import java.util.Optional;
1920
import java.util.concurrent.atomic.AtomicInteger;
2021
import java.util.stream.Collectors;
2122

@@ -31,12 +32,14 @@ public class WhereRenderer {
3132
private AtomicInteger sequence;
3233
private RenderingStrategy renderingStrategy;
3334
private TableAliasCalculator tableAliasCalculator;
35+
private Optional<String> parameterName;
3436

3537
private WhereRenderer(Builder builder) {
3638
whereModel = Objects.requireNonNull(builder.whereModel);
3739
sequence = Objects.requireNonNull(builder.sequence);
3840
renderingStrategy = Objects.requireNonNull(builder.renderingStrategy);
3941
tableAliasCalculator = Objects.requireNonNull(builder.tableAliasCalculator);
42+
parameterName = Objects.requireNonNull(builder.parameterName);
4043
}
4144

4245
public WhereClauseAndParameters render() {
@@ -54,6 +57,7 @@ private FragmentAndParameters render(SqlCriterion<?> criterion) {
5457
.withSequence(sequence)
5558
.withRenderingStrategy(renderingStrategy)
5659
.withTableAliasCalculator(tableAliasCalculator)
60+
.withParameterName(parameterName)
5761
.build()
5862
.render(criterion);
5963
}
@@ -68,6 +72,7 @@ public static class Builder {
6872
private RenderingStrategy renderingStrategy;
6973
private TableAliasCalculator tableAliasCalculator;
7074
private AtomicInteger sequence;
75+
private Optional<String> parameterName = Optional.empty();
7176

7277
public Builder withWhereModel(WhereModel whereModel) {
7378
this.whereModel = whereModel;
@@ -88,6 +93,11 @@ public Builder withSequence(AtomicInteger sequence) {
8893
this.sequence = sequence;
8994
return this;
9095
}
96+
97+
public Builder withParameterName(Optional<String> parameterName) {
98+
this.parameterName = parameterName;
99+
return this;
100+
}
91101

92102
public WhereRenderer build() {
93103
return new WhereRenderer(this);

src/test/java/examples/animal/data/AnimalDataMapper.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.ibatis.annotations.DeleteProvider;
2222
import org.apache.ibatis.annotations.InsertProvider;
23+
import org.apache.ibatis.annotations.Param;
2324
import org.apache.ibatis.annotations.Result;
2425
import org.apache.ibatis.annotations.ResultMap;
2526
import org.apache.ibatis.annotations.Results;
@@ -81,4 +82,26 @@ public interface AnimalDataMapper {
8182
})
8283
@ResultMap("AnimalDataResult")
8384
List<AnimalData> selectByExampleWithAlias(WhereClauseAndParameters whereClause);
85+
86+
@Select({
87+
"select id, animal_name, brain_weight, body_weight",
88+
"from AnimalData",
89+
"${whereSupport.whereClause}",
90+
"order by id",
91+
"OFFSET #{offset,jdbcType=INTEGER} LIMIT #{limit,jdbcType=INTEGER}"
92+
})
93+
@ResultMap("AnimalDataResult")
94+
List<AnimalData> selectByExampleWithLimitAndOffset(@Param("whereSupport") WhereClauseAndParameters whereClause,
95+
@Param("limit") int limit, @Param("offset") int offset);
96+
97+
@Select({
98+
"select b.id, b.animal_name, b.brain_weight, b.body_weight",
99+
"from AnimalData b",
100+
"${whereSupport.whereClause}",
101+
"order by id",
102+
"OFFSET #{offset,jdbcType=INTEGER} LIMIT #{limit,jdbcType=INTEGER}"
103+
})
104+
@ResultMap("AnimalDataResult")
105+
List<AnimalData> selectByExampleWithAliasLimitAndOffset(@Param("whereSupport") WhereClauseAndParameters whereClause,
106+
@Param("limit") int limit, @Param("offset") int offset);
84107
}

src/test/java/examples/animal/data/AnimalDataTest.java

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,63 @@ public void testSelectRowsNotBetweenWithStandaloneWhereClause() {
191191
}
192192
}
193193

194+
@Test
195+
public void testComplexConditionWithStandaloneWhereAndTableAlias() {
196+
SqlSession sqlSession = sqlSessionFactory.openSession();
197+
try {
198+
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
199+
200+
WhereClauseAndParameters whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
201+
.build()
202+
.render(RenderingStrategy.MYBATIS3, TableAliasCalculator.of(animalData, "a"));
203+
204+
assertThat(whereClause.whereClause()).isEqualTo("where (a.id = #{parameters.p1,jdbcType=INTEGER} or a.body_weight > #{parameters.p2,jdbcType=DOUBLE})");
205+
206+
List<AnimalData> animals = mapper.selectByExampleWithAlias(whereClause);
207+
assertThat(animals.size()).isEqualTo(59);
208+
} finally {
209+
sqlSession.close();
210+
}
211+
}
212+
213+
@Test
214+
public void testSelectRowsNotBetweenWithStandaloneWhereClauseLimitAndOffset() {
215+
SqlSession sqlSession = sqlSessionFactory.openSession();
216+
try {
217+
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
218+
219+
WhereClauseAndParameters whereClause = where(id, isLessThan(60))
220+
.build()
221+
.render(RenderingStrategy.MYBATIS3, "whereSupport");
222+
223+
List<AnimalData> animals = mapper.selectByExampleWithLimitAndOffset(whereClause, 5, 15);
224+
assertThat(animals.size()).isEqualTo(5);
225+
assertThat(animals.get(0).getId()).isEqualTo(16);
226+
227+
} finally {
228+
sqlSession.close();
229+
}
230+
}
231+
232+
@Test
233+
public void testSelectRowsNotBetweenWithStandaloneWhereClauseAliasLimitAndOffset() {
234+
SqlSession sqlSession = sqlSessionFactory.openSession();
235+
try {
236+
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
237+
238+
WhereClauseAndParameters whereClause = where(id, isLessThan(60))
239+
.build()
240+
.render(RenderingStrategy.MYBATIS3, TableAliasCalculator.of(animalData, "b"), "whereSupport");
241+
242+
List<AnimalData> animals = mapper.selectByExampleWithAliasLimitAndOffset(whereClause, 3, 24);
243+
assertThat(animals.size()).isEqualTo(3);
244+
assertThat(animals.get(0).getId()).isEqualTo(25);
245+
246+
} finally {
247+
sqlSession.close();
248+
}
249+
}
250+
194251
@Test
195252
public void testUnionSelectWithWhere() {
196253
SqlSession sqlSession = sqlSessionFactory.openSession();
@@ -744,25 +801,6 @@ public void testComplexCondition() {
744801
}
745802
}
746803

747-
@Test
748-
public void testComplexConditionWithStandaloneWhereAndTableAlias() {
749-
SqlSession sqlSession = sqlSessionFactory.openSession();
750-
try {
751-
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
752-
753-
WhereClauseAndParameters whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
754-
.build()
755-
.render(RenderingStrategy.MYBATIS3, TableAliasCalculator.of(animalData, "a"));
756-
757-
assertThat(whereClause.whereClause()).isEqualTo("where (a.id = #{parameters.p1,jdbcType=INTEGER} or a.body_weight > #{parameters.p2,jdbcType=DOUBLE})");
758-
759-
List<AnimalData> animals = mapper.selectByExampleWithAlias(whereClause);
760-
assertThat(animals.size()).isEqualTo(59);
761-
} finally {
762-
sqlSession.close();
763-
}
764-
}
765-
766804
@Test
767805
public void testUpdateByExample() {
768806
SqlSession sqlSession = sqlSessionFactory.openSession();

0 commit comments

Comments
 (0)