gu.sql2java.generator.Column Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql2java-generator Show documentation
Show all versions of sql2java-generator Show documentation
executable jar of sql2java generator
package gu.sql2java.generator;
import java.nio.ByteBuffer;
import java.sql.DatabaseMetaData;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import com.gitee.l0km.com4j.base.VolatileVariable;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import gu.sql2java.excel.annotations.ExcelColumn;
import static com.gitee.l0km.com4j.base.MiscellaneousUtils.elementsOf;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.nullToEmpty;
public class Column implements Cloneable, Comparable,MappedType {
private String catalog;
private String schema;
private String tableName;
private String name;
private SqlComment remarks;
private String defaultValue;
private int size;
private int decDigits;
private int radix;
private int nullable;
private int ordinal;
private short type;
private boolean isPrimaryKey;
private String strCheckingType = "";
private String autoincrement;
private Database db;
private List foreignKeys = new Vector();
private List importedKeys = new Vector();
private String typeName = "";
private volatile String invalidValueAnn;
private volatile Boolean preAlloc;
private static Random rand = new Random();
private static boolean jsonJacksonRawValue;
private static boolean byteBufferAsString;
private static boolean jacksonBeanSupport;
private static String geometrySerialType;
@Override
public String toString() {
return new ToStringBuilder(this)
.append("catalog",catalog)
.append("schema",schema)
.append("tableName",tableName)
.append("name",name)
.append("remarks",remarks)
.append("defaultValue",defaultValue)
.append("size",size)
.append("decDigits",decDigits)
.append("radix",radix)
.append("nullable",nullable)
.append("ordinal",ordinal)
.append("type",type)
.append("isPrimaryKey",isPrimaryKey)
.append("autoincrement",autoincrement)
.append("typeName",typeName)
.toString();
}
@Override
public boolean equals(Object obj) {
if(super.equals(obj))return true;
if(!(obj instanceof Column))return false;
Column other = (Column)obj;
return new EqualsBuilder()
.append(catalog,other.catalog)
.append(schema,other.schema)
.append(tableName,other.tableName)
.append(name,other.name)
.append(remarks,other.remarks)
.append(defaultValue,other.defaultValue)
.append(size,other.size)
.append(decDigits,other.decDigits)
.append(radix,other.radix)
.append(nullable,other.nullable)
.append(ordinal,other.ordinal)
.append(type,other.type)
.append(isPrimaryKey,other.isPrimaryKey)
.append(autoincrement,other.autoincrement)
.append(typeName,other.typeName)
.isEquals();
}
public void setCheckingType(String strValue) {
this.strCheckingType = strValue;
}
public String getCheckingType() {
return this.strCheckingType;
}
public void setDatabase(Database db) {
this.db = db;
}
public void setCatalog(String catalog) {
this.catalog = catalog;
}
public void setSchema(String schema) {
this.schema = schema;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public void setName(String name) {
this.name = null == name ? "" : name.replaceAll("\\W", "");
}
public void setType(short type) {
this.type = type;
}
public void setSize(int size) {
this.size = size;
}
public void setDecimalDigits(int decDigits) {
this.decDigits = decDigits;
}
public void setRadix(int radix) {
this.radix = radix;
}
public void setNullable(int nullable) {
this.nullable = nullable;
}
public void setRemarks(String remarks) {
this.remarks = new SqlComment(remarks);
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public void setOrdinalPosition(int ordinal) {
this.ordinal = ordinal;
}
public void isPrimaryKey(boolean isKey) {
this.isPrimaryKey = isKey;
}
public String getCatalog() {
return this.catalog;
}
public String getSchema() {
return this.schema;
}
public String getTableName() {
return this.tableName;
}
public String getName() {
return this.name;
}
public short getType() {
return this.type;
}
public int getSize() {
return this.size;
}
public int getDecimalDigits() {
return this.decDigits;
}
public int getRadix() {
return this.radix;
}
public int getNullable() {
return this.nullable;
}
public String getNullableAsString() {
return this.getNullable() != 0 ? "nullable" : "null not allowed";
}
public int getOrdinalPosition() {
return this.ordinal;
}
public boolean isPrimaryKey() {
return this.isPrimaryKey;
}
public String getFullName() {
return this.tableName + "." + this.getName();
}
/**
* @since 3.31.0
*/
public String getFullNameNsp() {
return getTable().getBasename(true) + "." + this.getName();
}
public String getConstName() {
return this.getName().toUpperCase();
}
public String getIDConstName() {
return (this.tableName + "_ID_" + this.getName()).toUpperCase();
}
private String associated(String prefix,String suffix) {
return getTable().asConstantVar(nullToEmpty(prefix) + this.getName().toUpperCase()+nullToEmpty(suffix));
}
public String getIDMaskConstName() {
return (this.tableName + "_ID_" + this.getName()).toUpperCase() + "_MASK";
}
public String getNameConstName() {
return (this.tableName + "_COLUMN_" + this.getName()).toUpperCase();
}
/**
* @since 3.31.0
*/
public String getIDAssociated() {
return associated("_ID_",null);
}
/**
* @since 3.31.0
*/
public String getIDAssociated(String suffix) {
return associated("_ID_",suffix);
}
/**
* @since 3.31.0
*/
public String getNameAssociated() {
return associated("_COLUMN_",null);
}
/**
* @see gu.sql2java.generator.SqlComment#getDescName()
*/
public String getDescName(){
return remarks.getDescName();
}
/**
* @see gu.sql2java.generator.SqlComment#getNamesTagMap()
*/
public Map getNamesTagMap() {
return remarks.getNamesTagMap();
}
public String getExcelColumn(){
return remarks.getExcelAnnotation(ExcelColumn.class,
buffer->{buffer.append("sort=").append(ordinal);return 1;});
}
/**
* 字段可见度定义
* 优先从字段注解中获取,如果没有定义则从配置文件中获取,如果还是没有则返回默认值:{@link ColumnVisibility#DEFAULT}
*/
private final VolatileVariable visibility = new VolatileVariable(()->{
try {
return ColumnVisibility.valueOf(remarks.getScopeType());
} catch (Exception e) {
return firstNonNull(getTable().getVisibilityOfColumns().get(name), ColumnVisibility.DEFAULT) ;
}
});
/**
* 返回当前字段可见度
* @since 3.32.0
*/
public ColumnVisibility getVisibility() {
return visibility.get();
}
/**
* 返回当前字段是否被定义为JSON字段
*/
public boolean isJsonField(){
return isString() && remarks.hasJsonTag();
}
/**
* 如果字段注释中定义了字段类型返回{@code true},否则返回{@code false}
* @since 3.21.0
*/
public boolean isDefinedFieldType() {
return !Strings.isNullOrEmpty(remarks.getFieldType());
}
/**
* 如果字段被定义为M_BOOLEAN类型则返回 {@code true},
* 否则返回{@code false}
*/
private boolean isBoolean() {
return M_BOOLEAN == getMappedType();
}
/**
* 返回当前字段是否为空间数据类型(Spatial Data)
* @since 3.18.0
*/
public boolean isGeometry() {
return null != getGeometryType();
}
public boolean isJsonJacksonRawValue(){
return jacksonBeanSupport && jsonJacksonRawValue && isJsonField();
}
public boolean isByteBufferAsString(){
return byteBufferAsString && ByteBuffer.class.equals(getJavaClass());
}
/**
* 如果字段注释中有JSON tag,则解析JSON tag,返回JSON的类型定义(fastjson)
* 如果不是JSON字段则返回{@code null}
* @see SqlComment#getJsonType()
*/
private String getJsonType(){
if(isJsonField()){
return remarks.getJsonType();
}
return null;
}
/**
* 如果字段注释中有ANN tag,则解析ANN tag,返回ANN的注解定义列表
* 如果不是ANN字段则返回空
* @since 3.21.0
*/
public List getAnnotations(){
return remarks.getAnnotations();
}
/**
* 如果字段注释中有JSAN tag,则解析JSAN tag,返回JSAN的注解定义列表
* 如果不是JSAN字段则返回空
* @since 3.32.0
*/
public List getJsonAnnotations(){
return remarks.getJsonAnnotations();
}
/**
* 如果字段为空间数据类型(Spatial Data)则返回对应的JTS Java类否则 返回{@code null}
* @since 3.18.0
*/
public Class> getGeometryType(){
return SPATIAL_TARGET_TYPES.get(this.getTypeName().toUpperCase());
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void tuoe() {
throw new UnsupportedOperationException("Not supported yet: " + this.getTableName() + "." + this.getName() + " "
+ this.getJavaTypeAsTypeName());
}
private void tiae() {
throw new IllegalArgumentException("No primary type associated: " + this.getTableName() + "." + this.getName());
}
public int getMappedType() {
switch (this.getType()) {
case Types.ARRAY : {
return M_ARRAY;
}
case Types.BIGINT : {
return M_LONG;
}
case Types.BINARY : {
return M_BYTES;
}
case Types.BIT : {
return M_BOOLEAN;
}
case Types.BLOB : {
return M_BLOB;
}
case Types.BOOLEAN : {
return M_BOOLEAN;
}
case Types.CHAR : {
return M_STRING;
}
case Types.CLOB : {
return M_CLOB;
}
case Types.DATALINK : {
return M_URL;
}
case Types.DATE : {
if ("java.util.Date".equals(CodeWriter.dateClassName)) {
return M_UTILDATE;
}
if ("java.sql.Date".equals(CodeWriter.dateClassName)) {
return M_SQLDATE;
}
if ("java.util.Calendar".equals(CodeWriter.dateClassName)) {
return M_CALENDAR;
}
this.tuoe();
}
case Types.DECIMAL : {
return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
}
case Types.DISTINCT : {
return M_OBJECT;
}
case Types.DOUBLE : {
return M_DOUBLE;
}
case Types.FLOAT : {
return M_DOUBLE;
}
case Types.INTEGER : {
return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? M_LONG : M_INTEGER;
}
case Types.JAVA_OBJECT : {
return M_OBJECT;
}
case Types.LONGVARBINARY : {
return M_BYTES;
}
case Types.LONGVARCHAR : {
return M_STRING;
}
case Types.NUMERIC : {
return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
}
case Types.OTHER : {
return M_OBJECT;
}
case Types.REAL : {
return M_FLOAT;
}
case Types.REF : {
return M_REF;
}
case Types.SMALLINT : {
return M_SHORT;
}
case Types.STRUCT : {
return M_OBJECT;
}
case Types.TIME : {
if ("java.util.Date".equals(CodeWriter.timeClassName)) {
return M_UTILDATE;
}
if ("java.sql.Time".equals(CodeWriter.timeClassName)) {
return M_TIME;
}
if ("java.util.Calendar".equals(CodeWriter.timeClassName)) {
return M_CALENDAR;
}
this.tuoe();
}
case Types.TIMESTAMP : {
if ("java.util.Date".equals(CodeWriter.timestampClassName)) {
return M_UTILDATE;
}
if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) {
return M_TIMESTAMP;
}
if ("java.util.Calendar".equals(CodeWriter.timestampClassName)) {
return M_CALENDAR;
}
this.tuoe();
}
case Types.TINYINT : {
/** 如果字段注释中有NUM tag,则解析NUM tag,且为Boolean返回 M_BOOLEAN */
if(Boolean.class.equals(remarks.getPrimitiveType())) {
return M_BOOLEAN;
}
return M_BYTE;
}
case Types.VARBINARY : {
return M_BYTES;
}
case Types.VARCHAR : {
return M_STRING;
}
}
this.tuoe();
return -1;
}
public String getQuerySetMethod() {
switch (this.getType()) {
case Types.ARRAY : {
return "setArray";
}
case Types.BIGINT : {
return "setBigDecimal";
}
case Types.BINARY : {
return "setBytes";
}
case Types.BIT : {
return "setBoolean";
}
case Types.BLOB : {
return "setBlob";
}
case Types.BOOLEAN : {
return "setBoolean";
}
case Types.CHAR : {
return "setString";
}
case Types.CLOB : {
return "setClob";
}
case Types.DATALINK : {
return "setURL";
}
case Types.DATE : {
return "setDate";
}
case Types.DECIMAL : {
return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
}
case Types.DISTINCT : {
return "setObject";
}
case Types.DOUBLE : {
return "setDouble";
}
case Types.FLOAT : {
return "setDouble";
}
case Types.INTEGER : {
return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? "setLong" : "setInt";
}
case Types.JAVA_OBJECT : {
return "setObject";
}
case Types.LONGVARBINARY : {
return "setBytes";
}
case Types.LONGVARCHAR : {
return "setString";
}
case Types.NUMERIC : {
return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
}
case Types.OTHER : {
return "setObject";
}
case Types.REAL : {
return "setFloat";
}
case Types.REF : {
return "setRef";
}
case Types.SMALLINT : {
return "setInt";
}
case Types.STRUCT : {
return "setObject";
}
case Types.TIME : {
if ("java.util.Date".equals(CodeWriter.timeClassName)) {
return "setDate";
}
if ("java.sql.Time".equals(CodeWriter.timeClassName)) {
return "setTime";
}
this.tuoe();
}
case Types.TIMESTAMP : {
if ("java.util.Date".equals(CodeWriter.timestampClassName)) {
return "setDate";
}
if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) {
return "setTimestamp";
}
this.tuoe();
}
case Types.TINYINT : {
return "setInt";
}
case Types.VARBINARY : {
return "setBytes";
}
case Types.VARCHAR : {
return "setString";
}
}
this.tuoe();
return "setObject";
}
/**
* @return 返回对应的Java类型
*/
public Class> getJavaClass() {
switch (this.getMappedType()) {
case M_ARRAY : {
return java.sql.Array.class;
}
case M_BIGDECIMAL : {
return java.math.BigDecimal.class;
}
case M_BOOLEAN : {
return Boolean.class;
}
case M_BYTES : {
try {
if(CodeWriter.DEFAULT_BINARY_TYPE.equals(CodeWriter.binaryClassName)){
return byte[].class;
}
return Class.forName(CodeWriter.binaryClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
case M_CLOB : {
// map Clob to java.lang.String
return String.class;
}
case M_SQLDATE : {
return java.sql.Date.class;
}
case M_UTILDATE : {
return java.util.Date.class;
}
case M_DOUBLE : {
return Double.class;
}
case M_FLOAT : {
return Float.class;
}
case M_BLOB : {
try {
return Class.forName(CodeWriter.binaryClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
case M_BYTE : {
return Byte.class;
}
case M_SHORT : {
return Short.class;
}
case M_INTEGER : {
return Integer.class;
}
case M_LONG : {
return Long.class;
}
case M_REF : {
return java.sql.Ref.class;
}
case M_STRING : {
return String.class;
}
case M_TIME : {
return java.sql.Time.class;
}
case M_TIMESTAMP : {
return java.sql.Timestamp.class;
}
case M_URL : {
return java.net.URL.class;
}
case M_OBJECT : {
return firstNonNull(OBJECT_TARGET_TYPES.get(this.getTypeName().toUpperCase()), Object.class);
}
case M_CALENDAR : {
return java.util.Calendar.class;
}
}
this.tiae();
return null;
}
/**
* SQL 空间数据类型对应的JTS Java类
*/
private static final ImmutableMap> SPATIAL_TARGET_TYPES =
ImmutableMap.>builder()
.put("GEOMETRY",com.vividsolutions.jts.geom.Geometry.class)
.put("POINT",com.vividsolutions.jts.geom.Point.class)
.put("LINESTRING",com.vividsolutions.jts.geom.LineString.class)
.put("POLYGON",com.vividsolutions.jts.geom.Polygon.class)
.put("MULTIPOINT",com.vividsolutions.jts.geom.GeometryCollection.class)
.put("MULTILINESTRING",com.vividsolutions.jts.geom.GeometryCollection.class)
.put("MULTIPOLYGON",com.vividsolutions.jts.geom.GeometryCollection.class)
.put("GEOMETRYCOLLECTION",com.vividsolutions.jts.geom.GeometryCollection.class)
.build();
/**
* SQL Object类型对应的Java类型
*/
private static final ImmutableMap> OBJECT_TARGET_TYPES =
ImmutableMap.copyOf(SPATIAL_TARGET_TYPES);
private String getJavaType(Class> type) {
if(type.isArray()){
return getJavaType(type.getComponentType()) + "[]";
}
if(type.isPrimitive()){
return type.getSimpleName();
}
if(type.getPackage().getName().equals("java.lang")){
return type.getSimpleName();
}
return type.getName();
}
/**
* 返回对应的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名
*/
String getJavaType0() {
if(isGeometry() && "STRING".equalsIgnoreCase(geometrySerialType)) {
return "String";
}
return getJavaType(getJavaClass());
}
/**
* 返回对应的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名,
* 如果SQL注释中定义了字段的Java类型则优先返回注释中定义的类型
*/
public String getJavaType() {
if(isDefinedFieldType()) {
return remarks.getFieldType();
}
return getJavaType0();
}
/**
* 返回字段的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名
*/
String getFieldJavaType0() {
if(isDefinedFieldType()) {
return remarks.getFieldType();
}
Class> javaClass = getJavaClass();
if(isByteBufferAsString()){
return "String";
}
if(jacksonBeanSupport && jsonJacksonRawValue){
String jsonType=getJsonType();
if(null != jsonType) {
return jsonType;
}
}
return getJavaType(javaClass);
}
/**
* 返回字段的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名,
* 如果SQL注释中定义了字段的Java类型则优先返回注释中定义的类型
*/
public String getFieldJavaType() {
if(isDefinedFieldType()) {
return remarks.getFieldType();
}
return getFieldJavaType0();
}
/**
* 返回字段 read/write方法的Java类型
* @since 3.21.0
*/
public String getRwType() {
if(isDefinedFieldType()) {
return getJavaType0();
}else {
return getFieldJavaType0();
}
}
public boolean hasPrimaryType() {
return this.getJavaPrimaryType() != null;
}
public String getJavaPrimaryType() throws IllegalArgumentException {
int decimalDigits = this.getDecimalDigits();
if ((this.type == Types.DECIMAL || this.type == Types.NUMERIC) && decimalDigits == 0) {
if (this.size == 1) {
return "boolean";
}
if (this.size < 3) {
return "byte";
}
if (this.size < 5) {
return "short";
}
if (this.size < 10) {
return "int";
}
if (this.size < 19) {
return "long";
}
}
switch (this.getMappedType()) {
case M_BOOLEAN : {
return "boolean";
}
case M_SQLDATE : {
return "long";
}
case M_UTILDATE : {
return "long";
}
case M_DOUBLE : {
return "double";
}
case M_FLOAT : {
return "float";
}
case M_INTEGER : {
return "int";
}
case M_LONG : {
return "long";
}
case M_TIME : {
return "long";
}
case M_TIMESTAMP : {
return "long";
}
}
return null;
}
public String getJavaTypeAsTypeName() {
switch (this.getType()) {
case Types.ARRAY : {
return "Types.ARRAY";
}
case Types.BIGINT : {
return "Types.BIGINT";
}
case Types.BINARY : {
return "Types.BINARY";
}
case Types.BIT : {
return "Types.BIT";
}
case Types.BLOB : {
return "Types.BLOB";
}
case Types.BOOLEAN : {
return "Types.BOOLEAN";
}
case Types.CHAR : {
return "Types.CHAR";
}
case Types.CLOB : {
return "Types.CLOB";
}
case Types.DATALINK : {
return "Types.DATALINK";
}
case Types.DATE : {
return "Types.DATE";
}
case Types.DECIMAL : {
return "Types.DECIMAL";
}
case Types.DISTINCT : {
return "Types.DISTINCT";
}
case Types.DOUBLE : {
return "Types.DOUBLE";
}
case Types.FLOAT : {
return "Types.FLOAT";
}
case Types.INTEGER : {
return "Types.INTEGER";
}
case Types.JAVA_OBJECT : {
return "Types.JAVA_OBJECT";
}
case Types.LONGVARBINARY : {
return "Types.LONGVARBINARY";
}
case Types.LONGVARCHAR : {
return "Types.LONGVARCHAR";
}
case Types.NULL : {
return "Types.NULL";
}
case Types.NUMERIC : {
return "Types.NUMERIC";
}
case Types.OTHER : {
return "Types.OTHER";
}
case Types.REAL : {
return "Types.REAL";
}
case Types.REF : {
return "Types.REF";
}
case Types.SMALLINT : {
return "Types.SMALLINT";
}
case Types.STRUCT : {
return "Types.STRUCT";
}
case Types.TIME : {
return "Types.TIME";
}
case Types.TIMESTAMP : {
return "Types.TIMESTAMP";
}
case Types.TINYINT : {
return "Types.TINYINT";
}
case Types.VARBINARY : {
return "Types.VARBINARY";
}
case Types.VARCHAR : {
return "Types.VARCHAR";
}
}
return "unkown SQL type " + this.getType();
}
/**
* @return 字段类型是否有长度限制
*/
public boolean isSizeLimit(){
switch (this.getMappedType()) {
case M_ARRAY :
case M_BYTES :
case M_CLOB :
case M_BLOB :
case M_STRING :
return true;
default:
return false;
}
}
/**
* @return 字段类型是否有最大长度限制
*/
public boolean isMaxSize(){
switch (this.getType()) {
case Types.BLOB :
case Types.CLOB :
case Types.NCLOB :
case Types.LONGVARBINARY :
case Types.LONGVARCHAR :
case Types.VARBINARY :
case Types.VARCHAR :
case Types.NVARCHAR :
return true;
default:
return false;
}
}
/**
* @return 字段类型是否有固定长度限制
*/
public boolean isFixSize(){
switch (this.getType()) {
case Types.ARRAY :
case Types.BINARY :
case Types.CHAR :
case Types.NCHAR:
return true;
default:
return false;
}
}
public boolean isCrossableDefaultvalue(){
return defaultValue != null && !defaultValue.equals("CURRENT_TIMESTAMP");
}
public boolean isColumnNumeric() {
switch (this.getMappedType()) {
case M_BIGDECIMAL :
case M_DOUBLE :
case M_FLOAT :
case M_BYTE :
case M_SHORT :
case M_INTEGER :
case M_LONG : {
return true;
}
}
return false;
}
public boolean isString() {
return M_STRING == this.getMappedType();
}
public boolean isFloat() {
return M_FLOAT == this.getMappedType();
}
public boolean isDate() {
switch (this.getMappedType()) {
case M_SQLDATE:
case M_UTILDATE :
case M_TIME :
case M_TIMESTAMP :
return true;
}
return false;
}
public boolean isBinary() {
switch (this.getMappedType()) {
case M_BYTES:
case M_BLOB:
return true;
}
return false;
}
public boolean isCalendar() {
return this.getMappedType() == M_CALENDAR;
}
public boolean hasCompareTo() throws Exception {
switch (this.getMappedType()) {
case M_ARRAY : {
return false;
}
case M_BIGDECIMAL : {
return true;
}
case M_BOOLEAN : {
return true;
}
case M_BYTES : {
return CodeWriter.binaryIsByteBuffer();
}
case M_CLOB : {
// Clob map to java.lang.String that has compareTo
return true;
}
case M_SQLDATE : {
return true;
}
case M_UTILDATE : {
return true;
}
case M_DOUBLE : {
return true;
}
case M_FLOAT : {
return true;
}
case M_BLOB : {
return CodeWriter.binaryIsByteBuffer();
}
case M_INTEGER : {
return true;
}
case M_LONG : {
return true;
}
case M_REF : {
return false;
}
case M_STRING : {
return true;
}
case M_TIME : {
return true;
}
case M_TIMESTAMP : {
return true;
}
case M_URL : {
return false;
}
case M_OBJECT : {
return false;
}
case M_CALENDAR : {
return true;
}
}
return false;
}
public boolean useEqualsInSetter() throws Exception {
// 优先使用equals方法
if(hasCompareTo())return true;
switch (this.getMappedType()) {
case M_BOOLEAN : {
return true;
}
case M_URL : {
return true;
}
}
return false;
}
public String getResultSetMethodObject(String pos) {
return this.getResultSetMethodObject("rs", pos);
}
public String getResultSetMethodObject(String resultSet, String pos) {
switch (this.getMappedType()) {
case M_ARRAY : {
return resultSet + ".getArray(" + pos + ")";
}
case M_LONG : {
return CodeWriter.MGR_CLASS + ".getLong(" + resultSet + ", " + pos + ")";
}
case M_BYTES : {
return CodeWriter.MGR_CLASS + ".getBytes(" + resultSet + ", " + pos + ")";
}
case M_BLOB : {
return CodeWriter.MGR_CLASS + ".getBlob(" + resultSet + ", " + pos + ")";
}
case M_BOOLEAN : {
return CodeWriter.MGR_CLASS + ".getBoolean(" + resultSet + ", " + pos + ")";
}
case M_STRING : {
return resultSet + ".getString(" + pos + ")";
}
case M_CLOB : {
return CodeWriter.MGR_CLASS + ".getClob(" + resultSet + ", " + pos + ")";
}
case M_URL : {
return resultSet + ".getURL(" + pos + ")";
}
case M_BIGDECIMAL : {
return resultSet + ".getBigDecimal(" + pos + ")";
}
case M_DOUBLE : {
return CodeWriter.MGR_CLASS + ".getDouble(" + resultSet + ", " + pos + ")";
}
case M_FLOAT : {
return CodeWriter.MGR_CLASS + ".getFloat(" + resultSet + ", " + pos + ")";
}
case M_INTEGER : {
return CodeWriter.MGR_CLASS + ".getInteger(" + resultSet + ", " + pos + ")";
}
case M_OBJECT : {
return resultSet + ".getObject(" + pos + ")";
}
case M_REF : {
return resultSet + ".getRef(" + pos + ")";
}
case M_SQLDATE : {
return resultSet + ".getDate(" + pos + ")";
}
case M_TIME : {
return resultSet + ".getTime(" + pos + ")";
}
case M_TIMESTAMP : {
return resultSet + ".getTimestamp(" + pos + ")";
}
case M_UTILDATE : {
switch (this.getType()) {
case Types.TIME : {
return resultSet + ".getTime(" + pos + ")";
}
case Types.TIMESTAMP : {
return resultSet + ".getTimestamp(" + pos + ")";
}
case Types.DATE : {
return resultSet + ".getDate(" + pos + ")";
}
}
this.tuoe();
}
case M_CALENDAR : {
return CodeWriter.MGR_CLASS + ".getCalendar(" + resultSet + ", " + pos + ")";
}
}
this.tuoe();
return null;
}
public String getPreparedStatementMethod(String var, int pos) {
return this.getPreparedStatementMethod(var, String.valueOf(pos));
}
public String getPreparedStatementMethod(String var, String pos) {
StringBuffer sb = new StringBuffer();
StringBuffer end = new StringBuffer();
end.append(pos).append(", ").append(var).append(");");
String fillNullStart = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "if(fillNull){";
String fillNullEnd = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "}";
Pattern p = Pattern.compile("^((?:SQL_LIKE_WILDCARD\\s*\\+)*)([\\w\\. \\(\\)-]*)((?:\\+\\s*SQL_LIKE_WILDCARD)*)$");
Matcher m = p.matcher(var);
if(!m.matches()){
throw new IllegalArgumentException(String.format("Not match found %s", var));
}
String v = m.group(2);
sb.append("if (").append(v).append(" == null) {"+fillNullStart+" ps.setNull(").append(pos).append(", ")
.append(this.getJavaTypeAsTypeName()).append(");").append(fillNullEnd).append(" } else { ");
end.append(" }");
switch (this.getMappedType()) {
case M_ARRAY : {
return sb.append("ps.setArray(").append(end).toString();
}
case M_LONG : {
return sb.append(CodeWriter.MGR_CLASS).append(".setLong(ps, ").append(end).toString();
}
case M_BYTES : {
return sb.append(CodeWriter.MGR_CLASS).append(".setBytes("+this.getJavaTypeAsTypeName()+",ps, ").append(end).toString();
}
case M_BLOB : {
return sb.append(CodeWriter.MGR_CLASS).append(".setBlob(ps, ").append(end).toString();
}
case M_BOOLEAN : {
return sb.append(CodeWriter.MGR_CLASS).append(".setBoolean(ps, ").append(end).toString();
}
case M_STRING : {
return sb.append("ps.setString(").append(end).toString();
}
case M_CLOB : {
return sb.append(CodeWriter.MGR_CLASS).append(".setClob(ps, ").append(end).toString();
}
case M_URL : {
return sb.append("ps.setURL(").append(end).toString();
}
case M_BIGDECIMAL : {
return sb.append("ps.setBigDecimal(").append(end).toString();
}
case M_DOUBLE : {
return sb.append(CodeWriter.MGR_CLASS).append(".setDouble(ps, ").append(end).toString();
}
case M_INTEGER : {
return sb.append(CodeWriter.MGR_CLASS).append(".setInteger(ps, ").append(end).toString();
}
case M_OBJECT : {
return sb.append("ps.setObject(").append(end).toString();
}
case M_FLOAT : {
return sb.append(CodeWriter.MGR_CLASS).append(".setFloat(ps, ").append(end).toString();
}
case M_SQLDATE : {
return sb.append("ps.setDate(").append(end).toString();
}
case M_TIME : {
return sb.append("ps.setTime(").append(end).toString();
}
case M_TIMESTAMP : {
return sb.append("ps.setTimestamp(").append(end).toString();
}
case M_UTILDATE : {
switch (this.getType()) {
case Types.TIMESTAMP : {
return sb.append("ps.setTimestamp(").append(pos).append(", new java.sql.Timestamp(").append(var)
.append(".getTime())); }").toString();
}
case Types.DATE : {
return sb.append("ps.setDate(").append(pos).append(", new java.sql.Date(").append(var)
.append(".getTime())); }").toString();
}
case Types.TIME : {
return sb.append("ps.setTime(").append(pos).append(", new java.sql.Time(").append(var)
.append(".getTime())); }").toString();
}
}
return null;
}
case M_CALENDAR : {
return sb.append(CodeWriter.MGR_CLASS).append(".setCalendar(ps, ").append(end).toString();
}
case M_REF : {
sb.setLength(0);
sb.append("ps.setRef(").append(end);
sb.setLength(sb.length() - 2);
return sb.toString();
}
}
sb.setLength(0);
sb.append("ps.setObject(").append(end);
sb.setLength(sb.length() - 2);
return sb.toString();
}
public String getStringConvertionMethod() {
switch (this.getMappedType()) {
case M_BIGDECIMAL : {
return "new java.math.BigDecimal";
}
case M_BOOLEAN : {
return "new Boolean";
}
case M_SQLDATE : {
return "new java.sql.Date";
}
case M_DOUBLE : {
return "new Double";
}
case M_FLOAT : {
return "new Float";
}
case M_INTEGER : {
return "new Integer";
}
case M_LONG : {
return "new Long";
}
case M_STRING : {
return "";
}
case M_UTILDATE :
case M_TIME :
case M_TIMESTAMP : {
if ("java.util.GregorianCalendar".equals(CodeWriter.dateClassName)) {
return "GregorianDate";
}
return CodeWriter.MGR_CLASS + ".getDateFromString";
}
}
System.err.println(
" unknown mapped type " + this.getMappedType() + " (" + this.getType() + ") for " + this.getFullName());
return "";
}
public String getDefaultWidget() {
if (this.isForeignKey()) {
return "SelectWidget";
}
if (this.isString() && (this.getSize() > 200 || this.getSize() == -1)) {
return "TextAreaWidget";
}
switch (this.getMappedType()) {
case M_BOOLEAN : {
return "BooleanWidget";
}
case M_SQLDATE :
case M_UTILDATE :
case M_TIME :
case M_TIMESTAMP : {
return "DateWidget";
}
case M_BIGDECIMAL :
case M_DOUBLE :
case M_FLOAT :
case M_INTEGER :
case M_LONG : {
return "NumericWidget";
}
case M_ARRAY :
case M_BYTES :
case M_CLOB :
case M_REF :
case M_STRING :
case M_URL :
case M_OBJECT : {
return "InputWidget";
}
}
System.err.println("type unknown for " + this.getFullName());
return "";
}
public boolean isVersion() {
if (!CodeWriter.optimisticLockType.equalsIgnoreCase("timestamp")) {
return false;
}
if (!this.getName().equalsIgnoreCase(CodeWriter.optimisticLockColumn)) {
return false;
}
if (this.getMappedType() == M_LONG || this.getMappedType() == M_STRING) {
return true;
}
return false;
}
public Table getTable() {
return this.db.getTable(this.getTableName());
}
public void addForeignKey(Column col,
String fkName,
short keySeq,
Table.ForeignKeyRule updateRule,
Table.ForeignKeyRule deleteRule) {
this.foreignKeys.add(col);
this.getTable().addForeignKey(this, fkName,keySeq, updateRule, deleteRule);
}
public List getForeignKeys() {
return this.foreignKeys;
}
public void addImportedKey(Column col) {
this.importedKeys.add(col);
this.getTable().addImportedKey(col);
}
public List getImportedKeys() {
return this.importedKeys;
}
public int countImportedKeys() {
return this.importedKeys.size();
}
public boolean isImportedKey() {
if (this.countImportedKeys() > 0) {
return true;
}
return false;
}
public Column getForeignColumn() {
return (Column) this.foreignKeys.get(0);
}
public int countForeignKeys() {
return this.foreignKeys.size();
}
public boolean isForeignKey() {
if (this.countForeignKeys() > 0) {
return true;
}
return false;
}
public String getPropertyTag() {
return (this.getTableName() + "." + this.getName()).toLowerCase();
}
public String getDefaultRules() {
String rule = "";
rule = this.getNullable() == 0 && !this.isPrimaryKey() ? rule + " nullnotallowed" : rule + " nullallowed";
if (this.getType() == 91 || this.getType() == 93) {
rule = rule + " dateformat";
}
return rule;
}
public boolean getDefaultIncludeFor(String webElement) {
return true;
}
private static final String EMPTY_STRING = "";
/**
* 生成缺省值字符串
* @param nullInstead 指示{@link #defaultValue}为 {@code null}时是否用字符串'null'代替
* @return 缺省值字符串
*/
public String getDefaultValue(boolean nullInstead) {
String empty = nullInstead?"null":EMPTY_STRING;
if(!CodeWriter.getPropertyBoolean("codewriter.generate.defaultvalue")){
return empty;
}
if (null != this.defaultValue) {
if (this.isColumnNumeric()) {
try {
double value = Double.parseDouble(this.defaultValue);
switch (this.getMappedType()) {
case M_BIGDECIMAL :
case M_SHORT :
case M_INTEGER :
case M_LONG : {
return this.generateNewNumeric(this.getFieldJavaType(), this.defaultValue);
}
case M_DOUBLE :
case M_FLOAT : {
return this.generateNewNumeric(this.getFieldJavaType(), String.valueOf(value));
}
case M_BYTE :{
return this.defaultValueForByte(this.defaultValue);
}
}
return empty;
} catch (NumberFormatException nfe) {
return empty;
}
}
if (this.isDate()) {
try {
return generateDateDefaultValue(this.getFieldJavaType(),this.defaultValue);
} catch (IllegalArgumentException pe) {
return empty;
}
}
if (this.isString()) {
return "\"" + this.defaultValue + '\"';
}
if (isBoolean()) {
return "1".equals(this.defaultValue) ? "true" : "false";
}
}
return this.defaultValue == null ? empty : this.defaultValue;
}
/** 兼容之前版本 */
public String getDefaultValue() {
return getDefaultValue(false);
}
/** 返回{@link #defaultValue}原始值 */
public String getOriginalDefaultValue(){
return this.defaultValue;
}
/** SQL 类型日期字符串转为java 日期对象 */
private static Date parseSqlDate(String source){
if(null == source)
throw new IllegalArgumentException();
try{
return java.sql.Date.valueOf(source);
}catch(IllegalArgumentException e){
try{
return java.sql.Time.valueOf(source);
}catch(IllegalArgumentException e2){
return java.sql.Timestamp.valueOf(source);
}
}
}
/** 生成日期类型缺省值语句 */
private String generateDateDefaultValue(String type, String parameter) {
StringBuffer sb = new StringBuffer(100);
Date parsedDate = parseSqlDate(parameter);
String dateStr;
switch(this.getMappedType()){
case M_UTILDATE:{
String instanceName="";
if(parsedDate instanceof java.sql.Date){
instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd\")";
}else if(parsedDate instanceof java.sql.Time){
instanceName = "new java.text.SimpleDateFormat(\"HH:mm:ss\")";
}else if(parsedDate instanceof java.sql.Timestamp){
instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\")";
}else{
throw new IllegalStateException("invalid type");
}
sb.append(instanceName).append(".parse(\"").append(parsedDate.toString()).append("\",new java.text.ParsePosition(0))");
break;
}
case M_SQLDATE:{
dateStr = new java.sql.Date(parsedDate.getTime()).toString();
sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");
break;
}
case M_TIME:{
dateStr = new java.sql.Time(parsedDate.getTime()).toString();
sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");
break;
}
case M_TIMESTAMP:{
dateStr = new java.sql.Timestamp(parsedDate.getTime()).toString();
sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");
break;
}
default:
return EMPTY_STRING;
}
return sb.toString();
}
private String generateNewNumeric(String type, String parameter) {
StringBuffer sb = new StringBuffer(70);
sb.append("new ").append(type);
sb.append('(').append(parameter).append(')');
return sb.toString();
}
private String defaultValueForByte(String parameter) {
return new StringBuffer(16).append("(byte)").append(parameter).toString();
}
/** 生成缺省值({@link #defaultValue})的注释信息 */
public String commentOfDefaultValue(){
return Strings.isNullOrEmpty(defaultValue)?EMPTY_STRING: "/* DEFAULT:'"+defaultValue+"'*/";
}
/** 生成缺省值赋值语句 */
public String getDefaultValueAssignment(boolean nullInstead){
StringBuffer buffer = new StringBuffer();
String value = getDefaultValue(nullInstead);
if(!value.isEmpty())
buffer.append(" = ").append(value);
return buffer.toString();
}
public String getRemarks() {
return this.remarks == null ? "" : this.remarks.getRemarks();
}
public String getJavaName() {
return this.convertName(this.getName());
}
public String getSampleData() {
if (this.getNullable() > 1 && rand.nextInt(20) == 10) {
return "";
}
if (this.isColumnNumeric()) {
return "" + rand.nextInt(100);
}
if (this.isDate()) {
Calendar rightNow = Calendar.getInstance();
rightNow.set(2000 + rand.nextInt(20), 1 + rand.nextInt(12), 1 + rand.nextInt(28), rand.nextInt(23),
rand.nextInt(60), rand.nextInt(60));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
return dateFormat.format(rightNow.getTime());
}
return StringUtilities.getSampleString((int) this.getSize());
}
private String escape(String s) {
return StringUtilities.escape((String) s);
}
private String escape() {
return this.escape(this.getName());
}
public String convertName(String columnName) {
return StringUtilities.convertName((String) columnName, true);
}
public String convertName(Column col) {
return this.convertName(col.getName());
}
public String convertName() {
return this.convertName(this.name);
}
public String getImportedKeyVarName() {
return this.convertName(this.escape() + "_collection");
}
public String getGetMethod() {
if(isBoolean()) {
return this.convertName("is_" + this.escape());
}
return this.convertName("get_" + this.escape());
}
public String getSetMethod() {
return this.convertName("set_" + this.escape());
}
public String getReadMethod() {
return this.convertName("read_" + this.escape());
}
public String getWriteMethod() {
return this.convertName("write_" + this.escape());
}
public String getModifiedMethod() {
return this.convertName("check_" + this.escape() + "_modified");
}
public String getInitializedMethod() {
return this.convertName("check_" + this.escape() + "_initialized");
}
public String getGetCacheMethod() {
return this.convertName("get_bean_by_" + this.escape());
}
public String getPutCacheMethod() {
return this.convertName("put_by_" + this.escape());
}
public String getPutIfAbsentCacheMethod() {
return this.convertName("put_If_absent_by_" + this.escape());
}
public String getReplaceCacheMethod() {
return this.convertName("replace_by_" + this.escape());
}
public String bitCheckExpression(String varName){
return String.format("ArraySupport.bitCheck(%s,%s)",varName,getIDConstName());
}
public String bitSetAssignExpression(String varName){
return String.format("ArraySupport.bitSet(%s,%s)",varName,getIDConstName());
}
public String bitResetAssignExpression(String varName){
return String.format("ArraySupport.bitReset(%s,%s)",varName,getIDConstName());
}
public String getWidgetMethod() {
return this.convertName("get_" + this.escape() + "_widget");
}
public String getVarName() {
return this.convertName(this.escape());
}
public String getCacheVarName() {
return this.convertName(this.escape() + "_cacher");
}
public String getFullVarName() {
return this.convertName(this.name +"_of_" + this.getTable().getBasename(true));
}
public String getModifiedVarName() {
return this.convertName(this.escape() + "_is_modified");
}
public String getInitializedVarName() {
return this.convertName(this.escape() + "_is_initialized");
}
public String getImportedKeyModifiedVarName() {
return this.convertName(this.escape() + "_collection_is_modified");
}
public String getImportedKeyInitializedVarName() {
return this.convertName(this.escape() + "_collection_is_initialized");
}
public String getImportedKeyInitializedMethod() {
return this.convertName("is_" + this.escape() + "_collection_initialized");
}
public String getImportedKeyGetMethod() {
return this.convertName("get_" + this.escape() + "_collection");
}
public String getImportedKeyAddMethod() {
return this.convertName("add_" + this.escape() + "");
}
public String getImportedKeySetMethod() {
return this.convertName("set_" + this.escape() + "_collection");
}
public String getImportedKeyModifiedMethod() {
return this.convertName("is_" + this.escape() + "_collection_modified");
}
public String getForeignKeyVarName() {
return this.convertName(this.escape() + "_object");
}
public String getForeignKeyModifiedVarName() {
return this.convertName(this.escape() + "_object_is_modified");
}
public String getForeignKeyInitializedVarName() {
return this.convertName(this.escape() + "_object_is_initialized");
}
public String getForeignKeyInitializedMethod() {
return this.convertName("is_" + this.escape() + "_object_initialized");
}
public String getForeignKeyGetMethod(String col) {
return this.convertName("get_" + this.escape() + "_object");
}
public String getForeignKeySetMethod(String col) {
return this.convertName("set_" + this.escape() + "_object");
}
public String getForeignKeyModifiedMethod(String col) {
return this.convertName("is_" + this.escape() + "_object_modified");
}
public String getTypeName() {
return this.typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public int compareTo(Column obj) {
return this.ordinal - obj.ordinal;
}
public String getAutoincrement() {
return autoincrement;
}
public void setAutoincrement(String autoincrement) {
this.autoincrement = autoincrement;
}
public boolean isAutoincrement(){
return "YES".equals(this.autoincrement);
}
public boolean isNotNull(){
return DatabaseMetaData.columnNoNulls == this.nullable ;
}
private static final String IV_PREFIX = "invalidvalue.";
private static final String IV_NUMBER = IV_PREFIX + "number";
private static final String IV_DATE = IV_PREFIX + "date";
private static final String PA_PREFIX = "prealloc.";
private static final String PA_STRING = PA_PREFIX + "string.limit";
private static final String PA_BINARY = PA_PREFIX + "binary.limit";
private String getCustomInvalidValueAnn(){
String iv = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName());
if(iv != null){
return String.format("@CodegenInvalidValue(\"%s\")",iv);
}
String exp = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName()+".exp" );
if(exp != null){
return String.format("@CodegenInvalidValue(exp=\"%s\")",exp);
}
return null;
}
public String getInvalidValueAnn(){
if(invalidValueAnn == null){
synchronized (this) {
if(invalidValueAnn == null){
invalidValueAnn = getCustomInvalidValueAnn();
if(invalidValueAnn == null){
if(isAutoincrement() || (getForeignKeys().size() ==1 && getForeignColumn().isAutoincrement())){
invalidValueAnn = "@CodegenInvalidValue(\"0\")";
} else if(isString()){
// 空字符串为无效值
invalidValueAnn = "@CodegenInvalidValue";
} else if(isBinary()){
// 空数组为无效值
invalidValueAnn = "@CodegenInvalidValue";
} else if(isColumnNumeric()){
String iv = CodeWriter.getProperty(IV_NUMBER , "-1");
invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")";
} else if(isDate()){
String iv = CodeWriter.getProperty(IV_DATE , "0");
invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")";
}else {
invalidValueAnn = "";
}
}
}
}
}
return invalidValueAnn;
}
private boolean isPreAlloc0(){
if(TypeToken.of(getJavaClass()).isPrimitive()){
return true;
}
String columns = CodeWriter.getProperty(PA_PREFIX + ".table." + getTableName());
if(columns != null){
if( elementsOf(columns).contains(getName())){
return true;
}
}
if(isString()){
return getSize() <= CodeWriter.getPropertyInteger(PA_STRING);
}
if(isBinary()){
return getSize() <= CodeWriter.getPropertyInteger(PA_BINARY);
}
return false;
}
public boolean isPreAlloc(){
if(preAlloc == null){
synchronized (this) {
if(preAlloc == null){
preAlloc = isPreAlloc0();
}
}
}
return preAlloc;
}
static void setJsonJacksonRawValue(boolean jsonJacksonRawValue) {
Column.jsonJacksonRawValue = jsonJacksonRawValue;
}
static void setByteBufferAsString(boolean byteBufferAsString) {
Column.byteBufferAsString = byteBufferAsString;
}
public static void setJacksonBeanSupport(boolean jacksonBeanSupport) {
Column.jacksonBeanSupport = jacksonBeanSupport;
}
public static void setGeometrySerialType(String geometrySerialType) {
Column.geometrySerialType = geometrySerialType;
}
}