View Javadoc
1   /*
2    *    Copyright 2009-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.submitted.dynsql;
17  
18  import static org.junit.jupiter.api.Assertions.assertEquals;
19  
20  import java.io.IOException;
21  import java.io.Reader;
22  import java.math.BigDecimal;
23  import java.math.BigInteger;
24  import java.sql.CallableStatement;
25  import java.sql.PreparedStatement;
26  import java.sql.ResultSet;
27  import java.sql.SQLException;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Map;
31  
32  import org.apache.ibatis.BaseDataTest;
33  import org.apache.ibatis.exceptions.PersistenceException;
34  import org.apache.ibatis.io.Resources;
35  import org.apache.ibatis.session.SqlSession;
36  import org.apache.ibatis.session.SqlSessionFactory;
37  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
38  import org.apache.ibatis.type.JdbcType;
39  import org.apache.ibatis.type.TypeHandler;
40  import org.junit.jupiter.api.BeforeAll;
41  import org.junit.jupiter.api.Test;
42  
43  class DynSqlTest {
44  
45    protected static SqlSessionFactory sqlSessionFactory;
46  
47    @BeforeAll
48    static void setUp() throws Exception {
49      try (Reader configReader = Resources.getResourceAsReader("org/apache/ibatis/submitted/dynsql/MapperConfig.xml")) {
50        sqlSessionFactory = new SqlSessionFactoryBuilder().build(configReader);
51      }
52  
53      BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
54          "org/apache/ibatis/submitted/dynsql/CreateDB.sql");
55    }
56  
57    @Test
58    void testSelect() {
59      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
60        List<Integer> ids = new ArrayList<>();
61        ids.add(1);
62        ids.add(3);
63        ids.add(5);
64        Parameter parameter = new Parameter();
65        parameter.setEnabled(true);
66        parameter.setSchema("ibtest");
67        parameter.setIds(ids);
68  
69        List<Map<String, Object>> answer = sqlSession.selectList("org.apache.ibatis.submitted.dynsql.select", parameter);
70  
71        assertEquals(3, answer.size());
72      }
73    }
74  
75    @Test
76    void testSelectSimple() {
77      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
78        List<Integer> ids = new ArrayList<>();
79        ids.add(1);
80        ids.add(3);
81        ids.add(5);
82        Parameter parameter = new Parameter();
83        parameter.setEnabled(true);
84        parameter.setSchema("ibtest");
85        parameter.setIds(ids);
86  
87        List<Map<String, Object>> answer = sqlSession.selectList("org.apache.ibatis.submitted.dynsql.select_simple",
88            parameter);
89  
90        assertEquals(3, answer.size());
91      }
92    }
93  
94    @Test
95    void testSelectLike() {
96      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
97  
98        List<Map<String, Object>> answer = sqlSession.selectList("org.apache.ibatis.submitted.dynsql.selectLike", "Ba");
99  
100       assertEquals(2, answer.size());
101       assertEquals(4, answer.get(0).get("ID"));
102       assertEquals(6, answer.get(1).get("ID"));
103     }
104   }
105 
106   @Test
107   void testNumerics() {
108     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
109       List<NumericRow> answer = sqlSession.selectList("org.apache.ibatis.submitted.dynsql.selectNumerics");
110 
111       assertEquals(1, answer.size());
112 
113       NumericRow row = answer.get(0);
114       assertEquals(1, (int) row.getId());
115       assertEquals(2, (int) row.getTinynumber());
116       assertEquals(3, (int) row.getSmallnumber());
117       assertEquals(4L, (long) row.getLonginteger());
118       assertEquals(new BigInteger("5"), row.getBiginteger());
119       assertEquals(new BigDecimal("6.00"), row.getNumericnumber());
120       assertEquals(new BigDecimal("7.00"), row.getDecimalnumber());
121       assertEquals((Float) 8.0f, row.getRealnumber());
122       assertEquals((Float) 9.0f, row.getFloatnumber());
123       assertEquals((Double) 10.0, row.getDoublenumber());
124     }
125   }
126 
127   @Test
128   void testOgnlStaticMethodCall() {
129     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
130       List<Map<String, Object>> answer = sqlSession
131           .selectList("org.apache.ibatis.submitted.dynsql.ognlStaticMethodCall", "Rock 'n Roll");
132       assertEquals(1, answer.size());
133       assertEquals(7, answer.get(0).get("ID"));
134     }
135   }
136 
137   @Test
138   void testBindNull() {
139     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
140       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
141       String description = mapper.selectDescription(null);
142       assertEquals("Pebbles", description);
143     }
144   }
145 
146   /**
147    * Verify that can specify any variable name for parameter object when parameter is value object that a type handler
148    * exists.
149    * <p>
150    * https://github.com/mybatis/mybatis-3/issues/1486
151    */
152   @Test
153   void testValueObjectWithoutParamAnnotation() {
154     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
155       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
156       List<String> descriptions = mapper.selectDescriptionById(3);
157       assertEquals(1, descriptions.size());
158       assertEquals("Pebbles", descriptions.get(0));
159 
160       assertEquals(7, mapper.selectDescriptionById(null).size());
161     }
162   }
163 
164   /**
165    * Variations for with https://github.com/mybatis/mybatis-3/issues/1486
166    */
167   @Test
168   void testNonValueObjectWithoutParamAnnotation() {
169     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
170       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
171       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
172       conditions.setId(3);
173       List<String> descriptions = mapper.selectDescriptionByConditions(conditions);
174       assertEquals(1, descriptions.size());
175       assertEquals("Pebbles", descriptions.get(0));
176 
177       assertEquals(7, mapper.selectDescriptionByConditions(null).size());
178       assertEquals(7, mapper.selectDescriptionByConditions(new DynSqlMapper.Conditions()).size());
179     }
180     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
181       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
182       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
183       conditions.setId(3);
184       try {
185         mapper.selectDescriptionByConditions2(conditions);
186       } catch (PersistenceException e) {
187         assertEquals(
188             "There is no getter for property named 'conditions' in 'class org.apache.ibatis.submitted.dynsql.DynSqlMapper$Conditions'",
189             e.getCause().getMessage());
190       }
191       assertEquals(7, mapper.selectDescriptionByConditions2(null).size());
192     }
193     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
194       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
195       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
196       conditions.setId(3);
197       try {
198         mapper.selectDescriptionByConditions3(conditions);
199       } catch (PersistenceException e) {
200         assertEquals(
201             "There is no getter for property named 'conditions' in 'class org.apache.ibatis.submitted.dynsql.DynSqlMapper$Conditions'",
202             e.getCause().getMessage());
203       }
204       assertEquals(7, mapper.selectDescriptionByConditions3(null).size());
205     }
206 
207   }
208 
209   /**
210    * Variations for with https://github.com/mybatis/mybatis-3/issues/1486
211    */
212   @Test
213   void testCustomValueObjectWithoutParamAnnotation() throws IOException {
214     SqlSessionFactory sqlSessionFactory;
215     try (Reader configReader = Resources.getResourceAsReader("org/apache/ibatis/submitted/dynsql/MapperConfig.xml")) {
216       sqlSessionFactory = new SqlSessionFactoryBuilder().build(configReader);
217       // register type handler for the user defined class (= value object)
218       sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(DynSqlMapper.Conditions.class,
219           new TypeHandler<DynSqlMapper.Conditions>() {
220             @Override
221             public void setParameter(PreparedStatement ps, int i, DynSqlMapper.Conditions parameter, JdbcType jdbcType)
222                 throws SQLException {
223               if (parameter.getId() != null) {
224                 ps.setInt(i, parameter.getId());
225               } else {
226                 ps.setNull(i, JdbcType.INTEGER.TYPE_CODE);
227               }
228             }
229 
230             @Override
231             public DynSqlMapper.Conditions getResult(ResultSet rs, String columnName) throws SQLException {
232               return null;
233             }
234 
235             @Override
236             public DynSqlMapper.Conditions getResult(ResultSet rs, int columnIndex) throws SQLException {
237               return null;
238             }
239 
240             @Override
241             public DynSqlMapper.Conditions getResult(CallableStatement cs, int columnIndex) throws SQLException {
242               return null;
243             }
244           });
245     }
246     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
247       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
248       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
249       conditions.setId(3);
250       List<String> descriptions = mapper.selectDescriptionByConditions(conditions);
251       assertEquals(1, descriptions.size());
252       assertEquals("Pebbles", descriptions.get(0));
253 
254       assertEquals(7, mapper.selectDescriptionByConditions(null).size());
255       assertEquals(7, mapper.selectDescriptionByConditions(new DynSqlMapper.Conditions()).size());
256     }
257     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
258       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
259       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
260       conditions.setId(3);
261       List<String> descriptions = mapper.selectDescriptionByConditions2(conditions);
262       assertEquals(1, descriptions.size());
263       assertEquals("Pebbles", descriptions.get(0));
264 
265       assertEquals(7, mapper.selectDescriptionByConditions2(null).size());
266       assertEquals(0, mapper.selectDescriptionByConditions2(new DynSqlMapper.Conditions()).size());
267     }
268     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
269       DynSqlMapper mapper = sqlSession.getMapper(DynSqlMapper.class);
270       DynSqlMapper.Conditions conditions = new DynSqlMapper.Conditions();
271       conditions.setId(3);
272       List<String> descriptions = mapper.selectDescriptionByConditions3(conditions);
273       assertEquals(1, descriptions.size());
274       assertEquals("Pebbles", descriptions.get(0));
275 
276       assertEquals(7, mapper.selectDescriptionByConditions3(null).size());
277       assertEquals(7, mapper.selectDescriptionByConditions3(new DynSqlMapper.Conditions()).size());
278     }
279   }
280 
281 }