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.typehandler;
17  
18  import static org.junit.jupiter.api.Assertions.assertEquals;
19  import static org.junit.jupiter.api.Assertions.assertNotNull;
20  
21  import java.io.Reader;
22  
23  import org.apache.ibatis.BaseDataTest;
24  import org.apache.ibatis.builder.BuilderException;
25  import org.apache.ibatis.io.Resources;
26  import org.apache.ibatis.session.SqlSession;
27  import org.apache.ibatis.session.SqlSessionFactory;
28  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
29  import org.apache.ibatis.submitted.typehandler.Product.ConstantProductIdTypeHandler;
30  import org.apache.ibatis.submitted.typehandler.Product.ProductId;
31  import org.apache.ibatis.submitted.typehandler.Product.ProductIdTypeHandler;
32  import org.apache.ibatis.type.JdbcType;
33  import org.junit.jupiter.api.Assertions;
34  import org.junit.jupiter.api.BeforeEach;
35  import org.junit.jupiter.api.Test;
36  
37  class TypeHandlerTest {
38  
39    private SqlSessionFactory sqlSessionFactory;
40  
41    @BeforeEach
42    void setUp() throws Exception {
43      // create a SqlSessionFactory
44      try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/typehandler/mybatis-config.xml")) {
45        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
46        sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(StringTrimmingTypeHandler.class);
47      }
48  
49      // populate in-memory database
50      BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
51          "org/apache/ibatis/submitted/typehandler/CreateDB.sql");
52    }
53  
54    // Some tests need to register additional type handler
55    // before adding mapper.
56    private void addMapper() {
57      sqlSessionFactory.getConfiguration().addMapper(Mapper.class);
58    }
59  
60    @Test
61    void shouldGetAUser() {
62      addMapper();
63      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
64        Mapper mapper = sqlSession.getMapper(Mapper.class);
65        User user = mapper.getUser(1);
66        assertEquals("User1", user.getName());
67        assertEquals("Carmel", user.getCity());
68        assertEquals("IN", user.getState());
69      }
70    }
71  
72    @Test
73    void shouldApplyTypeHandlerOnGeneratedKey() {
74      addMapper();
75      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
76        Mapper mapper = sqlSession.getMapper(Mapper.class);
77        Product product = new Product();
78        product.setName("new product");
79        mapper.insertProduct(product);
80        assertNotNull(product.getId());
81        assertNotNull(product.getId().getValue());
82      }
83    }
84  
85    @Test
86    void shouldApplyTypeHandlerWithJdbcTypeSpecified() {
87      addMapper();
88      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
89        Mapper mapper = sqlSession.getMapper(Mapper.class);
90        Product product = mapper.getProductByName("iPad");
91        assertEquals(Integer.valueOf(2), product.getId().getValue());
92      }
93    }
94  
95    @Test
96    void shouldApplyTypeHandlerUsingConstructor() {
97      addMapper();
98      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
99        Mapper mapper = sqlSession.getMapper(Mapper.class);
100       Product product = mapper.getProductByName("iPad");
101       assertEquals(Integer.valueOf(2), product.getId().getValue());
102     }
103   }
104 
105   @Test
106   void shouldApplyTypeHandlerOnReturnTypeWithJdbcTypeSpecified() {
107     addMapper();
108     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
109       Mapper mapper = sqlSession.getMapper(Mapper.class);
110       ProductId productId = mapper.getProductIdByName("iPad");
111       assertEquals(Integer.valueOf(2), productId.getValue());
112     }
113   }
114 
115   @Test
116   void shouldPickSoleTypeHandlerOnXmlResultMap() {
117     addMapper();
118     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
119       Mapper mapper = sqlSession.getMapper(Mapper.class);
120       Product product = mapper.getProductByNameXml("iPad");
121       assertEquals(Integer.valueOf(2), product.getId().getValue());
122     }
123   }
124 
125   @Test
126   void shouldPickSameTypeHandlerMappedToDifferentJdbcTypes() {
127     sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(ProductId.class, JdbcType.BIGINT,
128         ProductIdTypeHandler.class);
129     addMapper();
130     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
131       Mapper mapper = sqlSession.getMapper(Mapper.class);
132       Product product = mapper.getProductByNameXml("iPad");
133       assertEquals(Integer.valueOf(2), product.getId().getValue());
134     }
135   }
136 
137   @Test
138   void shouldFailIfMultipleHandlerMappedToAType() {
139     sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(ProductId.class, JdbcType.BIGINT,
140         ConstantProductIdTypeHandler.class);
141     // multiple type handlers are mapped to ProductId and
142     // none of them are mapped to null jdbcType.
143     Assertions.assertThrows(BuilderException.class, this::addMapper);
144   }
145 
146   @Test
147   void shouldPickHandlerForNull() {
148     sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(ProductId.class, null,
149         ConstantProductIdTypeHandler.class);
150     // multiple type handlers are mapped to ProductId and
151     // one of them are mapped to null jdbcType.
152     addMapper();
153     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
154       Mapper mapper = sqlSession.getMapper(Mapper.class);
155       Product product = mapper.getProductByNameXml("iPad");
156       assertEquals(Integer.valueOf(999), product.getId().getValue());
157     }
158   }
159 }