1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.generator.internal.types;
17
18 import java.math.BigDecimal;
19 import java.sql.Types;
20 import java.util.Date;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Properties;
25
26 import org.mybatis.generator.api.IntrospectedColumn;
27 import org.mybatis.generator.api.JavaTypeResolver;
28 import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
29 import org.mybatis.generator.config.Context;
30 import org.mybatis.generator.config.PropertyRegistry;
31 import org.mybatis.generator.internal.util.StringUtility;
32
33 public class JavaTypeResolverDefaultImpl implements JavaTypeResolver {
34
35 protected List<String> warnings;
36
37 protected final Properties properties;
38
39 protected Context context;
40
41 protected boolean forceBigDecimals;
42 protected boolean useJSR310Types;
43
44 protected final Map<Integer, JdbcTypeInformation> typeMap;
45
46 public JavaTypeResolverDefaultImpl() {
47 super();
48 properties = new Properties();
49 typeMap = new HashMap<>();
50
51 typeMap.put(Types.ARRAY, new JdbcTypeInformation("ARRAY",
52 new FullyQualifiedJavaType(Object.class.getName())));
53 typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT",
54 new FullyQualifiedJavaType(Long.class.getName())));
55 typeMap.put(Types.BINARY, new JdbcTypeInformation("BINARY",
56 new FullyQualifiedJavaType("byte[]")));
57 typeMap.put(Types.BIT, new JdbcTypeInformation("BIT",
58 new FullyQualifiedJavaType(Boolean.class.getName())));
59 typeMap.put(Types.BLOB, new JdbcTypeInformation("BLOB",
60 new FullyQualifiedJavaType("byte[]")));
61 typeMap.put(Types.BOOLEAN, new JdbcTypeInformation("BOOLEAN",
62 new FullyQualifiedJavaType(Boolean.class.getName())));
63 typeMap.put(Types.CHAR, new JdbcTypeInformation("CHAR",
64 new FullyQualifiedJavaType(String.class.getName())));
65 typeMap.put(Types.CLOB, new JdbcTypeInformation("CLOB",
66 new FullyQualifiedJavaType(String.class.getName())));
67 typeMap.put(Types.DATALINK, new JdbcTypeInformation("DATALINK",
68 new FullyQualifiedJavaType(Object.class.getName())));
69 typeMap.put(Types.DATE, new JdbcTypeInformation("DATE",
70 new FullyQualifiedJavaType(Date.class.getName())));
71 typeMap.put(Types.DECIMAL, new JdbcTypeInformation("DECIMAL",
72 new FullyQualifiedJavaType(BigDecimal.class.getName())));
73 typeMap.put(Types.DISTINCT, new JdbcTypeInformation("DISTINCT",
74 new FullyQualifiedJavaType(Object.class.getName())));
75 typeMap.put(Types.DOUBLE, new JdbcTypeInformation("DOUBLE",
76 new FullyQualifiedJavaType(Double.class.getName())));
77 typeMap.put(Types.FLOAT, new JdbcTypeInformation("FLOAT",
78 new FullyQualifiedJavaType(Double.class.getName())));
79 typeMap.put(Types.INTEGER, new JdbcTypeInformation("INTEGER",
80 new FullyQualifiedJavaType(Integer.class.getName())));
81 typeMap.put(Types.JAVA_OBJECT, new JdbcTypeInformation("JAVA_OBJECT",
82 new FullyQualifiedJavaType(Object.class.getName())));
83 typeMap.put(Types.LONGNVARCHAR, new JdbcTypeInformation("LONGNVARCHAR",
84 new FullyQualifiedJavaType(String.class.getName())));
85 typeMap.put(Types.LONGVARBINARY, new JdbcTypeInformation(
86 "LONGVARBINARY",
87 new FullyQualifiedJavaType("byte[]")));
88 typeMap.put(Types.LONGVARCHAR, new JdbcTypeInformation("LONGVARCHAR",
89 new FullyQualifiedJavaType(String.class.getName())));
90 typeMap.put(Types.NCHAR, new JdbcTypeInformation("NCHAR",
91 new FullyQualifiedJavaType(String.class.getName())));
92 typeMap.put(Types.NCLOB, new JdbcTypeInformation("NCLOB",
93 new FullyQualifiedJavaType(String.class.getName())));
94 typeMap.put(Types.NVARCHAR, new JdbcTypeInformation("NVARCHAR",
95 new FullyQualifiedJavaType(String.class.getName())));
96 typeMap.put(Types.NULL, new JdbcTypeInformation("NULL",
97 new FullyQualifiedJavaType(Object.class.getName())));
98 typeMap.put(Types.NUMERIC, new JdbcTypeInformation("NUMERIC",
99 new FullyQualifiedJavaType(BigDecimal.class.getName())));
100 typeMap.put(Types.OTHER, new JdbcTypeInformation("OTHER",
101 new FullyQualifiedJavaType(Object.class.getName())));
102 typeMap.put(Types.REAL, new JdbcTypeInformation("REAL",
103 new FullyQualifiedJavaType(Float.class.getName())));
104 typeMap.put(Types.REF, new JdbcTypeInformation("REF",
105 new FullyQualifiedJavaType(Object.class.getName())));
106 typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT",
107 new FullyQualifiedJavaType(Short.class.getName())));
108 typeMap.put(Types.STRUCT, new JdbcTypeInformation("STRUCT",
109 new FullyQualifiedJavaType(Object.class.getName())));
110 typeMap.put(Types.TIME, new JdbcTypeInformation("TIME",
111 new FullyQualifiedJavaType(Date.class.getName())));
112 typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP",
113 new FullyQualifiedJavaType(Date.class.getName())));
114 typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT",
115 new FullyQualifiedJavaType(Byte.class.getName())));
116 typeMap.put(Types.VARBINARY, new JdbcTypeInformation("VARBINARY",
117 new FullyQualifiedJavaType("byte[]")));
118 typeMap.put(Types.VARCHAR, new JdbcTypeInformation("VARCHAR",
119 new FullyQualifiedJavaType(String.class.getName())));
120
121 typeMap.put(Types.TIME_WITH_TIMEZONE, new JdbcTypeInformation("TIME_WITH_TIMEZONE",
122 new FullyQualifiedJavaType("java.time.OffsetTime")));
123 typeMap.put(Types.TIMESTAMP_WITH_TIMEZONE, new JdbcTypeInformation("TIMESTAMP_WITH_TIMEZONE",
124 new FullyQualifiedJavaType("java.time.OffsetDateTime")));
125 }
126
127 @Override
128 public void addConfigurationProperties(Properties properties) {
129 this.properties.putAll(properties);
130 forceBigDecimals = StringUtility
131 .isTrue(properties
132 .getProperty(PropertyRegistry.TYPE_RESOLVER_FORCE_BIG_DECIMALS));
133 useJSR310Types = StringUtility
134 .isTrue(properties
135 .getProperty(PropertyRegistry.TYPE_RESOLVER_USE_JSR310_TYPES));
136 }
137
138 @Override
139 public FullyQualifiedJavaType calculateJavaType(
140 IntrospectedColumn introspectedColumn) {
141 FullyQualifiedJavaType answer = null;
142 JdbcTypeInformation jdbcTypeInformation = typeMap
143 .get(introspectedColumn.getJdbcType());
144
145 if (jdbcTypeInformation != null) {
146 answer = jdbcTypeInformation.getFullyQualifiedJavaType();
147 answer = overrideDefaultType(introspectedColumn, answer);
148 }
149
150 return answer;
151 }
152
153 protected FullyQualifiedJavaType overrideDefaultType(IntrospectedColumn column,
154 FullyQualifiedJavaType defaultType) {
155 FullyQualifiedJavaType answer = defaultType;
156
157 switch (column.getJdbcType()) {
158 case Types.BIT:
159 answer = calculateBitReplacement(column, defaultType);
160 break;
161 case Types.DATE:
162 answer = calculateDateType(column, defaultType);
163 break;
164 case Types.DECIMAL:
165 case Types.NUMERIC:
166 answer = calculateBigDecimalReplacement(column, defaultType);
167 break;
168 case Types.TIME:
169 answer = calculateTimeType(column, defaultType);
170 break;
171 case Types.TIMESTAMP:
172 answer = calculateTimestampType(column, defaultType);
173 break;
174 default:
175 break;
176 }
177
178 return answer;
179 }
180
181 protected FullyQualifiedJavaType calculateDateType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
182 FullyQualifiedJavaType answer;
183
184 if (useJSR310Types) {
185 answer = new FullyQualifiedJavaType("java.time.LocalDate");
186 } else {
187 answer = defaultType;
188 }
189
190 return answer;
191 }
192
193 protected FullyQualifiedJavaType calculateTimeType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
194 FullyQualifiedJavaType answer;
195
196 if (useJSR310Types) {
197 answer = new FullyQualifiedJavaType("java.time.LocalTime");
198 } else {
199 answer = defaultType;
200 }
201
202 return answer;
203 }
204
205 protected FullyQualifiedJavaType calculateTimestampType(IntrospectedColumn column,
206 FullyQualifiedJavaType defaultType) {
207 FullyQualifiedJavaType answer;
208
209 if (useJSR310Types) {
210 answer = new FullyQualifiedJavaType("java.time.LocalDateTime");
211 } else {
212 answer = defaultType;
213 }
214
215 return answer;
216 }
217
218 protected FullyQualifiedJavaType calculateBitReplacement(IntrospectedColumn column,
219 FullyQualifiedJavaType defaultType) {
220 FullyQualifiedJavaType answer;
221
222 if (column.getLength() > 1) {
223 answer = new FullyQualifiedJavaType("byte[]");
224 } else {
225 answer = defaultType;
226 }
227
228 return answer;
229 }
230
231 protected FullyQualifiedJavaType calculateBigDecimalReplacement(IntrospectedColumn column,
232 FullyQualifiedJavaType defaultType) {
233 FullyQualifiedJavaType answer;
234
235 if (column.getScale() > 0 || column.getLength() > 18 || forceBigDecimals) {
236 answer = defaultType;
237 } else if (column.getLength() > 9) {
238 answer = new FullyQualifiedJavaType(Long.class.getName());
239 } else if (column.getLength() > 4) {
240 answer = new FullyQualifiedJavaType(Integer.class.getName());
241 } else {
242 answer = new FullyQualifiedJavaType(Short.class.getName());
243 }
244
245 return answer;
246 }
247
248 @Override
249 public String calculateJdbcTypeName(IntrospectedColumn introspectedColumn) {
250 String answer = null;
251 JdbcTypeInformation jdbcTypeInformation = typeMap
252 .get(introspectedColumn.getJdbcType());
253
254 if (jdbcTypeInformation != null) {
255 answer = jdbcTypeInformation.getJdbcTypeName();
256 }
257
258 return answer;
259 }
260
261 @Override
262 public void setWarnings(List<String> warnings) {
263 this.warnings = warnings;
264 }
265
266 @Override
267 public void setContext(Context context) {
268 this.context = context;
269 }
270
271 public static class JdbcTypeInformation {
272 private final String jdbcTypeName;
273
274 private final FullyQualifiedJavaType fullyQualifiedJavaType;
275
276 public JdbcTypeInformation(String jdbcTypeName,
277 FullyQualifiedJavaType fullyQualifiedJavaType) {
278 this.jdbcTypeName = jdbcTypeName;
279 this.fullyQualifiedJavaType = fullyQualifiedJavaType;
280 }
281
282 public String getJdbcTypeName() {
283 return jdbcTypeName;
284 }
285
286 public FullyQualifiedJavaType getFullyQualifiedJavaType() {
287 return fullyQualifiedJavaType;
288 }
289 }
290 }