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 InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql");
54 assert is != null;
55 try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) {
56 ScriptRunner sr = new ScriptRunner(connection);
57 sr.setLogWriter(null);
58 sr.runScript(new InputStreamReader(is));
59 }
60
61 UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
62 Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
63 Configuration config = new Configuration(environment);
64 config.addMapper(AnimalDataMapper.class);
65 sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
66 }
67
68 @Test
69 void testOffsetAndFetchFirstAfterFrom() {
70 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
71 SelectStatementProvider selectStatement = select(animalData.allColumns())
72 .from(animalData)
73 .offset(22)
74 .fetchFirst(3).rowsOnly()
75 .build()
76 .render(RenderingStrategies.MYBATIS3);
77
78 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
79 List<AnimalData> records = mapper.selectMany(selectStatement);
80
81 assertAll(
82 () -> assertThat(records).hasSize(3),
83 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23),
84 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"),
85 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L),
86 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L)
87 );
88 }
89 }
90
91 @Test
92 void testFetchFirstOnlyAfterFrom() {
93 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
94 SelectStatementProvider selectStatement = select(animalData.allColumns())
95 .from(animalData)
96 .fetchFirst(3).rowsOnly()
97 .build()
98 .render(RenderingStrategies.MYBATIS3);
99
100 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
101 List<AnimalData> records = mapper.selectMany(selectStatement);
102
103 assertAll(
104 () -> assertThat(records).hasSize(3),
105 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
106 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData fetch first #{parameters.p1} rows only"),
107 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
108 );
109 }
110 }
111
112 @Test
113 void testOffsetAndFetchFirstAfterWhere() {
114 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
115 SelectStatementProvider selectStatement = select(animalData.allColumns())
116 .from(animalData)
117 .where(id, isLessThan(50))
118 .and(id, isGreaterThan(22))
119 .offset(22)
120 .fetchFirst(3).rowsOnly()
121 .build()
122 .render(RenderingStrategies.MYBATIS3);
123
124 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
125 List<AnimalData> records = mapper.selectMany(selectStatement);
126
127 assertAll(
128 () -> assertThat(records).hasSize(3),
129 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45),
130 () -> 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"),
131 () -> assertThat(selectStatement.getParameters()).contains(entry("p4", 3L), entry("p3", 22L))
132 );
133 }
134 }
135
136 @Test
137 void testFetchFirstOnlyAfterWhere() {
138 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
139 SelectStatementProvider selectStatement = select(animalData.allColumns())
140 .from(animalData)
141 .where(id, isLessThan(50))
142 .fetchFirst(3).rowsOnly()
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(1),
152 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} fetch first #{parameters.p2} rows only"),
153 () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L)
154 );
155 }
156 }
157
158 @Test
159 void testOffsetAndFetchFirstAfterOrderBy() {
160 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
161 SelectStatementProvider selectStatement = select(animalData.allColumns())
162 .from(animalData)
163 .orderBy(id)
164 .offset(22)
165 .fetchFirst(3).rowsOnly()
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(23),
175 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"),
176 () -> assertThat(selectStatement)
177 .extracting(SelectStatementProvider::getParameters)
178 .extracting("p2", "p1")
179 .containsExactly(3L, 22L)
180 );
181 }
182 }
183
184 @Test
185 void testLimitOnlyAfterOrderBy() {
186 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
187 SelectStatementProvider selectStatement = select(animalData.allColumns())
188 .from(animalData)
189 .orderBy(id)
190 .fetchFirst(3).rowsOnly()
191 .build()
192 .render(RenderingStrategies.MYBATIS3);
193
194 AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
195 List<AnimalData> records = mapper.selectMany(selectStatement);
196
197 assertAll(
198 () -> assertThat(records).hasSize(3),
199 () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1),
200 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id fetch first #{parameters.p1} rows only"),
201 () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L)
202 );
203 }
204 }
205 }