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 InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql");
53 assert is != null;
54 try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) {
55 ScriptRunner sr = new ScriptRunner(connection);
56 sr.setLogWriter(null);
57 sr.runScript(new InputStreamReader(is));
58 }
59
60 UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
61 Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
62 Configuration config = new Configuration(environment);
63 config.addMapper(AnimalDataMapper.class);
64 sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
65 }
66
67 @Test
68 void testLimitAndOffsetAfterFrom() {
69 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
70 SelectStatementProvider selectStatement = select(animalData.allColumns())
71 .from(animalData)
72 .limit(3)
73 .offset(22)
74 .build()
75 .render(RenderingStrategies.MYBATIS3);
76
77 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
78 List<AnimalData> records = mapper.selectMany(selectStatement);
79
80 assertAll(
81 () -> assertThat(records).hasSize(3),
82 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
83 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1} offset #{parameters.p2}"),
84 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L),
85 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
86 );
87 }
88 }
89
90 @Test
91 void testLimitOnlyAfterFrom() {
92 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
93 SelectStatementProvider selectStatement = select(animalData.allColumns())
94 .from(animalData)
95 .limit(3)
96 .build()
97 .render(RenderingStrategies.MYBATIS3);
98
99 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
100 List<AnimalData> records = mapper.selectMany(selectStatement);
101
102 assertAll(
103 () -> assertThat(records).hasSize(3),
104 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
105 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1}"),
106 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
107 );
108 }
109 }
110
111 @Test
112 void testOffsetOnlyAfterFrom() {
113 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
114 SelectStatementProvider selectStatement = select(animalData.allColumns())
115 .from(animalData)
116 .offset(22)
117 .build()
118 .render(RenderingStrategies.MYBATIS3);
119
120 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
121 List<AnimalData> records = mapper.selectMany(selectStatement);
122
123 assertAll(
124 () -> assertThat(records).hasSize(43),
125 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
126 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows"),
127 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
128 );
129 }
130 }
131
132 @Test
133 void testLimitAndOffsetAfterWhere() {
134 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
135 SelectStatementProvider selectStatement = select(animalData.allColumns())
136 .from(animalData)
137 .where(id, isLessThan(50))
138 .and(id, isGreaterThan(22))
139 .limit(3)
140 .offset(22)
141 .build()
142 .render(RenderingStrategies.MYBATIS3);
143
144 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
145 List<AnimalData> records = mapper.selectMany(selectStatement);
146
147 assertAll(
148 () -> assertThat(records).hasSize(3),
149 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45),
150 () -> 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}"),
151 () -> assertThat(selectStatement.getParameters()).containsEntry("p3", 3L),
152 () -> assertThat(selectStatement.getParameters()).containsEntry("p4", 22L)
153 );
154 }
155 }
156
157 @Test
158 void testLimitOnlyAfterWhere() {
159 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
160 SelectStatementProvider selectStatement = select(animalData.allColumns())
161 .from(animalData)
162 .where(id, isLessThan(50))
163 .limit(3)
164 .build()
165 .render(RenderingStrategies.MYBATIS3);
166
167 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
168 List<AnimalData> records = mapper.selectMany(selectStatement);
169
170 assertAll(
171 () -> assertThat(records).hasSize(3),
172 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
173 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} limit #{parameters.p2}"),
174 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L)
175 );
176 }
177 }
178
179 @Test
180 void testOffsetOnlyAfterWhere() {
181 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
182 SelectStatementProvider selectStatement = select(animalData.allColumns())
183 .from(animalData)
184 .where(id, isLessThan(50))
185 .offset(22)
186 .build()
187 .render(RenderingStrategies.MYBATIS3);
188
189 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
190 List<AnimalData> records = mapper.selectMany(selectStatement);
191
192 assertAll(
193 () -> assertThat(records).hasSize(27),
194 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
195 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} offset #{parameters.p2} rows"),
196 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
197 );
198 }
199 }
200
201 @Test
202 void testLimitAndOffsetAfterOrderBy() {
203 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
204 SelectStatementProvider selectStatement = select(animalData.allColumns())
205 .from(animalData)
206 .orderBy(id)
207 .limit(3)
208 .offset(22)
209 .build()
210 .render(RenderingStrategies.MYBATIS3);
211
212 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
213 List<AnimalData> records = mapper.selectMany(selectStatement);
214
215 assertAll(
216 () -> assertThat(records).hasSize(3),
217 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
218 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1} offset #{parameters.p2}"),
219 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L),
220 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L)
221 );
222 }
223 }
224
225 @Test
226 void testLimitOnlyAfterOrderBy() {
227 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
228 SelectStatementProvider selectStatement = select(animalData.allColumns())
229 .from(animalData)
230 .orderBy(id)
231 .limit(3)
232 .build()
233 .render(RenderingStrategies.MYBATIS3);
234
235 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
236 List<AnimalData> records = mapper.selectMany(selectStatement);
237
238 assertAll(
239 () -> assertThat(records).hasSize(3),
240 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
241 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1}"),
242 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
243 );
244 }
245 }
246
247 @Test
248 void testOffsetOnlyAfterOrderBy() {
249 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
250 SelectStatementProvider selectStatement = select(animalData.allColumns())
251 .from(animalData)
252 .orderBy(id)
253 .offset(22)
254 .build()
255 .render(RenderingStrategies.MYBATIS3);
256
257 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
258 List<AnimalData> records = mapper.selectMany(selectStatement);
259
260 assertAll(
261 () -> assertThat(records).hasSize(43),
262 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
263 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows"),
264 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
265 );
266 }
267 }
268 }