View Javadoc
1   /*
2    *    Copyright 2009-2021 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    *       http://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.type;
17  
18  import static org.assertj.core.api.Assertions.assertThat;
19  import static org.mockito.Mockito.verify;
20  import static org.mockito.Mockito.when;
21  
22  import java.io.*;
23  import java.sql.Blob;
24  
25  import javax.sql.DataSource;
26  
27  import org.apache.ibatis.BaseDataTest;
28  import org.apache.ibatis.annotations.Insert;
29  import org.apache.ibatis.annotations.Select;
30  import org.apache.ibatis.mapping.Environment;
31  import org.apache.ibatis.session.Configuration;
32  import org.apache.ibatis.session.SqlSession;
33  import org.apache.ibatis.session.SqlSessionFactory;
34  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
35  import org.apache.ibatis.transaction.TransactionFactory;
36  import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
37  import org.junit.jupiter.api.BeforeAll;
38  import org.junit.jupiter.api.Test;
39  import org.mockito.Mock;
40  
41  /**
42   * Tests for {@link BlobInputStreamTypeHandler}.
43   *
44   * @since 3.4.0
45   * @author Kazuki Shimizu
46   */
47  class BlobInputStreamTypeHandlerTest extends BaseTypeHandlerTest {
48  
49    private static final TypeHandler<InputStream> TYPE_HANDLER = new BlobInputStreamTypeHandler();
50  
51    private static SqlSessionFactory sqlSessionFactory;
52  
53    @Mock
54    protected Blob blob;
55  
56    @BeforeAll
57    static void setupSqlSessionFactory() throws Exception {
58      DataSource dataSource = BaseDataTest.createUnpooledDataSource("org/apache/ibatis/type/jdbc.properties");
59      TransactionFactory transactionFactory = new JdbcTransactionFactory();
60      Environment environment = new Environment("Production", transactionFactory, dataSource);
61      Configuration configuration = new Configuration(environment);
62      configuration.addMapper(Mapper.class);
63      sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
64  
65      BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
66          "org/apache/ibatis/type/BlobInputStreamTypeHandlerTest.sql");
67    }
68  
69    @Override
70    @Test
71    public void shouldSetParameter() throws Exception {
72      InputStream in = new ByteArrayInputStream("Hello".getBytes());
73      TYPE_HANDLER.setParameter(ps, 1, in, null);
74      verify(ps).setBlob(1, in);
75    }
76  
77    @Override
78    @Test
79    public void shouldGetResultFromResultSetByName() throws Exception {
80      InputStream in = new ByteArrayInputStream("Hello".getBytes());
81      when(rs.getBlob("column")).thenReturn(blob);
82      when(blob.getBinaryStream()).thenReturn(in);
83      assertThat(TYPE_HANDLER.getResult(rs, "column")).isEqualTo(in);
84  
85    }
86  
87    @Override
88    @Test
89    public void shouldGetResultNullFromResultSetByName() throws Exception {
90      when(rs.getBlob("column")).thenReturn(null);
91      assertThat(TYPE_HANDLER.getResult(rs, "column")).isNull();
92    }
93  
94    @Override
95    @Test
96    public void shouldGetResultFromResultSetByPosition() throws Exception {
97      InputStream in = new ByteArrayInputStream("Hello".getBytes());
98      when(rs.getBlob(1)).thenReturn(blob);
99      when(blob.getBinaryStream()).thenReturn(in);
100     assertThat(TYPE_HANDLER.getResult(rs, 1)).isEqualTo(in);
101   }
102 
103   @Override
104   @Test
105   public void shouldGetResultNullFromResultSetByPosition() throws Exception {
106     when(rs.getBlob(1)).thenReturn(null);
107     assertThat(TYPE_HANDLER.getResult(rs, 1)).isNull();
108   }
109 
110   @Override
111   @Test
112   public void shouldGetResultFromCallableStatement() throws Exception {
113     InputStream in = new ByteArrayInputStream("Hello".getBytes());
114     when(cs.getBlob(1)).thenReturn(blob);
115     when(blob.getBinaryStream()).thenReturn(in);
116     assertThat(TYPE_HANDLER.getResult(cs, 1)).isEqualTo(in);
117   }
118 
119   @Override
120   @Test
121   public void shouldGetResultNullFromCallableStatement() throws Exception {
122     when(cs.getBlob(1)).thenReturn(null);
123     assertThat(TYPE_HANDLER.getResult(cs, 1)).isNull();
124   }
125 
126   @Test
127   void integrationTest() throws IOException {
128     try (SqlSession session = sqlSessionFactory.openSession()) {
129       Mapper mapper = session.getMapper(Mapper.class);
130       // insert (InputStream -> Blob)
131       {
132         BlobContent blobContent = new BlobContent();
133         blobContent.setId(1);
134         blobContent.setContent(new ByteArrayInputStream("Hello".getBytes()));
135         mapper.insert(blobContent);
136         session.commit();
137       }
138       // select (Blob -> InputStream)
139       {
140         BlobContent blobContent = mapper.findOne(1);
141         assertThat(new BufferedReader(new InputStreamReader(blobContent.getContent())).readLine()).isEqualTo("Hello");
142       }
143     }
144 
145   }
146 
147   interface Mapper {
148     @Select("SELECT ID, CONTENT FROM TEST_BLOB WHERE ID = #{id}")
149     BlobContent findOne(int id);
150 
151     @Insert("INSERT INTO TEST_BLOB (ID, CONTENT) VALUES(#{id}, #{content})")
152     void insert(BlobContent blobContent);
153   }
154 
155   static class BlobContent {
156     private int id;
157     private InputStream content;
158 
159     public int getId() {
160       return id;
161     }
162 
163     public void setId(int id) {
164       this.id = id;
165     }
166 
167     public InputStream getContent() {
168       return content;
169     }
170 
171     public void setContent(InputStream content) {
172       this.content = content;
173     }
174   }
175 
176 }