001package gu.sql2java.generator; 002 003import java.sql.DatabaseMetaData; 004import java.sql.Types; 005import java.text.SimpleDateFormat; 006import java.util.Calendar; 007import java.util.Date; 008import java.util.List; 009import java.util.Random; 010import java.util.Vector; 011import java.util.regex.Matcher; 012import java.util.regex.Pattern; 013 014import org.apache.commons.lang.builder.EqualsBuilder; 015import org.apache.commons.lang.builder.ToStringBuilder; 016 017import com.google.common.base.Function; 018import com.google.common.base.Strings; 019import com.google.common.collect.ImmutableMap; 020import com.google.common.collect.Maps; 021import com.google.common.primitives.Primitives; 022import com.google.common.reflect.TypeToken; 023 024import gu.sql2java.generator.CodeWriter; 025import gu.sql2java.generator.Database; 026import gu.sql2java.generator.StringUtilities; 027import gu.sql2java.generator.Table; 028import net.gdface.utils.MiscellaneousUtils; 029 030public class Column implements Cloneable, Comparable<Column>,MappedType { 031 private String catalog; 032 private String schema; 033 private String tableName; 034 private String name; 035 private String remarks; 036 private String defaultValue; 037 private int size; 038 private int decDigits; 039 private int radix; 040 private int nullable; 041 private int ordinal; 042 private short type; 043 private boolean isPrimaryKey; 044 private String strCheckingType = ""; 045 private String autoincrement; 046 private Database db; 047 private List<Column> foreignKeys = new Vector<Column>(); 048 private List<Column> importedKeys = new Vector<Column>(); 049 private String typeName = ""; 050 private volatile String invalidValueAnn; 051 private volatile Boolean preAlloc; 052 private static Random rand = new Random(); 053 054 @Override 055 public String toString() { 056 return new ToStringBuilder(this) 057 .append("catalog",catalog) 058 .append("schema",schema) 059 .append("tableName",tableName) 060 .append("name",name) 061 .append("remarks",remarks) 062 .append("defaultValue",defaultValue) 063 .append("size",size) 064 .append("decDigits",decDigits) 065 .append("radix",radix) 066 .append("nullable",nullable) 067 .append("ordinal",ordinal) 068 .append("type",type) 069 .append("isPrimaryKey",isPrimaryKey) 070 .append("autoincrement",autoincrement) 071 .append("typeName",typeName) 072 .toString(); 073 } 074 075 @Override 076 public boolean equals(Object obj) { 077 if(super.equals(obj))return true; 078 if(!(obj instanceof Column))return false; 079 Column other = (Column)obj; 080 return new EqualsBuilder() 081 .append(catalog,other.catalog) 082 .append(schema,other.schema) 083 .append(tableName,other.tableName) 084 .append(name,other.name) 085 .append(remarks,other.remarks) 086 .append(defaultValue,other.defaultValue) 087 .append(size,other.size) 088 .append(decDigits,other.decDigits) 089 .append(radix,other.radix) 090 .append(nullable,other.nullable) 091 .append(ordinal,other.ordinal) 092 .append(type,other.type) 093 .append(isPrimaryKey,other.isPrimaryKey) 094 .append(autoincrement,other.autoincrement) 095 .append(typeName,other.typeName) 096 .isEquals(); 097 } 098 099 public void setCheckingType(String strValue) { 100 this.strCheckingType = strValue; 101 } 102 103 public String getCheckingType() { 104 return this.strCheckingType; 105 } 106 107 public void setDatabase(Database db) { 108 this.db = db; 109 } 110 111 public void setCatalog(String catalog) { 112 this.catalog = catalog; 113 } 114 115 public void setSchema(String schema) { 116 this.schema = schema; 117 } 118 119 public void setTableName(String tableName) { 120 this.tableName = tableName; 121 } 122 123 public void setName(String name) { 124 this.name = null == name ? "" : name.replaceAll("\\W", ""); 125 } 126 127 public void setType(short type) { 128 this.type = type; 129 } 130 131 public void setSize(int size) { 132 this.size = size; 133 } 134 135 public void setDecimalDigits(int decDigits) { 136 this.decDigits = decDigits; 137 } 138 139 public void setRadix(int radix) { 140 this.radix = radix; 141 } 142 143 public void setNullable(int nullable) { 144 this.nullable = nullable; 145 } 146 147 public void setRemarks(String remarks) { 148 if (remarks != null) { 149 this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH"); 150 } 151 } 152 153 public void setDefaultValue(String defaultValue) { 154 this.defaultValue = defaultValue; 155 } 156 157 public void setOrdinalPosition(int ordinal) { 158 this.ordinal = ordinal; 159 } 160 161 public void isPrimaryKey(boolean isKey) { 162 this.isPrimaryKey = isKey; 163 } 164 165 public String getCatalog() { 166 return this.catalog; 167 } 168 169 public String getSchema() { 170 return this.schema; 171 } 172 173 public String getTableName() { 174 return this.tableName; 175 } 176 177 public String getName() { 178 return this.name; 179 } 180 181 public short getType() { 182 return this.type; 183 } 184 185 public int getSize() { 186 return this.size; 187 } 188 189 public int getDecimalDigits() { 190 return this.decDigits; 191 } 192 193 public int getRadix() { 194 return this.radix; 195 } 196 197 public int getNullable() { 198 return this.nullable; 199 } 200 201 public String getNullableAsString() { 202 return this.getNullable() != 0 ? "nullable" : "null not allowed"; 203 } 204 205 public int getOrdinalPosition() { 206 return this.ordinal; 207 } 208 209 public boolean isPrimaryKey() { 210 return this.isPrimaryKey; 211 } 212 213 public String getFullName() { 214 return this.tableName + "." + this.getName(); 215 } 216 217 public String getConstName() { 218 return this.getName().toUpperCase(); 219 } 220 221 public String getIDConstName() { 222 return (this.tableName + "_ID_" + this.getName()).toUpperCase(); 223 } 224 public String getIDMaskConstName() { 225 return (this.tableName + "_ID_" + this.getName()).toUpperCase() + "_MASK"; 226 } 227 public Object clone() throws CloneNotSupportedException { 228 return super.clone(); 229 } 230 231 private void tuoe() { 232 throw new UnsupportedOperationException("Not supported yet: " + this.getTableName() + "." + this.getName() + " " 233 + this.getJavaTypeAsTypeName()); 234 } 235 236 private void tiae() { 237 throw new IllegalArgumentException("No primary type associated: " + this.getTableName() + "." + this.getName()); 238 } 239 240 public int getMappedType() { 241 switch (this.getType()) { 242 case Types.ARRAY : { 243 return M_ARRAY; 244 } 245 case Types.BIGINT : { 246 return M_LONG; 247 } 248 case Types.BINARY : { 249 return M_BYTES; 250 } 251 case Types.BIT : { 252 return M_BOOLEAN; 253 } 254 case Types.BLOB : { 255 return M_BLOB; 256 } 257 case Types.BOOLEAN : { 258 return M_BOOLEAN; 259 } 260 case Types.CHAR : { 261 return M_STRING; 262 } 263 case Types.CLOB : { 264 return M_CLOB; 265 } 266 case Types.DATALINK : { 267 return M_URL; 268 } 269 case Types.DATE : { 270 if ("java.util.Date".equals(CodeWriter.dateClassName)) { 271 return M_UTILDATE; 272 } 273 if ("java.sql.Date".equals(CodeWriter.dateClassName)) { 274 return M_SQLDATE; 275 } 276 if ("java.util.Calendar".equals(CodeWriter.dateClassName)) { 277 return M_CALENDAR; 278 } 279 this.tuoe(); 280 } 281 case Types.DECIMAL : { 282 return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; 283 } 284 case Types.DISTINCT : { 285 return M_OBJECT; 286 } 287 case Types.DOUBLE : { 288 return M_DOUBLE; 289 } 290 case Types.FLOAT : { 291 return M_DOUBLE; 292 } 293 case Types.INTEGER : { 294 return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? M_LONG : M_INTEGER; 295 } 296 case Types.JAVA_OBJECT : { 297 return M_OBJECT; 298 } 299 case Types.LONGVARBINARY : { 300 return M_BYTES; 301 } 302 case Types.LONGVARCHAR : { 303 return M_STRING; 304 } 305 case Types.NUMERIC : { 306 return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; 307 } 308 case Types.OTHER : { 309 return M_OBJECT; 310 } 311 case Types.REAL : { 312 return M_FLOAT; 313 } 314 case Types.REF : { 315 return M_REF; 316 } 317 case Types.SMALLINT : { 318 return M_INTEGER; 319 } 320 case Types.STRUCT : { 321 return M_OBJECT; 322 } 323 case Types.TIME : { 324 if ("java.util.Date".equals(CodeWriter.timeClassName)) { 325 return M_UTILDATE; 326 } 327 if ("java.sql.Time".equals(CodeWriter.timeClassName)) { 328 return M_TIME; 329 } 330 if ("java.util.Calendar".equals(CodeWriter.timeClassName)) { 331 return M_CALENDAR; 332 } 333 this.tuoe(); 334 } 335 case Types.TIMESTAMP : { 336 if ("java.util.Date".equals(CodeWriter.timestampClassName)) { 337 return M_UTILDATE; 338 } 339 if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) { 340 return M_TIMESTAMP; 341 } 342 if ("java.util.Calendar".equals(CodeWriter.timestampClassName)) { 343 return M_CALENDAR; 344 } 345 this.tuoe(); 346 } 347 case Types.TINYINT : { 348 return M_INTEGER; 349 } 350 case Types.VARBINARY : { 351 return M_BYTES; 352 } 353 case Types.VARCHAR : { 354 return M_STRING; 355 } 356 } 357 this.tuoe(); 358 return -1; 359 } 360 361 public String getQuerySetMethod() { 362 switch (this.getType()) { 363 case Types.ARRAY : { 364 return "setArray"; 365 } 366 case Types.BIGINT : { 367 return "setBigDecimal"; 368 } 369 case Types.BINARY : { 370 return "setBytes"; 371 } 372 case Types.BIT : { 373 return "setBoolean"; 374 } 375 case Types.BLOB : { 376 return "setBlob"; 377 } 378 case Types.BOOLEAN : { 379 return "setBoolean"; 380 } 381 case Types.CHAR : { 382 return "setString"; 383 } 384 case Types.CLOB : { 385 return "setClob"; 386 } 387 case Types.DATALINK : { 388 return "setURL"; 389 } 390 case Types.DATE : { 391 return "setDate"; 392 } 393 case Types.DECIMAL : { 394 return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong"; 395 } 396 case Types.DISTINCT : { 397 return "setObject"; 398 } 399 case Types.DOUBLE : { 400 return "setDouble"; 401 } 402 case Types.FLOAT : { 403 return "setDouble"; 404 } 405 case Types.INTEGER : { 406 return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? "setLong" : "setInt"; 407 } 408 case Types.JAVA_OBJECT : { 409 return "setObject"; 410 } 411 case Types.LONGVARBINARY : { 412 return "setBytes"; 413 } 414 case Types.LONGVARCHAR : { 415 return "setString"; 416 } 417 case Types.NUMERIC : { 418 return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong"; 419 } 420 case Types.OTHER : { 421 return "setObject"; 422 } 423 case Types.REAL : { 424 return "setFloat"; 425 } 426 case Types.REF : { 427 return "setRef"; 428 } 429 case Types.SMALLINT : { 430 return "setInt"; 431 } 432 case Types.STRUCT : { 433 return "setObject"; 434 } 435 case Types.TIME : { 436 if ("java.util.Date".equals(CodeWriter.timeClassName)) { 437 return "setDate"; 438 } 439 if ("java.sql.Time".equals(CodeWriter.timeClassName)) { 440 return "setTime"; 441 } 442 this.tuoe(); 443 } 444 case Types.TIMESTAMP : { 445 if ("java.util.Date".equals(CodeWriter.timestampClassName)) { 446 return "setDate"; 447 } 448 if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) { 449 return "setTimestamp"; 450 } 451 this.tuoe(); 452 } 453 case Types.TINYINT : { 454 return "setInt"; 455 } 456 case Types.VARBINARY : { 457 return "setBytes"; 458 } 459 case Types.VARCHAR : { 460 return "setString"; 461 } 462 } 463 this.tuoe(); 464 return "setObject"; 465 } 466 /** 467 * @return 返回对应的Java类型 468 */ 469 public Class<?> getJavaClass() { 470 switch (this.getMappedType()) { 471 case M_ARRAY : { 472 return java.sql.Array.class; 473 } 474 case M_BIGDECIMAL : { 475 return java.math.BigDecimal.class; 476 } 477 case M_BOOLEAN : { 478 return Boolean.class; 479 } 480 case M_BYTES : { 481 try { 482 return Class.forName(CodeWriter.binaryClassName); 483 } catch (ClassNotFoundException e) { 484 throw new RuntimeException(e); 485 } 486 } 487 case M_CLOB : { 488 // map Clob to java.lang.String 489 return String.class; 490 } 491 case M_SQLDATE : { 492 return java.sql.Date.class; 493 } 494 case M_UTILDATE : { 495 return java.util.Date.class; 496 } 497 case M_DOUBLE : { 498 return Double.class; 499 } 500 case M_FLOAT : { 501 return Float.class; 502 } 503 case M_BLOB : { 504 try { 505 return Class.forName(CodeWriter.binaryClassName); 506 } catch (ClassNotFoundException e) { 507 throw new RuntimeException(e); 508 } 509 } 510 case M_INTEGER : { 511 return Integer.class; 512 } 513 case M_LONG : { 514 return Long.class; 515 } 516 case M_REF : { 517 return java.sql.Ref.class; 518 } 519 case M_STRING : { 520 return String.class; 521 } 522 case M_TIME : { 523 return java.sql.Time.class; 524 } 525 case M_TIMESTAMP : { 526 return java.sql.Timestamp.class; 527 } 528 case M_URL : { 529 return java.net.URL.class; 530 } 531 case M_OBJECT : { 532 return Object.class; 533 } 534 case M_CALENDAR : { 535 return java.util.Calendar.class; 536 } 537 } 538 this.tiae(); 539 return null; 540 } 541 private String getJavaType(Class<?> type) { 542 if(type.isArray()){ 543 return getJavaType(type.getComponentType()) + "[]"; 544 } 545 if(type.isPrimitive()){ 546 return type.getSimpleName(); 547 } 548 if(type.getPackage().getName().equals("java.lang")){ 549 return type.getSimpleName(); 550 } 551 return type.getName(); 552 } 553 /** 554 * 返回对应的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名 555 * @return 556 */ 557 public String getJavaType() { 558 return getJavaType(getJavaClass()); 559 } 560 561 public boolean hasPrimaryType() { 562 return this.getJavaPrimaryType() != null; 563 } 564 565 public String getJavaPrimaryType() throws IllegalArgumentException { 566 int decimalDigits = this.getDecimalDigits(); 567 if ((this.type == Types.DECIMAL || this.type == Types.NUMERIC) && decimalDigits == 0) { 568 if (this.size == 1) { 569 return "boolean"; 570 } 571 if (this.size < 3) { 572 return "byte"; 573 } 574 if (this.size < 5) { 575 return "short"; 576 } 577 if (this.size < 10) { 578 return "int"; 579 } 580 if (this.size < 19) { 581 return "long"; 582 } 583 } 584 switch (this.getMappedType()) { 585 case M_BOOLEAN : { 586 return "boolean"; 587 } 588 case M_SQLDATE : { 589 return "long"; 590 } 591 case M_UTILDATE : { 592 return "long"; 593 } 594 case M_DOUBLE : { 595 return "double"; 596 } 597 case M_FLOAT : { 598 return "float"; 599 } 600 case M_INTEGER : { 601 return "int"; 602 } 603 case M_LONG : { 604 return "long"; 605 } 606 case M_TIME : { 607 return "long"; 608 } 609 case M_TIMESTAMP : { 610 return "long"; 611 } 612 } 613 return null; 614 } 615 616 public String getNullInstead(){ 617 if(isDate()){ 618 return "new "+getJavaType() + "(0L)"; 619 }else if(isString()){ 620 return "\"\""; 621 }else{ 622 String primitiveName = getJavaPrimaryType(); 623 if(null != primitiveName){ 624 ImmutableMap<String, Class<?>> primtypes = Maps.uniqueIndex(Primitives.allWrapperTypes(),new Function<Class<?>,String>(){ 625 @Override 626 public String apply(Class<?> input) { 627 return Primitives.unwrap(input).getSimpleName(); 628 }}); 629 Class<?> wrapType = primtypes.get(primitiveName); 630 if(Number.class.isAssignableFrom(wrapType) || Character.class==wrapType){ 631 return wrapType.getSimpleName()+".MIN_VALUE"; 632 }else if(Boolean.class == wrapType) 633 return wrapType.getSimpleName()+".FALSE"; 634 tuoe(); 635 } 636 } 637 return "null"; 638 } 639 public String getJavaTypeAsTypeName() { 640 switch (this.getType()) { 641 case Types.ARRAY : { 642 return "Types.ARRAY"; 643 } 644 case Types.BIGINT : { 645 return "Types.BIGINT"; 646 } 647 case Types.BINARY : { 648 return "Types.BINARY"; 649 } 650 case Types.BIT : { 651 return "Types.BIT"; 652 } 653 case Types.BLOB : { 654 return "Types.BLOB"; 655 } 656 case Types.BOOLEAN : { 657 return "Types.BOOLEAN"; 658 } 659 case Types.CHAR : { 660 return "Types.CHAR"; 661 } 662 case Types.CLOB : { 663 return "Types.CLOB"; 664 } 665 case Types.DATALINK : { 666 return "Types.DATALINK"; 667 } 668 case Types.DATE : { 669 return "Types.DATE"; 670 } 671 case Types.DECIMAL : { 672 return "Types.DECIMAL"; 673 } 674 case Types.DISTINCT : { 675 return "Types.DISTINCT"; 676 } 677 case Types.DOUBLE : { 678 return "Types.DOUBLE"; 679 } 680 case Types.FLOAT : { 681 return "Types.FLOAT"; 682 } 683 case Types.INTEGER : { 684 return "Types.INTEGER"; 685 } 686 case Types.JAVA_OBJECT : { 687 return "Types.JAVA_OBJECT"; 688 } 689 case Types.LONGVARBINARY : { 690 return "Types.LONGVARBINARY"; 691 } 692 case Types.LONGVARCHAR : { 693 return "Types.LONGVARCHAR"; 694 } 695 case Types.NULL : { 696 return "Types.NULL"; 697 } 698 case Types.NUMERIC : { 699 return "Types.NUMERIC"; 700 } 701 case Types.OTHER : { 702 return "Types.OTHER"; 703 } 704 case Types.REAL : { 705 return "Types.REAL"; 706 } 707 case Types.REF : { 708 return "Types.REF"; 709 } 710 case Types.SMALLINT : { 711 return "Types.SMALLINT"; 712 } 713 case Types.STRUCT : { 714 return "Types.STRUCT"; 715 } 716 case Types.TIME : { 717 return "Types.TIME"; 718 } 719 case Types.TIMESTAMP : { 720 return "Types.TIMESTAMP"; 721 } 722 case Types.TINYINT : { 723 return "Types.TINYINT"; 724 } 725 case Types.VARBINARY : { 726 return "Types.VARBINARY"; 727 } 728 case Types.VARCHAR : { 729 return "Types.VARCHAR"; 730 } 731 } 732 return "unkown SQL type " + this.getType(); 733 } 734 735 /** 736 * @return 字段类型是否有长度限制 737 */ 738 public boolean isSizeLimit(){ 739 switch (this.getMappedType()) { 740 case M_ARRAY : 741 case M_BYTES : 742 case M_CLOB : 743 case M_BLOB : 744 case M_STRING : 745 return true; 746 default: 747 return false; 748 } 749 } 750 /** 751 * @return 字段类型是否有最大长度限制 752 */ 753 public boolean isMaxSize(){ 754 switch (this.getType()) { 755 case Types.BLOB : 756 case Types.CLOB : 757 case Types.NCLOB : 758 case Types.LONGVARBINARY : 759 case Types.LONGVARCHAR : 760 case Types.VARBINARY : 761 case Types.VARCHAR : 762 case Types.NVARCHAR : 763 return true; 764 default: 765 return false; 766 } 767 } 768 /** 769 * @return 字段类型是否有固定长度限制 770 */ 771 public boolean isFixSize(){ 772 switch (this.getType()) { 773 case Types.ARRAY : 774 case Types.BINARY : 775 case Types.CHAR : 776 case Types.NCHAR: 777 return true; 778 default: 779 return false; 780 } 781 } 782 783 public boolean isCrossableDefaultvalue(){ 784 return defaultValue != null && !defaultValue.equals("CURRENT_TIMESTAMP"); 785 } 786 public boolean isColumnNumeric() { 787 switch (this.getMappedType()) { 788 case M_BIGDECIMAL : 789 case M_DOUBLE : 790 case M_FLOAT : 791 case M_INTEGER : 792 case M_LONG : { 793 return true; 794 } 795 } 796 return false; 797 } 798 799 public boolean isString() { 800 return M_STRING == this.getMappedType(); 801 } 802 public boolean isFloat() { 803 return M_FLOAT == this.getMappedType(); 804 } 805 public boolean isDate() { 806 switch (this.getMappedType()) { 807 case M_SQLDATE: 808 case M_UTILDATE : 809 case M_TIME : 810 case M_TIMESTAMP : 811 return true; 812 } 813 return false; 814 } 815 public boolean isBinary() { 816 switch (this.getMappedType()) { 817 case M_BYTES: 818 case M_BLOB: 819 return true; 820 } 821 return false; 822 } 823 public boolean isCalendar() { 824 return this.getMappedType() == M_CALENDAR; 825 } 826 827 public boolean hasCompareTo() throws Exception { 828 switch (this.getMappedType()) { 829 case M_ARRAY : { 830 return false; 831 } 832 case M_BIGDECIMAL : { 833 return true; 834 } 835 case M_BOOLEAN : { 836 return true; 837 } 838 case M_BYTES : { 839 return CodeWriter.binaryIsByteBuffer(); 840 } 841 case M_CLOB : { 842 // Clob map to java.lang.String that has compareTo 843 return true; 844 } 845 case M_SQLDATE : { 846 return true; 847 } 848 case M_UTILDATE : { 849 return true; 850 } 851 case M_DOUBLE : { 852 return true; 853 } 854 case M_FLOAT : { 855 return true; 856 } 857 case M_BLOB : { 858 return CodeWriter.binaryIsByteBuffer(); 859 } 860 case M_INTEGER : { 861 return true; 862 } 863 case M_LONG : { 864 return true; 865 } 866 case M_REF : { 867 return false; 868 } 869 case M_STRING : { 870 return true; 871 } 872 case M_TIME : { 873 return true; 874 } 875 case M_TIMESTAMP : { 876 return true; 877 } 878 case M_URL : { 879 return false; 880 } 881 case M_OBJECT : { 882 return false; 883 } 884 case M_CALENDAR : { 885 return true; 886 } 887 } 888 return false; 889 } 890 891 public boolean useEqualsInSetter() throws Exception { 892 // 优先使用equals方法 893 if(hasCompareTo())return true; 894 switch (this.getMappedType()) { 895 case M_BOOLEAN : { 896 return true; 897 } 898 case M_URL : { 899 return true; 900 } 901 } 902 return false; 903 } 904 905 public String getResultSetMethodObject(String pos) { 906 return this.getResultSetMethodObject("rs", pos); 907 } 908 909 public String getResultSetMethodObject(String resultSet, String pos) { 910 switch (this.getMappedType()) { 911 case M_ARRAY : { 912 return resultSet + ".getArray(" + pos + ")"; 913 } 914 case M_LONG : { 915 return CodeWriter.MGR_CLASS + ".getLong(" + resultSet + ", " + pos + ")"; 916 } 917 case M_BYTES : { 918 return CodeWriter.MGR_CLASS + ".getBytes(" + resultSet + ", " + pos + ")"; 919 } 920 case M_BLOB : { 921 return CodeWriter.MGR_CLASS + ".getBlob(" + resultSet + ", " + pos + ")"; 922 } 923 case M_BOOLEAN : { 924 return CodeWriter.MGR_CLASS + ".getBoolean(" + resultSet + ", " + pos + ")"; 925 } 926 case M_STRING : { 927 return resultSet + ".getString(" + pos + ")"; 928 } 929 case M_CLOB : { 930 return CodeWriter.MGR_CLASS + ".getClob(" + resultSet + ", " + pos + ")"; 931 } 932 case M_URL : { 933 return resultSet + ".getURL(" + pos + ")"; 934 } 935 case M_BIGDECIMAL : { 936 return resultSet + ".getBigDecimal(" + pos + ")"; 937 } 938 case M_DOUBLE : { 939 return CodeWriter.MGR_CLASS + ".getDouble(" + resultSet + ", " + pos + ")"; 940 } 941 case M_FLOAT : { 942 return CodeWriter.MGR_CLASS + ".getFloat(" + resultSet + ", " + pos + ")"; 943 } 944 case M_INTEGER : { 945 return CodeWriter.MGR_CLASS + ".getInteger(" + resultSet + ", " + pos + ")"; 946 } 947 case M_OBJECT : { 948 return resultSet + ".getObject(" + pos + ")"; 949 } 950 case M_REF : { 951 return resultSet + ".getRef(" + pos + ")"; 952 } 953 case M_SQLDATE : { 954 return resultSet + ".getDate(" + pos + ")"; 955 } 956 case M_TIME : { 957 return resultSet + ".getTime(" + pos + ")"; 958 } 959 case M_TIMESTAMP : { 960 return resultSet + ".getTimestamp(" + pos + ")"; 961 } 962 case M_UTILDATE : { 963 switch (this.getType()) { 964 case Types.TIME : { 965 return resultSet + ".getTime(" + pos + ")"; 966 } 967 case Types.TIMESTAMP : { 968 return resultSet + ".getTimestamp(" + pos + ")"; 969 } 970 case Types.DATE : { 971 return resultSet + ".getDate(" + pos + ")"; 972 } 973 } 974 this.tuoe(); 975 } 976 case M_CALENDAR : { 977 return CodeWriter.MGR_CLASS + ".getCalendar(" + resultSet + ", " + pos + ")"; 978 } 979 } 980 this.tuoe(); 981 return null; 982 } 983 984 public String getPreparedStatementMethod(String var, int pos) { 985 return this.getPreparedStatementMethod(var, String.valueOf(pos)); 986 } 987 988 public String getPreparedStatementMethod(String var, String pos) { 989 StringBuffer sb = new StringBuffer(); 990 StringBuffer end = new StringBuffer(); 991 end.append(pos).append(", ").append(var).append(");"); 992 String fillNullStart = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "if(fillNull){"; 993 String fillNullEnd = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "}"; 994 Pattern p = Pattern.compile("^((?:SQL_LIKE_WILDCARD\\s*\\+)*)([\\w\\. \\(\\)-]*)((?:\\+\\s*SQL_LIKE_WILDCARD)*)$"); 995 996 Matcher m = p.matcher(var); 997 if(!m.matches()){ 998 throw new IllegalArgumentException(String.format("Not match found %s", var)); 999 } 1000 String v = m.group(2); 1001 sb.append("if (").append(v).append(" == null) {"+fillNullStart+" ps.setNull(").append(pos).append(", ") 1002 .append(this.getJavaTypeAsTypeName()).append(");").append(fillNullEnd).append(" } else { "); 1003 end.append(" }"); 1004 switch (this.getMappedType()) { 1005 case M_ARRAY : { 1006 return sb.append("ps.setArray(").append(end).toString(); 1007 } 1008 case M_LONG : { 1009 return sb.append(CodeWriter.MGR_CLASS).append(".setLong(ps, ").append(end).toString(); 1010 } 1011 case M_BYTES : { 1012 return sb.append(CodeWriter.MGR_CLASS).append(".setBytes("+this.getJavaTypeAsTypeName()+",ps, ").append(end).toString(); 1013 } 1014 case M_BLOB : { 1015 return sb.append(CodeWriter.MGR_CLASS).append(".setBlob(ps, ").append(end).toString(); 1016 } 1017 case M_BOOLEAN : { 1018 return sb.append(CodeWriter.MGR_CLASS).append(".setBoolean(ps, ").append(end).toString(); 1019 } 1020 case M_STRING : { 1021 return sb.append("ps.setString(").append(end).toString(); 1022 } 1023 case M_CLOB : { 1024 return sb.append(CodeWriter.MGR_CLASS).append(".setClob(ps, ").append(end).toString(); 1025 } 1026 case M_URL : { 1027 return sb.append("ps.setURL(").append(end).toString(); 1028 } 1029 case M_BIGDECIMAL : { 1030 return sb.append("ps.setBigDecimal(").append(end).toString(); 1031 } 1032 case M_DOUBLE : { 1033 return sb.append(CodeWriter.MGR_CLASS).append(".setDouble(ps, ").append(end).toString(); 1034 } 1035 case M_INTEGER : { 1036 return sb.append(CodeWriter.MGR_CLASS).append(".setInteger(ps, ").append(end).toString(); 1037 } 1038 case M_OBJECT : { 1039 return sb.append("ps.setObject(").append(end).toString(); 1040 } 1041 case M_FLOAT : { 1042 return sb.append(CodeWriter.MGR_CLASS).append(".setFloat(ps, ").append(end).toString(); 1043 } 1044 case M_SQLDATE : { 1045 return sb.append("ps.setDate(").append(end).toString(); 1046 } 1047 case M_TIME : { 1048 return sb.append("ps.setTime(").append(end).toString(); 1049 } 1050 case M_TIMESTAMP : { 1051 return sb.append("ps.setTimestamp(").append(end).toString(); 1052 } 1053 case M_UTILDATE : { 1054 switch (this.getType()) { 1055 case Types.TIMESTAMP : { 1056 return sb.append("ps.setTimestamp(").append(pos).append(", new java.sql.Timestamp(").append(var) 1057 .append(".getTime())); }").toString(); 1058 } 1059 case Types.DATE : { 1060 return sb.append("ps.setDate(").append(pos).append(", new java.sql.Date(").append(var) 1061 .append(".getTime())); }").toString(); 1062 } 1063 case Types.TIME : { 1064 return sb.append("ps.setTime(").append(pos).append(", new java.sql.Time(").append(var) 1065 .append(".getTime())); }").toString(); 1066 } 1067 } 1068 return null; 1069 } 1070 case M_CALENDAR : { 1071 return sb.append(CodeWriter.MGR_CLASS).append(".setCalendar(ps, ").append(end).toString(); 1072 } 1073 case M_REF : { 1074 sb.setLength(0); 1075 sb.append("ps.setRef(").append(end); 1076 sb.setLength(sb.length() - 2); 1077 return sb.toString(); 1078 } 1079 } 1080 sb.setLength(0); 1081 sb.append("ps.setObject(").append(end); 1082 sb.setLength(sb.length() - 2); 1083 return sb.toString(); 1084 } 1085 1086 public String getStringConvertionMethod() { 1087 switch (this.getMappedType()) { 1088 case M_BIGDECIMAL : { 1089 return "new java.math.BigDecimal"; 1090 } 1091 case M_BOOLEAN : { 1092 return "new Boolean"; 1093 } 1094 case M_SQLDATE : { 1095 return "new java.sql.Date"; 1096 } 1097 case M_DOUBLE : { 1098 return "new Double"; 1099 } 1100 case M_FLOAT : { 1101 return "new Float"; 1102 } 1103 case M_INTEGER : { 1104 return "new Integer"; 1105 } 1106 case M_LONG : { 1107 return "new Long"; 1108 } 1109 case M_STRING : { 1110 return ""; 1111 } 1112 case M_UTILDATE : 1113 case M_TIME : 1114 case M_TIMESTAMP : { 1115 if ("java.util.GregorianCalendar".equals(CodeWriter.dateClassName)) { 1116 return "GregorianDate"; 1117 } 1118 return CodeWriter.MGR_CLASS + ".getDateFromString"; 1119 } 1120 } 1121 System.err.println( 1122 " unknown mapped type " + this.getMappedType() + " (" + this.getType() + ") for " + this.getFullName()); 1123 return ""; 1124 } 1125 1126 public String getDefaultWidget() { 1127 if (this.isForeignKey()) { 1128 return "SelectWidget"; 1129 } 1130 if (this.isString() && (this.getSize() > 200 || this.getSize() == -1)) { 1131 return "TextAreaWidget"; 1132 } 1133 switch (this.getMappedType()) { 1134 case M_BOOLEAN : { 1135 return "BooleanWidget"; 1136 } 1137 case M_SQLDATE : 1138 case M_UTILDATE : 1139 case M_TIME : 1140 case M_TIMESTAMP : { 1141 return "DateWidget"; 1142 } 1143 case M_BIGDECIMAL : 1144 case M_DOUBLE : 1145 case M_FLOAT : 1146 case M_INTEGER : 1147 case M_LONG : { 1148 return "NumericWidget"; 1149 } 1150 case M_ARRAY : 1151 case M_BYTES : 1152 case M_CLOB : 1153 case M_REF : 1154 case M_STRING : 1155 case M_URL : 1156 case M_OBJECT : { 1157 return "InputWidget"; 1158 } 1159 } 1160 System.err.println("type unknown for " + this.getFullName()); 1161 return ""; 1162 } 1163 1164 public boolean isVersion() { 1165 if (!CodeWriter.optimisticLockType.equalsIgnoreCase("timestamp")) { 1166 return false; 1167 } 1168 if (!this.getName().equalsIgnoreCase(CodeWriter.optimisticLockColumn)) { 1169 return false; 1170 } 1171 if (this.getMappedType() == M_LONG || this.getMappedType() == M_STRING) { 1172 return true; 1173 } 1174 return false; 1175 } 1176 1177 public Table getTable() { 1178 return this.db.getTable(this.getTableName()); 1179 } 1180 1181 public void addForeignKey(Column col, 1182 String fkName, 1183 short keySeq, 1184 Table.ForeignKeyRule updateRule, 1185 Table.ForeignKeyRule deleteRule) { 1186 this.foreignKeys.add(col); 1187 this.getTable().addForeignKey(this, fkName,keySeq, updateRule, deleteRule); 1188 } 1189 1190 public List<Column> getForeignKeys() { 1191 return this.foreignKeys; 1192 } 1193 1194 public void addImportedKey(Column col) { 1195 this.importedKeys.add(col); 1196 this.getTable().addImportedKey(col); 1197 } 1198 1199 public List<Column> getImportedKeys() { 1200 return this.importedKeys; 1201 } 1202 1203 public int countImportedKeys() { 1204 return this.importedKeys.size(); 1205 } 1206 1207 public boolean isImportedKey() { 1208 if (this.countImportedKeys() > 0) { 1209 return true; 1210 } 1211 return false; 1212 } 1213 1214 public Column getForeignColumn() { 1215 return (Column) this.foreignKeys.get(0); 1216 } 1217 1218 public int countForeignKeys() { 1219 return this.foreignKeys.size(); 1220 } 1221 1222 public boolean isForeignKey() { 1223 if (this.countForeignKeys() > 0) { 1224 return true; 1225 } 1226 return false; 1227 } 1228 1229 public String getPropertyTag() { 1230 return (this.getTableName() + "." + this.getName()).toLowerCase(); 1231 } 1232 1233 public String getDefaultRules() { 1234 String rule = ""; 1235 rule = this.getNullable() == 0 && !this.isPrimaryKey() ? rule + " nullnotallowed" : rule + " nullallowed"; 1236 if (this.getType() == 91 || this.getType() == 93) { 1237 rule = rule + " dateformat"; 1238 } 1239 return rule; 1240 } 1241 1242 public boolean getDefaultIncludeFor(String webElement) { 1243 return true; 1244 } 1245 1246 private static final String EMPTY_STRING = ""; 1247 /** 1248 * 生成缺省值字符串 1249 * @param nullInstead 指示{@link #defaultValue}为 {@code null}时是否用字符串'null'代替 1250 * @return 1251 */ 1252 public String getDefaultValue(boolean nullInstead) { 1253 String empty = nullInstead?"null":EMPTY_STRING; 1254 if(!CodeWriter.getPropertyBoolean("codewriter.generate.defaultvalue")){ 1255 return empty; 1256 } 1257 if (null != this.defaultValue) { 1258 if (this.isColumnNumeric()) { 1259 try { 1260 double value = Double.parseDouble(this.defaultValue); 1261 switch (this.getMappedType()) { 1262 case M_BIGDECIMAL : 1263 case M_INTEGER : 1264 case M_LONG : { 1265 return this.generateNewNumeric(this.getJavaType(), this.defaultValue); 1266 } 1267 case M_DOUBLE : 1268 case M_FLOAT : { 1269 return this.generateNewNumeric(this.getJavaType(), String.valueOf(value)); 1270 } 1271 } 1272 return empty; 1273 } catch (NumberFormatException nfe) { 1274 return empty; 1275 } 1276 } 1277 if (this.isDate()) { 1278 try { 1279 return generateDateDefaultValue(this.getJavaType(),this.defaultValue); 1280 } catch (IllegalArgumentException pe) { 1281 return empty; 1282 } 1283 } 1284 if (this.isString()) { 1285 return "\"" + this.defaultValue + '\"'; 1286 } 1287 if (M_BOOLEAN == this.getMappedType()) { 1288 return "Boolean.valueOf(\"" + ("1".equals(this.defaultValue) ? "true" : "false") 1289 + "\").booleanValue()"; 1290 } 1291 } 1292 return this.defaultValue == null ? empty : this.defaultValue; 1293 } 1294 /** 兼容之前版本 */ 1295 public String getDefaultValue() { 1296 return getDefaultValue(false); 1297 } 1298 /** 返回{@link #defaultValue}原始值 */ 1299 public String getOriginalDefaultValue(){ 1300 return this.defaultValue; 1301 } 1302 /** SQL 类型日期字符串转为java 日期对象 */ 1303 private static Date parseSqlDate(String source){ 1304 if(null == source) 1305 throw new IllegalArgumentException(); 1306 try{ 1307 return java.sql.Date.valueOf(source); 1308 }catch(IllegalArgumentException e){ 1309 try{ 1310 return java.sql.Time.valueOf(source); 1311 }catch(IllegalArgumentException e2){ 1312 return java.sql.Timestamp.valueOf(source); 1313 } 1314 } 1315 } 1316 /** 生成日期类型缺省值语句 */ 1317 private String generateDateDefaultValue(String type, String parameter) { 1318 StringBuffer sb = new StringBuffer(100); 1319 Date parsedDate = parseSqlDate(parameter); 1320 String dateStr; 1321 switch(this.getMappedType()){ 1322 case M_UTILDATE:{ 1323 String instanceName=""; 1324 if(parsedDate instanceof java.sql.Date){ 1325 instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd\")"; 1326 }else if(parsedDate instanceof java.sql.Time){ 1327 instanceName = "new java.text.SimpleDateFormat(\"HH:mm:ss\")"; 1328 }else if(parsedDate instanceof java.sql.Timestamp){ 1329 instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\")"; 1330 }else{ 1331 throw new IllegalStateException("invalid type"); 1332 } 1333 sb.append(instanceName).append(".parse(\"").append(parsedDate.toString()).append("\",new java.text.ParsePosition(0))"); 1334 break; 1335 } 1336 case M_SQLDATE:{ 1337 dateStr = new java.sql.Date(parsedDate.getTime()).toString(); 1338 sb.append(type).append(".valueOf(\"").append(dateStr).append("\")"); 1339 break; 1340 } 1341 case M_TIME:{ 1342 dateStr = new java.sql.Time(parsedDate.getTime()).toString(); 1343 sb.append(type).append(".valueOf(\"").append(dateStr).append("\")"); 1344 break; 1345 } 1346 case M_TIMESTAMP:{ 1347 dateStr = new java.sql.Timestamp(parsedDate.getTime()).toString(); 1348 sb.append(type).append(".valueOf(\"").append(dateStr).append("\")"); 1349 break; 1350 } 1351 default: 1352 return EMPTY_STRING; 1353 } 1354 return sb.toString(); 1355 } 1356 1357 private String generateNewNumeric(String type, String parameter) { 1358 StringBuffer sb = new StringBuffer(70); 1359 sb.append("new ").append(type); 1360 sb.append('(').append(parameter).append(')'); 1361 return sb.toString(); 1362 } 1363 1364 /** 生成缺省值({@link #defaultValue})的注释信息 */ 1365 public String commentOfDefaultValue(){ 1366 return Strings.isNullOrEmpty(defaultValue)?EMPTY_STRING: "/* DEFAULT:'"+defaultValue+"'*/"; 1367 } 1368 /** 生成缺省值赋值语句 */ 1369 public String getDefaultValueAssignment(boolean nullInstead){ 1370 StringBuffer buffer = new StringBuffer(); 1371 String value = getDefaultValue(nullInstead); 1372 if(!value.isEmpty()) 1373 buffer.append(" = ").append(value); 1374 return buffer.toString(); 1375 } 1376 public String getRemarks() { 1377 return this.remarks == null ? "" : this.remarks; 1378 } 1379 1380 public String getJavaName() { 1381 return this.convertName(this.getName()); 1382 } 1383 1384 public String getSampleData() { 1385 if (this.getNullable() > 1 && rand.nextInt(20) == 10) { 1386 return ""; 1387 } 1388 if (this.isColumnNumeric()) { 1389 return "" + rand.nextInt(100); 1390 } 1391 if (this.isDate()) { 1392 Calendar rightNow = Calendar.getInstance(); 1393 rightNow.set(2000 + rand.nextInt(20), 1 + rand.nextInt(12), 1 + rand.nextInt(28), rand.nextInt(23), 1394 rand.nextInt(60), rand.nextInt(60)); 1395 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 1396 return dateFormat.format(rightNow.getTime()); 1397 } 1398 return StringUtilities.getSampleString((int) this.getSize()); 1399 } 1400 1401 private String escape(String s) { 1402 return StringUtilities.escape((String) s); 1403 } 1404 1405 private String escape() { 1406 return this.escape(this.getName()); 1407 } 1408 1409 public String convertName(String columnName) { 1410 return StringUtilities.convertName((String) columnName, true); 1411 } 1412 1413 public String convertName(Column col) { 1414 return this.convertName(col.getName()); 1415 } 1416 1417 public String convertName() { 1418 return this.convertName(this.name); 1419 } 1420 1421 public String getImportedKeyVarName() { 1422 return this.convertName(this.escape() + "_collection"); 1423 } 1424 1425 public String getGetMethod() { 1426 return this.convertName("get_" + this.escape()); 1427 } 1428 1429 public String getSetMethod() { 1430 return this.convertName("set_" + this.escape()); 1431 } 1432 public String getReadMethod() { 1433 return this.convertName("read_" + this.escape()); 1434 } 1435 public String getWriteMethod() { 1436 return this.convertName("write_" + this.escape()); 1437 } 1438 public String getModifiedMethod() { 1439 return this.convertName("check_" + this.escape() + "_modified"); 1440 } 1441 1442 public String getInitializedMethod() { 1443 return this.convertName("check_" + this.escape() + "_initialized"); 1444 } 1445 public String getGetCacheMethod() { 1446 return this.convertName("get_bean_by_" + this.escape()); 1447 } 1448 public String getPutCacheMethod() { 1449 return this.convertName("put_by_" + this.escape()); 1450 } 1451 public String getPutIfAbsentCacheMethod() { 1452 return this.convertName("put_If_absent_by_" + this.escape()); 1453 } 1454 public String getReplaceCacheMethod() { 1455 return this.convertName("replace_by_" + this.escape()); 1456 } 1457 1458 public String bitAndExpression(String varName){ 1459 if(this.getTable().countColumns()>32){ 1460 int pos = getOrdinalPosition()-1; 1461 return String.format("(%s[%d] & (1 << %d))",varName,pos>>6,pos & 0x3f); 1462 }else{ 1463 return String.format("(%s & %s)", varName,getIDMaskConstName()); 1464 } 1465 } 1466 1467 public String bitORAssignExpression(String varName){ 1468 if(this.getTable().countColumns()>32){ 1469 int pos = getOrdinalPosition()-1; 1470 return String.format("%s[%d] |= (1 << %d)",varName,pos>>6,pos & 0x3f); 1471 }else{ 1472 return String.format("%s |= %s", varName,getIDMaskConstName()); 1473 } 1474 } 1475 public String bitResetAssignExpression(String varName){ 1476 if(this.getTable().countColumns()>32){ 1477 int pos = getOrdinalPosition()-1; 1478 return String.format("%s[%d] &= (~(1 << %d))",varName,pos>>6,pos & 0x3f); 1479 }else{ 1480 return String.format("%s &= (~%s)", varName,getIDMaskConstName()); 1481 } 1482 } 1483 public String getWidgetMethod() { 1484 return this.convertName("get_" + this.escape() + "_widget"); 1485 } 1486 1487 public String getVarName() { 1488 return this.convertName(this.escape()); 1489 } 1490 public String getCacheVarName() { 1491 return this.convertName(this.escape() + "_cacher"); 1492 } 1493 public String getFullVarName() { 1494 return this.convertName(this.name +"_of_" + this.getTable().getBasename(true)); 1495 } 1496 public String getModifiedVarName() { 1497 return this.convertName(this.escape() + "_is_modified"); 1498 } 1499 1500 public String getInitializedVarName() { 1501 return this.convertName(this.escape() + "_is_initialized"); 1502 } 1503 1504 public String getImportedKeyModifiedVarName() { 1505 return this.convertName(this.escape() + "_collection_is_modified"); 1506 } 1507 1508 public String getImportedKeyInitializedVarName() { 1509 return this.convertName(this.escape() + "_collection_is_initialized"); 1510 } 1511 1512 public String getImportedKeyInitializedMethod() { 1513 return this.convertName("is_" + this.escape() + "_collection_initialized"); 1514 } 1515 1516 public String getImportedKeyGetMethod() { 1517 return this.convertName("get_" + this.escape() + "_collection"); 1518 } 1519 1520 public String getImportedKeyAddMethod() { 1521 return this.convertName("add_" + this.escape() + ""); 1522 } 1523 1524 public String getImportedKeySetMethod() { 1525 return this.convertName("set_" + this.escape() + "_collection"); 1526 } 1527 1528 public String getImportedKeyModifiedMethod() { 1529 return this.convertName("is_" + this.escape() + "_collection_modified"); 1530 } 1531 1532 public String getForeignKeyVarName() { 1533 return this.convertName(this.escape() + "_object"); 1534 } 1535 1536 public String getForeignKeyModifiedVarName() { 1537 return this.convertName(this.escape() + "_object_is_modified"); 1538 } 1539 1540 public String getForeignKeyInitializedVarName() { 1541 return this.convertName(this.escape() + "_object_is_initialized"); 1542 } 1543 1544 public String getForeignKeyInitializedMethod() { 1545 return this.convertName("is_" + this.escape() + "_object_initialized"); 1546 } 1547 1548 public String getForeignKeyGetMethod(String col) { 1549 return this.convertName("get_" + this.escape() + "_object"); 1550 } 1551 1552 public String getForeignKeySetMethod(String col) { 1553 return this.convertName("set_" + this.escape() + "_object"); 1554 } 1555 1556 public String getForeignKeyModifiedMethod(String col) { 1557 return this.convertName("is_" + this.escape() + "_object_modified"); 1558 } 1559 1560 public String getTypeName() { 1561 return this.typeName; 1562 } 1563 1564 public void setTypeName(String typeName) { 1565 this.typeName = typeName; 1566 } 1567 1568 public int compareTo(Column obj) { 1569 return this.ordinal - obj.ordinal; 1570 } 1571 1572 public String getAutoincrement() { 1573 return autoincrement; 1574 } 1575 1576 public void setAutoincrement(String autoincrement) { 1577 this.autoincrement = autoincrement; 1578 } 1579 public boolean isAutoincrement(){ 1580 return "YES".equals(this.autoincrement); 1581 } 1582 public boolean isNotNull(){ 1583 return DatabaseMetaData.columnNoNulls == this.nullable ; 1584 } 1585 1586 private static final String IV_PREFIX = "invalidvalue."; 1587 private static final String IV_NUMBER = IV_PREFIX + "number"; 1588 private static final String IV_DATE = IV_PREFIX + "date"; 1589 private static final String PA_PREFIX = "prealloc."; 1590 private static final String PA_STRING = PA_PREFIX + "string.limit"; 1591 private static final String PA_BINARY = PA_PREFIX + "binary.limit"; 1592 private String getCustomInvalidValueAnn(){ 1593 String iv = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName()); 1594 if(iv != null){ 1595 return String.format("@CodegenInvalidValue(\"%s\")",iv); 1596 } 1597 String exp = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName()+".exp" ); 1598 if(exp != null){ 1599 return String.format("@CodegenInvalidValue(exp=\"%s\")",exp); 1600 } 1601 return null; 1602 } 1603 public String getInvalidValueAnn(){ 1604 if(invalidValueAnn == null){ 1605 synchronized (this) { 1606 if(invalidValueAnn == null){ 1607 invalidValueAnn = getCustomInvalidValueAnn(); 1608 if(invalidValueAnn == null){ 1609 if(isAutoincrement() || (getForeignKeys().size() ==1 && getForeignColumn().isAutoincrement())){ 1610 invalidValueAnn = "@CodegenInvalidValue(\"0\")"; 1611 } else if(isString()){ 1612 // 空字符串为无效值 1613 invalidValueAnn = "@CodegenInvalidValue"; 1614 } else if(isBinary()){ 1615 // 空数组为无效值 1616 invalidValueAnn = "@CodegenInvalidValue"; 1617 } else if(isColumnNumeric()){ 1618 String iv = CodeWriter.getProperty(IV_NUMBER , "-1"); 1619 invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")"; 1620 } else if(isDate()){ 1621 String iv = CodeWriter.getProperty(IV_DATE , "0"); 1622 invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")"; 1623 }else { 1624 invalidValueAnn = ""; 1625 } 1626 } 1627 } 1628 } 1629 } 1630 return invalidValueAnn; 1631 } 1632 1633 private boolean isPreAlloc0(){ 1634 if(TypeToken.of(getJavaClass()).isPrimitive()){ 1635 return true; 1636 } 1637 String columns = CodeWriter.getProperty(PA_PREFIX + ".table." + getTableName()); 1638 if(columns != null){ 1639 if( MiscellaneousUtils.elementsOf(columns).contains(getName())){ 1640 return true; 1641 } 1642 } 1643 if(isString()){ 1644 return getSize() <= CodeWriter.getPropertyInteger(PA_STRING); 1645 } 1646 if(isBinary()){ 1647 return getSize() <= CodeWriter.getPropertyInteger(PA_BINARY); 1648 } 1649 return false; 1650 } 1651 public boolean isPreAlloc(){ 1652 if(preAlloc == null){ 1653 synchronized (this) { 1654 if(preAlloc == null){ 1655 preAlloc = isPreAlloc0(); 1656 } 1657 } 1658 } 1659 return preAlloc; 1660 } 1661 1662}