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.assertj.core.api.Assertions.entry;
21 import static org.junit.jupiter.api.Assertions.assertAll;
22 import static org.mybatis.dynamic.sql.SqlBuilder.*;
23
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.sql.Connection;
27 import java.sql.DriverManager;
28 import java.util.List;
29
30 import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
31 import org.apache.ibatis.jdbc.ScriptRunner;
32 import org.apache.ibatis.mapping.Environment;
33 import org.apache.ibatis.session.Configuration;
34 import org.apache.ibatis.session.SqlSession;
35 import org.apache.ibatis.session.SqlSessionFactory;
36 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
37 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.mybatis.dynamic.sql.render.RenderingStrategies;
41 import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
42
43 class FetchFirstTest {
44
45 private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
46 private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
47
48 private SqlSessionFactory sqlSessionFactory;
49
50 @BeforeEach
51 void setup() throws Exception {
52 Class.forName(JDBC_DRIVER);
53 try (InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql")) {
54 assert is != null;
55 try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "");
56 InputStreamReader isr = new InputStreamReader(is)) {
57 ScriptRunner sr = new ScriptRunner(connection);
58 sr.setLogWriter(null);
59 sr.runScript(isr);
60 }
61 }
62
63 UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
64 Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
65 Configuration config = new Configuration(environment);
66 config.addMapper(AnimalDataMapper.class);
67 sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
68 }
69
70 @Test
71 void testOffsetAndFetchFirstAfterFrom() {
72 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
73 SelectStatementProvider selectStatement = select(animalData.allColumns())
74 .from(animalData)
75 .offset(22)
76 .fetchFirst(3).rowsOnly()
77 .build()
78 .render(RenderingStrategies.MYBATIS3);
79
80 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
81 List<AnimalData> records = mapper.selectMany(selectStatement);
82
83 assertAll(
84 () -> assertThat(records).hasSize(3),
85 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
86 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"),
87 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L),
88 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
89 );
90 }
91 }
92
93 @Test
94 void testFetchFirstOnlyAfterFrom() {
95 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
96 SelectStatementProvider selectStatement = select(animalData.allColumns())
97 .from(animalData)
98 .fetchFirst(3).rowsOnly()
99 .build()
100 .render(RenderingStrategies.MYBATIS3);
101
102 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
103 List<AnimalData> records = mapper.selectMany(selectStatement);
104
105 assertAll(
106 () -> assertThat(records).hasSize(3),
107 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
108 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData fetch first #{parameters.p1} rows only"),
109 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
110 );
111 }
112 }
113
114 @Test
115 void testOffsetAndFetchFirstAfterWhere() {
116 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
117 SelectStatementProvider selectStatement = select(animalData.allColumns())
118 .from(animalData)
119 .where(id, isLessThan(50))
120 .and(id, isGreaterThan(22))
121 .offset(22)
122 .fetchFirst(3).rowsOnly()
123 .build()
124 .render(RenderingStrategies.MYBATIS3);
125
126 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
127 List<AnimalData> records = mapper.selectMany(selectStatement);
128
129 assertAll(
130 () -> assertThat(records).hasSize(3),
131 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45),
132 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} and id > #{parameters.p2,jdbcType=INTEGER} offset #{parameters.p3} rows fetch first #{parameters.p4} rows only"),
133 () -> assertThat(selectStatement.getParameters()).contains(entry("p4", 3L), entry("p3", 22L))
134 );
135 }
136 }
137
138 @Test
139 void testFetchFirstOnlyAfterWhere() {
140 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
141 SelectStatementProvider selectStatement = select(animalData.allColumns())
142 .from(animalData)
143 .where(id, isLessThan(50))
144 .fetchFirst(3).rowsOnly()
145 .build()
146 .render(RenderingStrategies.MYBATIS3);
147
148 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
149 List<AnimalData> records = mapper.selectMany(selectStatement);
150
151 assertAll(
152 () -> assertThat(records).hasSize(3),
153 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
154 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} fetch first #{parameters.p2} rows only"),
155 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L)
156 );
157 }
158 }
159
160 @Test
161 void testOffsetAndFetchFirstAfterOrderBy() {
162 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
163 SelectStatementProvider selectStatement = select(animalData.allColumns())
164 .from(animalData)
165 .orderBy(id)
166 .offset(22)
167 .fetchFirst(3).rowsOnly()
168 .build()
169 .render(RenderingStrategies.MYBATIS3);
170
171 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
172 List<AnimalData> records = mapper.selectMany(selectStatement);
173
174 assertAll(
175 () -> assertThat(records).hasSize(3),
176 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
177 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"),
178 () -> assertThat(selectStatement)
179 .extracting(SelectStatementProvider::getParameters)
180 .extracting("p2", "p1")
181 .containsExactly(3L, 22L)
182 );
183 }
184 }
185
186 @Test
187 void testLimitOnlyAfterOrderBy() {
188 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
189 SelectStatementProvider selectStatement = select(animalData.allColumns())
190 .from(animalData)
191 .orderBy(id)
192 .fetchFirst(3).rowsOnly()
193 .build()
194 .render(RenderingStrategies.MYBATIS3);
195
196 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
197 List<AnimalData> records = mapper.selectMany(selectStatement);
198
199 assertAll(
200 () -> assertThat(records).hasSize(3),
201 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
202 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id fetch first #{parameters.p1} rows only"),
203 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
204 );
205 }
206 }
207 }