JavaTypeResolverDefaultImpl.java
/*
* Copyright 2006-2026 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.generator.internal.types;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
import java.math.BigDecimal;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.jspecify.annotations.Nullable;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.PropertyRegistry;
public class JavaTypeResolverDefaultImpl implements JavaTypeResolver {
protected @Nullable List<String> warnings;
protected final Properties properties;
protected @Nullable Context context;
protected boolean forceBigDecimals;
protected final Map<Integer, JdbcTypeInformation> typeMap;
public JavaTypeResolverDefaultImpl() {
super();
properties = new Properties();
typeMap = new HashMap<>();
typeMap.put(Types.ARRAY, new JdbcTypeInformation("ARRAY", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT", //$NON-NLS-1$
new FullyQualifiedJavaType(Long.class.getName())));
typeMap.put(Types.BINARY, new JdbcTypeInformation("BINARY", //$NON-NLS-1$
new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
typeMap.put(Types.BIT, new JdbcTypeInformation("BIT", //$NON-NLS-1$
new FullyQualifiedJavaType(Boolean.class.getName())));
typeMap.put(Types.BLOB, new JdbcTypeInformation("BLOB", //$NON-NLS-1$
new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
typeMap.put(Types.BOOLEAN, new JdbcTypeInformation("BOOLEAN", //$NON-NLS-1$
new FullyQualifiedJavaType(Boolean.class.getName())));
typeMap.put(Types.CHAR, new JdbcTypeInformation("CHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.CLOB, new JdbcTypeInformation("CLOB", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.DATALINK, new JdbcTypeInformation("DATALINK", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.DATE, new JdbcTypeInformation("DATE", //$NON-NLS-1$
new FullyQualifiedJavaType(LocalDate.class.getName())));
typeMap.put(Types.DECIMAL, new JdbcTypeInformation("DECIMAL", //$NON-NLS-1$
new FullyQualifiedJavaType(BigDecimal.class.getName())));
typeMap.put(Types.DISTINCT, new JdbcTypeInformation("DISTINCT", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.DOUBLE, new JdbcTypeInformation("DOUBLE", //$NON-NLS-1$
new FullyQualifiedJavaType(Double.class.getName())));
typeMap.put(Types.FLOAT, new JdbcTypeInformation("FLOAT", //$NON-NLS-1$
new FullyQualifiedJavaType(Double.class.getName())));
typeMap.put(Types.INTEGER, new JdbcTypeInformation("INTEGER", //$NON-NLS-1$
new FullyQualifiedJavaType(Integer.class.getName())));
typeMap.put(Types.JAVA_OBJECT, new JdbcTypeInformation("JAVA_OBJECT", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.LONGNVARCHAR, new JdbcTypeInformation("LONGNVARCHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.LONGVARBINARY, new JdbcTypeInformation("LONGVARBINARY", //$NON-NLS-1$
new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
typeMap.put(Types.LONGVARCHAR, new JdbcTypeInformation("LONGVARCHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.NCHAR, new JdbcTypeInformation("NCHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.NCLOB, new JdbcTypeInformation("NCLOB", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.NVARCHAR, new JdbcTypeInformation("NVARCHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.NULL, new JdbcTypeInformation("NULL", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.NUMERIC, new JdbcTypeInformation("NUMERIC", //$NON-NLS-1$
new FullyQualifiedJavaType(BigDecimal.class.getName())));
typeMap.put(Types.OTHER, new JdbcTypeInformation("OTHER", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.REAL, new JdbcTypeInformation("REAL", //$NON-NLS-1$
new FullyQualifiedJavaType(Float.class.getName())));
typeMap.put(Types.REF, new JdbcTypeInformation("REF", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT", //$NON-NLS-1$
new FullyQualifiedJavaType(Short.class.getName())));
typeMap.put(Types.SQLXML, new JdbcTypeInformation("SQLXML", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
typeMap.put(Types.STRUCT, new JdbcTypeInformation("STRUCT", //$NON-NLS-1$
new FullyQualifiedJavaType(Object.class.getName())));
typeMap.put(Types.TIME, new JdbcTypeInformation("TIME", //$NON-NLS-1$
new FullyQualifiedJavaType(LocalTime.class.getName())));
typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP", //$NON-NLS-1$
new FullyQualifiedJavaType(LocalDateTime.class.getName())));
typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", //$NON-NLS-1$
new FullyQualifiedJavaType(Byte.class.getName())));
typeMap.put(Types.VARBINARY, new JdbcTypeInformation("VARBINARY", //$NON-NLS-1$
new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
typeMap.put(Types.VARCHAR, new JdbcTypeInformation("VARCHAR", //$NON-NLS-1$
new FullyQualifiedJavaType(String.class.getName())));
// JDK 1.8 types
typeMap.put(Types.TIME_WITH_TIMEZONE, new JdbcTypeInformation("TIME_WITH_TIMEZONE", //$NON-NLS-1$
new FullyQualifiedJavaType(OffsetTime.class.getName())));
typeMap.put(Types.TIMESTAMP_WITH_TIMEZONE, new JdbcTypeInformation("TIMESTAMP_WITH_TIMEZONE", //$NON-NLS-1$
new FullyQualifiedJavaType(OffsetDateTime.class.getName())));
}
@Override
public void addConfigurationProperties(Properties properties) {
this.properties.putAll(properties);
forceBigDecimals = isTrue(properties.getProperty(PropertyRegistry.TYPE_RESOLVER_FORCE_BIG_DECIMALS));
}
@Override
public Optional<JdbcTypeInformation> calculateTypeInformation(IntrospectedColumn introspectedColumn) {
JdbcTypeInformation jdbcTypeInformation = typeMap.get(introspectedColumn.getJdbcType());
if (jdbcTypeInformation != null) {
return Optional.of(overrideDefault(introspectedColumn, jdbcTypeInformation));
} else {
return Optional.empty();
}
}
protected JdbcTypeInformation overrideDefault(IntrospectedColumn column,
JdbcTypeInformation defaultTypeInformation) {
return switch (column.getJdbcType()) {
case Types.BIT -> overrideBitType(column, defaultTypeInformation);
case Types.DECIMAL, Types.NUMERIC -> overrideBigDecimalType(column, defaultTypeInformation);
default -> defaultTypeInformation;
};
}
protected JdbcTypeInformation overrideBitType(IntrospectedColumn column,
JdbcTypeInformation defaultTypeInformation) {
if (column.getLength() > 1) {
return defaultTypeInformation.withJavaType(new FullyQualifiedJavaType("byte[]")); //$NON-NLS-1$
} else {
return defaultTypeInformation;
}
}
protected JdbcTypeInformation overrideBigDecimalType(IntrospectedColumn column,
JdbcTypeInformation defaultTypeInformation) {
if (column.getScale() > 0 || column.getLength() > 18 || forceBigDecimals) {
return defaultTypeInformation;
} else if (column.getLength() > 9) {
return defaultTypeInformation.withJavaType(new FullyQualifiedJavaType(Long.class.getName()));
} else if (column.getLength() > 4) {
return defaultTypeInformation.withJavaType(new FullyQualifiedJavaType(Integer.class.getName()));
} else {
return defaultTypeInformation.withJavaType(new FullyQualifiedJavaType(Short.class.getName()));
}
}
@Override
public void setWarnings(List<String> warnings) {
this.warnings = warnings;
}
@Override
public void setContext(Context context) {
this.context = context;
}
}