View Javadoc
1   /*
2    *    Copyright 2016-2025 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          InputStream is = getClass().getResourceAsStream("/examples/type_conversion/CreateDB.sql");
57          assert is != null;
58          try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) {
59              ScriptRunner sr = new ScriptRunner(connection);
60              sr.setLogWriter(null);
61              sr.runScript(new InputStreamReader(is));
62          }
63  
64          UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
65          Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
66          Configuration config = new Configuration(environment);
67          config.addMapper(MyFilesMapper.class);
68          sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
69      }
70  
71      @Test
72      void testFunctionInSelect() {
73          try (SqlSession session = sqlSessionFactory.openSession()) {
74              MyFilesMapper mapper = session.getMapper(MyFilesMapper.class);
75  
76              Random random = new Random();
77              byte[] randomBlob = new byte[1024];
78              random.nextBytes(randomBlob);
79  
80              GeneralInsertStatementProvider insertStatement = insertInto(myfiles)
81                      .set(fileId).toValue(1)
82                      .set(fileContents).toValue(randomBlob)
83                      .build()
84                      .render(RenderingStrategies.MYBATIS3);
85  
86              int rows = mapper.generalInsert(insertStatement);
87              assertThat(rows).isEqualTo(1);
88  
89              SelectStatementProvider selectStatement = select(fileId, fileContents)
90                      .from(myfiles)
91                      .where(fileId, isEqualTo(1))
92                      .build()
93                      .render(RenderingStrategies.MYBATIS3);
94  
95              Map<String, Object> row = mapper.selectOneMappedRow(selectStatement);
96              assertThat(row).containsExactly(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
97  
98              selectStatement = select(fileId, toBase64(fileContents).as("checksum"))
99                      .from(myfiles)
100                     .where(fileId, isEqualTo(1))
101                     .build()
102                     .render(RenderingStrategies.MYBATIS3);
103 
104             String expected = "select file_id, TO_BASE64(file_contents) as checksum from MyFiles "
105                     + "where file_id = #{parameters.p1,jdbcType=INTEGER}";
106             assertThat(selectStatement.getSelectStatement()).isEqualTo(expected);
107 
108             row = mapper.selectOneMappedRow(selectStatement);
109 
110             String base64 = Base64.getEncoder().encodeToString(randomBlob);
111             assertThat(row).contains(entry("FILE_ID", 1), entry("CHECKSUM", base64));
112         }
113     }
114 
115     @Test
116     void testFunctionInWhere() {
117         try (SqlSession session = sqlSessionFactory.openSession()) {
118             MyFilesMapper mapper = session.getMapper(MyFilesMapper.class);
119 
120             Random random = new Random();
121             byte[] randomBlob = new byte[1024];
122             random.nextBytes(randomBlob);
123 
124             GeneralInsertStatementProvider insertStatement = insertInto(myfiles)
125                     .set(fileId).toValue(1)
126                     .set(fileContents).toValue(randomBlob)
127                     .build()
128                     .render(RenderingStrategies.MYBATIS3);
129 
130             int rows = mapper.generalInsert(insertStatement);
131             assertThat(rows).isEqualTo(1);
132 
133             SelectStatementProvider selectStatement = select(fileId, fileContents)
134                     .from(myfiles)
135                     .where(fileId, isEqualTo(1))
136                     .build()
137                     .render(RenderingStrategies.MYBATIS3);
138 
139             Map<String, Object> row = mapper.selectOneMappedRow(selectStatement);
140             assertThat(row).contains(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
141 
142             String base64 = Base64.getEncoder().encodeToString(randomBlob);
143             selectStatement = select(fileId, fileContents)
144                     .from(myfiles)
145                     .where(toBase64(fileContents), isEqualTo(base64))
146                     .build()
147                     .render(RenderingStrategies.MYBATIS3);
148 
149             String expected = "select file_id, file_contents from MyFiles "
150                     + "where TO_BASE64(file_contents) = #{parameters.p1,jdbcType=VARCHAR}";
151             assertThat(selectStatement.getSelectStatement()).isEqualTo(expected);
152 
153             row = mapper.selectOneMappedRow(selectStatement);
154 
155             assertThat(row).contains(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
156         }
157     }
158 }