1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package examples.animal.data;
17
18 import static examples.animal.data.AnimalDataDynamicSqlSupport.*;
19 import static org.assertj.core.api.Assertions.assertThat;
20 import static org.junit.jupiter.api.Assertions.assertAll;
21 import static org.mybatis.dynamic.sql.SqlBuilder.*;
22
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.sql.Connection;
26 import java.sql.DriverManager;
27 import java.util.List;
28
29 import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
30 import org.apache.ibatis.jdbc.ScriptRunner;
31 import org.apache.ibatis.mapping.Environment;
32 import org.apache.ibatis.session.Configuration;
33 import org.apache.ibatis.session.SqlSession;
34 import org.apache.ibatis.session.SqlSessionFactory;
35 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
36 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
37 import org.junit.jupiter.api.BeforeEach;
38 import org.junit.jupiter.api.Test;
39 import org.mybatis.dynamic.sql.render.RenderingStrategies;
40 import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
41
42 class LimitAndOffsetTest {
43
44 private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
45 private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
46
47 private SqlSessionFactory sqlSessionFactory;
48
49 @BeforeEach
50 void setup() throws Exception {
51 Class.forName(JDBC_DRIVER);
52 try (InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql")) {
53 assert is != null;
54 try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "");
55 InputStreamReader isr = new InputStreamReader(is)) {
56 ScriptRunner sr = new ScriptRunner(connection);
57 sr.setLogWriter(null);
58 sr.runScript(isr);
59 }
60 }
61
62 UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
63 Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
64 Configuration config = new Configuration(environment);
65 config.addMapper(AnimalDataMapper.class);
66 sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
67 }
68
69 @Test
70 void testLimitAndOffsetAfterFrom() {
71 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
72 SelectStatementProvider selectStatement = select(animalData.allColumns())
73 .from(animalData)
74 .limit(3)
75 .offset(22)
76 .build()
77 .render(RenderingStrategies.MYBATIS3);
78
79 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
80 List<AnimalData> records = mapper.selectMany(selectStatement);
81
82 assertAll(
83 () -> assertThat(records).hasSize(3),
84 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
85 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1} offset #{parameters.p2}"),
86 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L),
87 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
88 );
89 }
90 }
91
92 @Test
93 void testLimitOnlyAfterFrom() {
94 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
95 SelectStatementProvider selectStatement = select(animalData.allColumns())
96 .from(animalData)
97 .limit(3)
98 .build()
99 .render(RenderingStrategies.MYBATIS3);
100
101 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
102 List<AnimalData> records = mapper.selectMany(selectStatement);
103
104 assertAll(
105 () -> assertThat(records).hasSize(3),
106 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
107 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1}"),
108 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
109 );
110 }
111 }
112
113 @Test
114 void testOffsetOnlyAfterFrom() {
115 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
116 SelectStatementProvider selectStatement = select(animalData.allColumns())
117 .from(animalData)
118 .offset(22)
119 .build()
120 .render(RenderingStrategies.MYBATIS3);
121
122 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
123 List<AnimalData> records = mapper.selectMany(selectStatement);
124
125 assertAll(
126 () -> assertThat(records).hasSize(43),
127 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
128 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows"),
129 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
130 );
131 }
132 }
133
134 @Test
135 void testLimitAndOffsetAfterWhere() {
136 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
137 SelectStatementProvider selectStatement = select(animalData.allColumns())
138 .from(animalData)
139 .where(id, isLessThan(50))
140 .and(id, isGreaterThan(22))
141 .limit(3)
142 .offset(22)
143 .build()
144 .render(RenderingStrategies.MYBATIS3);
145
146 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
147 List<AnimalData> records = mapper.selectMany(selectStatement);
148
149 assertAll(
150 () -> assertThat(records).hasSize(3),
151 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45),
152 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} and id > #{parameters.p2,jdbcType=INTEGER} limit #{parameters.p3} offset #{parameters.p4}"),
153 () -> assertThat(selectStatement.getParameters()).containsEntry("p3", 3L),
154 () -> assertThat(selectStatement.getParameters()).containsEntry("p4", 22L)
155 );
156 }
157 }
158
159 @Test
160 void testLimitOnlyAfterWhere() {
161 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
162 SelectStatementProvider selectStatement = select(animalData.allColumns())
163 .from(animalData)
164 .where(id, isLessThan(50))
165 .limit(3)
166 .build()
167 .render(RenderingStrategies.MYBATIS3);
168
169 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
170 List<AnimalData> records = mapper.selectMany(selectStatement);
171
172 assertAll(
173 () -> assertThat(records).hasSize(3),
174 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
175 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} limit #{parameters.p2}"),
176 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L)
177 );
178 }
179 }
180
181 @Test
182 void testOffsetOnlyAfterWhere() {
183 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
184 SelectStatementProvider selectStatement = select(animalData.allColumns())
185 .from(animalData)
186 .where(id, isLessThan(50))
187 .offset(22)
188 .build()
189 .render(RenderingStrategies.MYBATIS3);
190
191 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
192 List<AnimalData> records = mapper.selectMany(selectStatement);
193
194 assertAll(
195 () -> assertThat(records).hasSize(27),
196 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
197 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} offset #{parameters.p2} rows"),
198 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
199 );
200 }
201 }
202
203 @Test
204 void testLimitAndOffsetAfterOrderBy() {
205 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
206 SelectStatementProvider selectStatement = select(animalData.allColumns())
207 .from(animalData)
208 .orderBy(id)
209 .limit(3)
210 .offset(22)
211 .build()
212 .render(RenderingStrategies.MYBATIS3);
213
214 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
215 List<AnimalData> records = mapper.selectMany(selectStatement);
216
217 assertAll(
218 () -> assertThat(records).hasSize(3),
219 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
220 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1} offset #{parameters.p2}"),
221 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L),
222 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
223 );
224 }
225 }
226
227 @Test
228 void testLimitOnlyAfterOrderBy() {
229 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
230 SelectStatementProvider selectStatement = select(animalData.allColumns())
231 .from(animalData)
232 .orderBy(id)
233 .limit(3)
234 .build()
235 .render(RenderingStrategies.MYBATIS3);
236
237 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
238 List<AnimalData> records = mapper.selectMany(selectStatement);
239
240 assertAll(
241 () -> assertThat(records).hasSize(3),
242 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
243 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1}"),
244 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
245 );
246 }
247 }
248
249 @Test
250 void testOffsetOnlyAfterOrderBy() {
251 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
252 SelectStatementProvider selectStatement = select(animalData.allColumns())
253 .from(animalData)
254 .orderBy(id)
255 .offset(22)
256 .build()
257 .render(RenderingStrategies.MYBATIS3);
258
259 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
260 List<AnimalData> records = mapper.selectMany(selectStatement);
261
262 assertAll(
263 () -> assertThat(records).hasSize(43),
264 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
265 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows"),
266 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
267 );
268 }
269 }
270 }