View Javadoc
1   /*
2    *    Copyright 2016-2026 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 examples.type_conversion;
17  
18  import static examples.type_conversion.MyFilesDynamicSqlSupport.*;
19  import static examples.type_conversion.ToBase64.toBase64;
20  import static org.assertj.core.api.Assertions.assertThat;
21  import static org.assertj.core.api.Assertions.entry;
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.Base64;
29  import java.util.Map;
30  import java.util.Random;
31  
32  import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
33  import org.apache.ibatis.jdbc.ScriptRunner;
34  import org.apache.ibatis.mapping.Environment;
35  import org.apache.ibatis.session.Configuration;
36  import org.apache.ibatis.session.SqlSession;
37  import org.apache.ibatis.session.SqlSessionFactory;
38  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
39  import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
40  import org.junit.jupiter.api.BeforeEach;
41  import org.junit.jupiter.api.Test;
42  import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider;
43  import org.mybatis.dynamic.sql.render.RenderingStrategies;
44  import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
45  
46  class TypeConversionTest {
47  
48      private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
49      private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
50  
51      private SqlSessionFactory sqlSessionFactory;
52  
53      @BeforeEach
54      void setup() throws Exception {
55          Class.forName(JDBC_DRIVER);
56          try (InputStream is = getClass().getResourceAsStream("/examples/type_conversion/CreateDB.sql")) {
57              assert is != null;
58              try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "");
59                   InputStreamReader isr = new InputStreamReader(is)) {
60                  ScriptRunner sr = new ScriptRunner(connection);
61                  sr.setLogWriter(null);
62                  sr.runScript(isr);
63              }
64          }
65  
66          UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
67          Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
68          Configuration config = new Configuration(environment);
69          config.addMapper(MyFilesMapper.class);
70          sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
71      }
72  
73      @Test
74      void testFunctionInSelect() {
75          try (SqlSession session = sqlSessionFactory.openSession()) {
76              MyFilesMapper mapper = session.getMapper(MyFilesMapper.class);
77  
78              Random random = new Random();
79              byte[] randomBlob = new byte[1024];
80              random.nextBytes(randomBlob);
81  
82              GeneralInsertStatementProvider insertStatement = insertInto(myfiles)
83                      .set(fileId).toValue(1)
84                      .set(fileContents).toValue(randomBlob)
85                      .build()
86                      .render(RenderingStrategies.MYBATIS3);
87  
88              int rows = mapper.generalInsert(insertStatement);
89              assertThat(rows).isEqualTo(1);
90  
91              SelectStatementProvider selectStatement = select(fileId, fileContents)
92                      .from(myfiles)
93                      .where(fileId, isEqualTo(1))
94                      .build()
95                      .render(RenderingStrategies.MYBATIS3);
96  
97              Map<String, Object> row = mapper.selectOneMappedRow(selectStatement);
98              assertThat(row).containsOnly(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
99  
100             selectStatement = select(fileId, toBase64(fileContents).as("checksum"))
101                     .from(myfiles)
102                     .where(fileId, isEqualTo(1))
103                     .build()
104                     .render(RenderingStrategies.MYBATIS3);
105 
106             String expected = "select file_id, TO_BASE64(file_contents) as checksum from MyFiles "
107                     + "where file_id = #{parameters.p1,jdbcType=INTEGER}";
108             assertThat(selectStatement.getSelectStatement()).isEqualTo(expected);
109 
110             row = mapper.selectOneMappedRow(selectStatement);
111 
112             String base64 = Base64.getEncoder().encodeToString(randomBlob);
113             assertThat(row).contains(entry("FILE_ID", 1), entry("CHECKSUM", base64));
114         }
115     }
116 
117     @Test
118     void testFunctionInWhere() {
119         try (SqlSession session = sqlSessionFactory.openSession()) {
120             MyFilesMapper mapper = session.getMapper(MyFilesMapper.class);
121 
122             Random random = new Random();
123             byte[] randomBlob = new byte[1024];
124             random.nextBytes(randomBlob);
125 
126             GeneralInsertStatementProvider insertStatement = insertInto(myfiles)
127                     .set(fileId).toValue(1)
128                     .set(fileContents).toValue(randomBlob)
129                     .build()
130                     .render(RenderingStrategies.MYBATIS3);
131 
132             int rows = mapper.generalInsert(insertStatement);
133             assertThat(rows).isEqualTo(1);
134 
135             SelectStatementProvider selectStatement = select(fileId, fileContents)
136                     .from(myfiles)
137                     .where(fileId, isEqualTo(1))
138                     .build()
139                     .render(RenderingStrategies.MYBATIS3);
140 
141             Map<String, Object> row = mapper.selectOneMappedRow(selectStatement);
142             assertThat(row).contains(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
143 
144             String base64 = Base64.getEncoder().encodeToString(randomBlob);
145             selectStatement = select(fileId, fileContents)
146                     .from(myfiles)
147                     .where(toBase64(fileContents), isEqualTo(base64))
148                     .build()
149                     .render(RenderingStrategies.MYBATIS3);
150 
151             String expected = "select file_id, file_contents from MyFiles "
152                     + "where TO_BASE64(file_contents) = #{parameters.p1,jdbcType=VARCHAR}";
153             assertThat(selectStatement.getSelectStatement()).isEqualTo(expected);
154 
155             row = mapper.selectOneMappedRow(selectStatement);
156 
157             assertThat(row).contains(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
158         }
159     }
160 }