Skip to content

Commit c5b45b0

Browse files
committed
WHere renderer should return Optional
1 parent 008749c commit c5b45b0

File tree

6 files changed

+137
-126
lines changed

6 files changed

+137
-126
lines changed

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

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
import org.mybatis.dynamic.sql.where.render.WhereRenderer;
3232

3333
public class WhereModel {
34-
private static final WhereClauseProvider EMPTY_WHERE_CLAUSE =
35-
new WhereClauseProvider.Builder().withWhereClause("").build(); //$NON-NLS-1$
36-
3734
private final SqlCriterion initialCriterion;
3835
private final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>();
3936

@@ -66,48 +63,44 @@ public boolean isNonRenderingClauseAllowed() {
6663
*
6764
* @return rendered where clause
6865
*/
69-
public WhereClauseProvider render(RenderingStrategy renderingStrategy) {
66+
public Optional<WhereClauseProvider> render(RenderingStrategy renderingStrategy) {
7067
return WhereRenderer.withWhereModel(this)
7168
.withRenderingStrategy(renderingStrategy)
7269
.withSequence(new AtomicInteger(1))
7370
.withTableAliasCalculator(TableAliasCalculator.empty())
7471
.build()
75-
.render()
76-
.orElse(EMPTY_WHERE_CLAUSE);
72+
.render();
7773
}
7874

79-
public WhereClauseProvider render(RenderingStrategy renderingStrategy,
75+
public Optional<WhereClauseProvider> render(RenderingStrategy renderingStrategy,
8076
TableAliasCalculator tableAliasCalculator) {
8177
return WhereRenderer.withWhereModel(this)
8278
.withRenderingStrategy(renderingStrategy)
8379
.withSequence(new AtomicInteger(1))
8480
.withTableAliasCalculator(tableAliasCalculator)
8581
.build()
86-
.render()
87-
.orElse(EMPTY_WHERE_CLAUSE);
82+
.render();
8883
}
8984

90-
public WhereClauseProvider render(RenderingStrategy renderingStrategy,
85+
public Optional<WhereClauseProvider> render(RenderingStrategy renderingStrategy,
9186
String parameterName) {
9287
return WhereRenderer.withWhereModel(this)
9388
.withRenderingStrategy(renderingStrategy)
9489
.withSequence(new AtomicInteger(1))
9590
.withTableAliasCalculator(TableAliasCalculator.empty())
9691
.withParameterName(parameterName)
9792
.build()
98-
.render()
99-
.orElse(EMPTY_WHERE_CLAUSE);
93+
.render();
10094
}
10195

102-
public WhereClauseProvider render(RenderingStrategy renderingStrategy,
96+
public Optional<WhereClauseProvider> render(RenderingStrategy renderingStrategy,
10397
TableAliasCalculator tableAliasCalculator, String parameterName) {
10498
return WhereRenderer.withWhereModel(this)
10599
.withRenderingStrategy(renderingStrategy)
106100
.withSequence(new AtomicInteger(1))
107101
.withTableAliasCalculator(tableAliasCalculator)
108102
.withParameterName(parameterName)
109103
.build()
110-
.render()
111-
.orElse(EMPTY_WHERE_CLAUSE);
104+
.render();
112105
}
113106
}

src/site/markdown/docs/whereClauses.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ library. If you want to use a stand alone where clause, you can code a mapper me
8787
You can build a stand alone where clause and call your mapper like this:
8888

8989
```java
90-
WhereClauseProvider whereClause = where(id, isNotBetween(10).and(60))
90+
Optional<WhereClauseProvider> whereClause = where(id, isNotBetween(10).and(60))
9191
.build()
9292
.render(RenderingStrategies.MYBATIS3);
9393

94-
List<AnimalData> animals = mapper.selectWithWhereClause(whereClause);
94+
List<AnimalData> animals = whereClause.map(wc -> mapper.selectWithWhereClause(wc)).orElse(Collections.emptyList());
9595
```
9696
This method works well when there are no other parameters needed for the statement and when there are no table aliases
9797
involved. If you have those other needs, then see the following.
@@ -112,11 +112,11 @@ If you need to use a table alias in the generated where clause you can supply it
112112
Then you can specify the alias for the generated WHERE clause on the render method like this:
113113

114114
```java
115-
WhereClauseProvider whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
115+
Optional<WhereClauseProvider> whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
116116
.build()
117117
.render(RenderingStrategies.MYBATIS3, TableAliasCalculator.of(animalData, "a"));
118118

119-
List<AnimalData> animals = mapper.selectWithWhereClauseAndAlias(whereClause);
119+
List<AnimalData> animals = whereClause.map(wc -> mapper.selectWithWhereClauseAndAlias(wc)).orElse(Collections.emptyList());
120120
```
121121
It is more likely that you will be using table aliases with hand coded joins where there is more than on table alias.
122122
In this case, you supply a `Map<SqlTable, String>` to the TableAliasCalculator that holds an alias for each table
@@ -143,11 +143,11 @@ In this mapper method there are three parameters. So in this case it will be ne
143143
parameter name to use the for rendered where clause. That code looks like this:
144144

145145
```java
146-
WhereClauseProvider whereClause = where(id, isLessThan(60))
146+
Optional<WhereClauseProvider> whereClause = where(id, isLessThan(60))
147147
.build()
148148
.render(RenderingStrategies.MYBATIS3, "whereClauseProvider");
149149

150-
List<AnimalData> animals = mapper.selectWithWhereClauseLimitAndOffset(whereClause, 5, 15);
150+
List<AnimalData> animals = whereClause.map(wc -> mapper.selectWithWhereClauseLimitAndOffset(wc, 5, 15)).orElse(Collections.emptyList());
151151
```
152152
Notice that the string `whereClauseProvider` is used both as the parameter name in the mapper `@Param` annotation,
153153
and the parameter name in the `render` method.

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

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.List;
3434
import java.util.Map;
3535
import java.util.Objects;
36+
import java.util.Optional;
3637

3738
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
3839
import org.apache.ibatis.jdbc.ScriptRunner;
@@ -298,13 +299,15 @@ void testSelectRowsNotBetweenWithStandaloneWhereClause() {
298299
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
299300
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
300301

301-
WhereClauseProvider whereClause = where(id, isNotBetween(10).and(60))
302+
Optional<WhereClauseProvider> whereClause = where(id, isNotBetween(10).and(60))
302303
.or(id, isIn(25, 27))
303304
.build()
304305
.render(RenderingStrategies.MYBATIS3);
305306

306-
List<AnimalData> animals = mapper.selectWithWhereClause(whereClause);
307-
assertThat(animals).hasSize(16);
307+
assertThat(whereClause).hasValueSatisfying(wc -> {
308+
List<AnimalData> animals = mapper.selectWithWhereClause(wc);
309+
assertThat(animals).hasSize(16);
310+
});
308311
}
309312
}
310313

@@ -313,14 +316,15 @@ void testComplexConditionWithStandaloneWhereAndTableAlias() {
313316
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
314317
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
315318

316-
WhereClauseProvider whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
319+
Optional<WhereClauseProvider> whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
317320
.build()
318321
.render(RenderingStrategies.MYBATIS3, ExplicitTableAliasCalculator.of(animalData, "a"));
319322

320-
assertThat(whereClause.getWhereClause()).isEqualTo("where (a.id = #{parameters.p1,jdbcType=INTEGER} or a.body_weight > #{parameters.p2,jdbcType=DOUBLE})");
321-
322-
List<AnimalData> animals = mapper.selectWithWhereClauseAndAlias(whereClause);
323-
assertThat(animals).hasSize(59);
323+
assertThat(whereClause).hasValueSatisfying(wc -> {
324+
assertThat(wc.getWhereClause()).isEqualTo("where (a.id = #{parameters.p1,jdbcType=INTEGER} or a.body_weight > #{parameters.p2,jdbcType=DOUBLE})");
325+
List<AnimalData> animals = mapper.selectWithWhereClauseAndAlias(wc);
326+
assertThat(animals).hasSize(59);
327+
});
324328
}
325329
}
326330

@@ -329,15 +333,15 @@ void testSelectRowsNotBetweenWithStandaloneWhereClauseLimitAndOffset() {
329333
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
330334
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
331335

332-
WhereClauseProvider whereClause = where(id, isLessThan(60))
336+
Optional<WhereClauseProvider> whereClause = where(id, isLessThan(60))
333337
.build()
334338
.render(RenderingStrategies.MYBATIS3, "whereClauseProvider");
335339

336-
List<AnimalData> animals = mapper.selectWithWhereClauseLimitAndOffset(whereClause, 5, 15);
337-
assertAll(
338-
() -> assertThat(animals).hasSize(5),
339-
() -> assertThat(animals.get(0).getId()).isEqualTo(16)
340-
);
340+
assertThat(whereClause).hasValueSatisfying(wc -> {
341+
List<AnimalData> animals = mapper.selectWithWhereClauseLimitAndOffset(wc, 5, 15);
342+
assertThat(animals).hasSize(5);
343+
assertThat(animals.get(0).getId()).isEqualTo(16);
344+
});
341345
}
342346
}
343347

@@ -346,16 +350,17 @@ void testSelectRowsNotBetweenWithStandaloneWhereClauseAliasLimitAndOffset() {
346350
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
347351
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
348352

349-
WhereClauseProvider whereClause = where(id, isLessThan(60))
353+
Optional<WhereClauseProvider> whereClause = where(id, isLessThan(60))
350354
.build()
351355
.render(RenderingStrategies.MYBATIS3, ExplicitTableAliasCalculator.of(animalData, "b"),
352356
"whereClauseProvider");
353357

354-
List<AnimalData> animals = mapper.selectWithWhereClauseAliasLimitAndOffset(whereClause, 3, 24);
355-
assertAll(
356-
() -> assertThat(animals).hasSize(3),
357-
() -> assertThat(animals.get(0).getId()).isEqualTo(25)
358-
);
358+
assertThat(whereClause).hasValueSatisfying(wc -> {
359+
List<AnimalData> animals = mapper.selectWithWhereClauseAliasLimitAndOffset(wc, 3, 24);
360+
assertThat(animals).hasSize(3);
361+
assertThat(animals.get(0).getId()).isEqualTo(25);
362+
});
363+
359364
}
360365
}
361366

src/test/java/examples/emptywhere/EmptyWhereTest.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,15 @@ void testWhereThreeConditions() {
267267
builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull));
268268
builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull));
269269

270-
WhereClauseProvider whereClause = builder.build().render(RenderingStrategies.MYBATIS3);
270+
Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3);
271271

272272
String expected = "where id = #{parameters.p1}"
273273
+ " and first_name = #{parameters.p2}"
274274
+ " and last_name = #{parameters.p3}";
275275

276-
assertThat(whereClause.getWhereClause()).isEqualTo(expected);
276+
assertThat(whereClause.map(WhereClauseProvider::getWhereClause)).hasValueSatisfying(wc ->
277+
assertThat(wc).isEqualTo(expected)
278+
);
277279
}
278280

279281
@ParameterizedTest
@@ -285,9 +287,15 @@ void testWhereVariations(Variation variation) {
285287
builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull));
286288
builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true));
287289

288-
WhereClauseProvider whereClause = builder.build().render(RenderingStrategies.MYBATIS3);
290+
Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3);
289291

290-
assertThat(whereClause.getWhereClause()).isEqualTo(variation.whereClause);
292+
if (variation.firstName == null && variation.lastName == null) {
293+
assertThat(whereClause).isEmpty();
294+
} else {
295+
assertThat(whereClause.map(WhereClauseProvider::getWhereClause)).hasValueSatisfying(wc ->
296+
assertThat(wc).isEqualTo(variation.whereClause)
297+
);
298+
}
291299
}
292300

293301
private static class Variation {

src/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mybatis.dynamic.sql.SqlBuilder.*;
2020

2121
import java.sql.JDBCType;
22+
import java.util.Optional;
2223

2324
import org.junit.jupiter.api.Test;
2425
import org.mybatis.dynamic.sql.SqlColumn;
@@ -33,9 +34,11 @@ void testThatParameterNameCarriesToSubCriteria() {
3334
SqlTable table = SqlTable.of("foo");
3435
SqlColumn<Integer> id = table.column("id", JDBCType.INTEGER);
3536

36-
WhereClauseProvider wc = where(id, isEqualTo(3), or(id, isEqualTo(4))).build()
37+
Optional<WhereClauseProvider> whereClause = where(id, isEqualTo(3), or(id, isEqualTo(4))).build()
3738
.render(RenderingStrategies.MYBATIS3, "myName");
3839

39-
assertThat(wc.getWhereClause()).isEqualTo("where (id = #{myName.parameters.p1,jdbcType=INTEGER} or id = #{myName.parameters.p2,jdbcType=INTEGER})");
40+
assertThat(whereClause.map(WhereClauseProvider::getWhereClause)).hasValueSatisfying(wc ->
41+
assertThat(wc).isEqualTo("where (id = #{myName.parameters.p1,jdbcType=INTEGER} or id = #{myName.parameters.p2,jdbcType=INTEGER})")
42+
);
4043
}
4144
}

0 commit comments

Comments
 (0)