Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/test/java/examples/simple/ReusableWhereTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@

import static examples.simple.PersonDynamicSqlSupport.id;
import static examples.simple.PersonDynamicSqlSupport.occupation;
import static examples.simple.PersonDynamicSqlSupport.person;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan;
import static org.mybatis.dynamic.sql.SqlBuilder.isNull;
import static org.mybatis.dynamic.sql.SqlBuilder.select;
import static org.mybatis.dynamic.sql.SqlBuilder.where;

import java.io.InputStream;
Expand All @@ -38,6 +42,12 @@
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.QueryExpressionModel;
import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.SubQuery;
import org.mybatis.dynamic.sql.select.aggregate.CountAll;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.where.WhereApplier;

class ReusableWhereTest {
Expand Down Expand Up @@ -114,5 +124,64 @@ void testUpdate() {
}
}

@Test
void testTransformToCount() {
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper mapper = session.getMapper(PersonMapper.class);

SelectModel selectModel = select(PersonMapper.selectList)
.from(person)
.where(id, isLessThan(5))
.limit(2)
.build();

SelectStatementProvider selectStatement = selectModel.render(RenderingStrategies.MYBATIS3);

assertThat(selectStatement.getSelectStatement()).isEqualTo(
"select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id from Person where id < #{parameters.p1,jdbcType=INTEGER} limit #{parameters.p2}");
assertThat(selectStatement.getParameters()).containsOnly(entry("p1", 5), entry("p2", 2L));

SelectModel countModel = toCount(selectModel);
SelectStatementProvider countStatement = countModel.render(RenderingStrategies.MYBATIS3);

assertThat(countStatement.getSelectStatement()).isEqualTo(
"select count(*) from (select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id from Person where id < #{parameters.p1,jdbcType=INTEGER})");
assertThat(countStatement.getParameters()).containsOnly(entry("p1", 5));

long count = mapper.count(countStatement);

assertThat(count).isEqualTo(4);
}

}

private final WhereApplier commonWhere = where(id, isEqualTo(1)).or(occupation, isNull()).toWhereApplier();

/**
* This function transforms a select statement into a count statement by wrapping the select statement into
* a subquery. This can be used to create a single select statement and use it for both selects and counts
* in a paging scenario. This is more appropriate than a reusable where clause if the query is complex. For simple
* queries, a reusable where clause is best.
*
* <p>This function will strip any paging configuration, waits, order bys, etc. from the top level query. This
* will allow usage of a paging query for selects, and the transformed query for a count of all rows.
*
* @param selectModel the select model to transform
* @return a new select model that is "select count(*) from (subquery)" where subquery is the input select statement
*/
static SelectModel toCount(SelectModel selectModel) {
// remove any paging configuration, order by, wait clause, etc. from the incoming select model
SelectModel strippedSelectModel = SelectModel.withQueryExpressions(selectModel.queryExpressions().toList())
.withStatementConfiguration(selectModel.statementConfiguration())
.build();

QueryExpressionModel model = QueryExpressionModel
.withSelectList(List.of(new CountAll()))
.withTable(new SubQuery.Builder().withSelectModel(strippedSelectModel).build())
.build();

return SelectModel.withQueryExpressions(List.of(model))
.withStatementConfiguration(selectModel.statementConfiguration())
.build();
}
}