背景
平时业务需求开发,经常面临的枯燥而又机械的创建各种实体类,写一些无脑的CRUD,还要对着数据库给实体类添加注解和注释,接口使用的实体类还要写参数效验,前端调用后端还要对着接口文档写请求地址,请求参数,返回内容还需要接收处理等等还有很多无脑操作的工作,既浪费时间又没啥营养。于是我们可以把这些有一定规则的代码让他自动生成,这样我们就可以专注业务或技术点来写代码了,摆脱无脑和机械的操作。废话不多说,上干货。
搭建
下面是maven项目为例介绍的,别的项目也支持,不过操作上有少许不同。
需要创建maven项目或在已有项目中添加包引用
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> <dependency> <groupId>com.googlecode.rapid-framework</groupId> <artifactId>rapid-generator</artifactId> <version>4.0.6</version> </dependency> <!-- https://mvnrepository.com/artifact/com.googlecode.rapid-framework/rapid-generator-ext --> <dependency> <groupId>com.googlecode.rapid-framework</groupId> <artifactId>rapid-generator-ext</artifactId> <version>4.0.6</version> </dependency> <!-- https://mvnrepository.com/artifact/com.googlecode.rapid-framework/rapid-generator-template --> <dependency> <groupId>com.googlecode.rapid-framework</groupId> <artifactId>rapid-generator-template</artifactId> <version>4.0.6</version> <scope>test</scope> </dependency>
然后添加配置文件generator.xml,一下几点需要自己配置
1.如果是别的数据库连接,自行替换注释,
2.数据类型和java实体类字段类型映射关系也需要自己根据项目实际情况配置
3.代码生成的路径需要自己手动修改,我个人喜欢直接生成到目标项目的对应文件夹下,这样拷贝代码的动作也可以省略了。
4.配置项目的上级包路径。
下面以MySQL为例,展示的配置信息
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment> 代码生成器配置文件: 1.会为所有的property生成property_dir属性,如pkg=com.company => pkg_dir=com/company 2.可以引用环境变量: ${env.JAVA_HOME} or System.properties: ${user.home},property之间也可以相互引用 </comment> <entry key="jdbc_url">jdbc:mysql://10.1.128.22:3306?useInformationSchema=true</entry> <entry key="jdbc_catalog">maintenance_dev</entry> <!-- <entry key="outRoot">D:\pro\src\main\resources\output</entry>--> <entry key="outRoot">changan-ev-domain-maintenance-provider\src\main\java\com\changan\ev\maintenance</entry> <entry key="author">caohu</entry> <entry key="basepackage">com.changan.ev.maintenance</entry> <!-- jsp namespace: web/${namespace}/${table.className}/list.jsp --> <entry key="namespace">pages</entry> <!-- 对应修改下Constants.Mybatis.NAMESPACE_PREFIX --> <entry key="namespace_prefix">com.changan.ev.entity</entry> <!-- 需要移除的表名前缀,使用逗号进行分隔多个前缀,示例值: t_,v_ --> <entry key="tableRemovePrefixes"></entry> <entry key="jdbc_username">changanev_dev</entry> <entry key="jdbc_password">fO3aX7pB3nI3uH3kC5fY2gE8</entry> <!-- oracle需要指定jdbc.schema,其它数据库忽略此项配置 --> <entry key="jdbc_schema"></entry> <!-- 数据库类型映射 --> <entry key="java_typemapping.java.sql.Timestamp">java.util.Date</entry> <entry key="java_typemapping.java.sql.Date">java.util.Date</entry> <entry key="java_typemapping.java.sql.Time">java.util.Date</entry> <entry key="java_typemapping.java.lang.Byte">Integer</entry> <entry key="java_typemapping.java.lang.Short">Integer</entry> <!-- <entry key="java_typemapping.java.math.BigDecimal">Long</entry>--> <!-- H2 --> <!-- <entry key="jdbc.url">jdbc:h2:tcp://localhost/test</entry> <entry key="jdbc.driver">org.h2.Driver</entry> --> <entry key="jdbc_driver">com.mysql.cj.jdbc.Driver</entry> <!-- Oracle jdbc:oracle:oci:@tnsname_devdb <entry key="jdbc.url">jdbc:oracle:thin:@192.168.0.177:1521:[sid]</entry> <entry key="jdbc.driver">oracle.jdbc.driver.OracleDriver</entry> --> <!-- SQLServer2000 <entry key="jdbc.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=[database]</entry> <entry key="jdbc.driver">com.microsoft.jdbc.sqlserver.SQLServerDriver</entry> --> <!-- SQLServer2005 <entry key="jdbc.url">jdbc:sqlserver://192.168.0.98:1433;DatabaseName=[database]</entry> <entry key="jdbc.driver">com.microsoft.sqlserver.jdbc.SQLServerDriver</entry> --> <!-- JTDs for SQLServer <entry key="jdbc.url">jdbc:jtds:sqlserver://192.168.0.102:1433/[database];tds=8.0;lastupdatecount=true</entry> <entry key="jdbc.driver">net.sourceforge.jtds.jdbc.Driver</entry> --> <!-- PostgreSql <entry key="jdbc.url">jdbc:postgresql://localhost/[database]</entry> <entry key="jdbc.driver">org.postgresql.Driver</entry> --> <!-- Sybase <entry key="jdbc.url">jdbc:sybase:Tds:localhost:5007/[database]</entry> <entry key="jdbc.driver">com.sybase.jdbc.SybDriver</entry> --> <!-- DB2 <entry key="jdbc.url">jdbc:db2://localhost:5000/[database]</entry> <entry key="jdbc.driver">com.ibm.db2.jdbc.app.DB2Driver</entry> --> <!-- HsqlDB <entry key="jdbc.url">jdbc:hsqldb:mem:generatorDB</entry> <entry key="jdbc.driver">org.hsqldb.jdbcDriver</entry> --> <!-- Derby <entry key="jdbc.url">jdbc:derby://localhost/databaseName</entry> <entry key="jdbc.driver">org.apache.derby.jdbc.ClientDriver</entry> --> </properties>
ps:小伙伴注意啦,数据库类型映射时候,有的小伙伴喜欢用int存放枚举,长度也设置为1,然后用我搭建的代码生成生成了代码,发现字段类型不是他想要的,于是说我弄的代码生成器有问题,生成的字段类型都错了,我想说的是在MySQL中这样操作是错误,首先如果确实想实体类是int类型存放,数据库用tinyint比用int更节约磁盘空间,然后MySQL中的数字类型的长度不是控制他能存储几位,例如int(1)时候,值可以是1001,或更大的值,int(1)并不能控制他存储的不能超过一位的值,int长度可以配合ZEROFILL来自动填充,比如int(6)存储的值可能是006100。数字类型长度给1,java字段类型就会转换成boolean类型的。另外在提示一个小技巧,想让生成的java字段类型是bolean,可以考虑tinyint(1),这写法虽然MySQL中1的长度不影响他存储超过1位的值,但是字段映射却可以生成boolean类型。
添加运行入口:
import cn.org.rapid_framework.generator.GeneratorFacade; /** * * @author caohu * @date 2019-07-31 22:27:05 * */ public class CodeGenerator { public static void main(String[] args) throws Exception { // ${table.classNameFirstLower} sysGame // ${table.className} SysGame // ${table} // 模板地址 String templatePath = "classpath:template"; GeneratorFacade g = new GeneratorFacade(); g.getGenerator().addTemplateRootDir(templatePath); // 删除生成器的输出目录// // g.deleteOutRootDir(); // 通过数据库表生成文件 // g.generateByTable("housekeeper_error"); g.generateByTable("housekeeper_error"); // 自动搜索数据库中的所有表并生成文件,template为模板的根目录 // g.generateByAllTable(); // 按table名字删除文件 // g.deleteByTable("table_name", "template"); // 打开文件夹 // Runtime.getRuntime().exec("cmd.exe /c start // "+GeneratorProperties.getRequiredProperty("outRoot")); } }
模板编写
最后就剩下最关键最消耗时间的事了,自然就是根据项目情况编写模板。
这里模板是用freemarker进行编写的,模版不限于生成的语言,框架,这项目前端界面千奇百怪的,于是这样例中我并没有编写前端模板,需要或多或少了解下freemarker的语法,下面就是我曾今在项目中写的新增修改接口用的入参实体类,以这为例,介绍下写法
这里能看到自动生成字段时候需要排除一些框架自动处理的字段,逻辑删除标识,创建人,修改人,创建时间,修改时间,版本号(默认版本号不处理,需要做并发控制时候,手动添加这字段)不需要处理,这就让这些字段不生成。
<#assign ignoreColumn = ["isDeleted", "createdBy", "updatedBy", "createdTime", "updatedTime", "reversion"]> <#list table.columns as column> <#if !ignoreColumn?seq_contains(column.columnNameLower) >
对参数效验,全部根据数据库设置的来控制,整数类型的需要手动设置长度限制,其余的自动生成长度限制,数据库非空控制直接生成参数的非空效验
<#if column.sqlTypeName == "BigDecimal"> @DecimalMax(value = "${column.size}", message = "${column.columnAlias!}不能超过") </#if> <#if column.sqlTypeName == "VARCHAR"> @Size( max = ${column.size}, message = "${column.columnAlias!}不能超过${column.size}位") </#if> <#if column.nullable == false> <#if column.sqlTypeName == "String"> @NotBlank(message = "${column.columnAlias!}不能为空") <#else> @NotNull(message = "${column.columnAlias!}不能为空") </#if> </#if>
还有就是时间格式转换
<#if column.simpleJavaType == "Date"> @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") </#if>
最后,根据类型自动导包
<#list table.columns as column> <#if column.simpleJavaType == "Date" && importDate == 0> <#assign importDate = 1> import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; </#if> <#if column.simpleJavaType == "BigDecimal" && importDecimal == 0> <#assign importDecimal = 1> import java.math.BigDecimal; </#if> </#list>
最后为了方便大家编写模板,我把rapid-generator关键地方的源码截图出来,小伙伴们可以根据这些源码获取自己想要的数据
首先是table:
public class Table implements java.io.Serializable,Cloneable { String sqlName; String remarks; String className; /** the name of the owner of the synonym if this table is a synonym */ private String ownerSynonymName = null; /** real table name for oracle SYNONYM */ private String tableSynonymName = null; ColumnSet columns = new ColumnSet(); List<Column> primaryKeyColumns = new ArrayList<Column>(); public Table() {} public Table(Table t) { setSqlName(t.getSqlName()); this.remarks = t.getRemarks(); this.className = t.getClassName(); this.ownerSynonymName = t.getOwnerSynonymName(); setColumns(t.getColumns()); this.primaryKeyColumns = t.getPrimaryKeyColumns(); this.tableAlias = t.getTableAlias(); this.exportedKeys = t.exportedKeys; this.importedKeys = t.importedKeys; } public LinkedHashSet<Column> getColumns() { return columns.getColumns(); } public void setColumns(LinkedHashSet<Column> columns) { this.columns.setColumns(columns); } public String getOwnerSynonymName() { return ownerSynonymName; } public void setOwnerSynonymName(String ownerSynonymName) { this.ownerSynonymName = ownerSynonymName; } public String getTableSynonymName() { return tableSynonymName; } public void setTableSynonymName(String tableSynonymName) { this.tableSynonymName = tableSynonymName; } /** 使用 getPkColumns() 替换*/ @Deprecated public List<Column> getPrimaryKeyColumns() { return primaryKeyColumns; } /** 使用 setPkColumns() 替换*/ @Deprecated public void setPrimaryKeyColumns(List<Column> primaryKeyColumns) { this.primaryKeyColumns = primaryKeyColumns; } /** 数据库中表的表名称,其它属性很多都是根据此属性派生 */ public String getSqlName() { return sqlName; } public void setSqlName(String sqlName) { this.sqlName = sqlName; } /** 数据库中表的表备注 */ public String getRemarks() { return remarks; } public void setRemarks(String remarks) { this.remarks = remarks; } public void addColumn(Column column) { columns.addColumn(column); } public void setClassName(String customClassName) { this.className = customClassName; } /** * 根据sqlName得到的类名称,示例值: UserInfo * @return */ public String getClassName() { if(StringHelper.isBlank(className)) { return StringHelper.toJavaClassName(sqlName); }else { return className; } } /** 数据库中表的别名,等价于: getRemarks().isEmpty() ? getClassName() : getRemarks() */ public String getTableAlias() { if(StringHelper.isNotBlank(tableAlias)) return tableAlias; return StringHelper.removeCrlf(StringHelper.defaultIfEmpty(getRemarks(), getClassName())); } public void setTableAlias(String v) { this.tableAlias = v; } /** * 等价于getClassName().toLowerCase() * @return */ public String getClassNameLowerCase() { return getClassName().toLowerCase(); } /** * 得到用下划线分隔的类名称,如className=UserInfo,则underscoreName=user_info * @return */ public String getUnderscoreName() { return StringHelper.toUnderscoreName(getClassName()).toLowerCase(); } /** * 返回值为getClassName()的第一个字母小写,如className=UserInfo,则ClassNameFirstLower=userInfo * @return */ public String getClassNameFirstLower() { return StringHelper.uncapitalize(getClassName()); } /** * 根据getClassName()计算而来,用于得到常量名,如className=UserInfo,则constantName=USER_INFO * @return */ public String getConstantName() { return StringHelper.toUnderscoreName(getClassName()).toUpperCase(); } /** 使用 getPkCount() 替换*/ @Deprecated public boolean isSingleId() { return getPkCount() == 1 ? true : false; } /** 使用 getPkCount() 替换*/ @Deprecated public boolean isCompositeId() { return getPkCount() > 1 ? true : false; } /** 使用 getPkCount() 替换*/ @Deprecated public boolean isNotCompositeId() { return !isCompositeId(); } /** * 得到主键总数 * @return */ public int getPkCount() { return columns.getPkCount(); } /** * use getPkColumns() * @deprecated */ public List getCompositeIdColumns() { return getPkColumns(); } /** * 得到是主键的全部column * @return */ public List<Column> getPkColumns() { return columns.getPkColumns(); } /** * 得到不是主键的全部column * @return */ public List<Column> getNotPkColumns() { return columns.getNotPkColumns(); } /** 得到单主键,等价于getPkColumns().get(0) */ public Column getPkColumn() { Column c = columns.getPkColumn(); if(c == null) { throw new IllegalStateException("not found primary key on table:"+getSqlName()); } return c; } /**使用 getPkColumn()替换 */ @Deprecated public Column getIdColumn() { return getPkColumn(); } public List<Column> getEnumColumns() { return columns.getEnumColumns(); } public Column getColumnByName(String name) { return columns.getByName(name); } public Column getColumnBySqlName(String sqlName) { return columns.getBySqlName(sqlName); } public Column getRequiredColumnBySqlName(String sqlName) { if(getColumnBySqlName(sqlName) == null) { throw new IllegalArgumentException("not found column with sqlName:"+sqlName+" on table:"+getSqlName()); } return getColumnBySqlName(sqlName); } /** * 忽略过滤掉某些关键字的列,关键字不区分大小写,以逗号分隔 * @param ignoreKeywords * @return */ public List<Column> getIgnoreKeywordsColumns(String ignoreKeywords) { List results = new ArrayList(); for(Column c : getColumns()) { String sqlname = c.getSqlName().toLowerCase(); if(StringHelper.contains(sqlname,ignoreKeywords.split(","))) { continue; } results.add(c); } return results; } /** * This method was created in VisualAge. */ public void initImportedKeys(DatabaseMetaData dbmd) throws java.sql.SQLException { // get imported keys a ResultSet fkeys = dbmd.getImportedKeys(catalog,schema,this.sqlName); while ( fkeys.next()) { String pktable = fkeys.getString(PKTABLE_NAME); String pkcol = fkeys.getString(PKCOLUMN_NAME); String fktable = fkeys.getString(FKTABLE_NAME); String fkcol = fkeys.getString(FKCOLUMN_NAME); String seq = fkeys.getString(KEY_SEQ); Integer iseq = new Integer(seq); getImportedKeys().addForeignKey(pktable,pkcol,fkcol,iseq); } fkeys.close(); } /** * This method was created in VisualAge. */ public void initExportedKeys(DatabaseMetaData dbmd) throws java.sql.SQLException { // get Exported keys ResultSet fkeys = dbmd.getExportedKeys(catalog,schema,this.sqlName); while ( fkeys.next()) { String pktable = fkeys.getString(PKTABLE_NAME); String pkcol = fkeys.getString(PKCOLUMN_NAME); String fktable = fkeys.getString(FKTABLE_NAME); String fkcol = fkeys.getString(FKCOLUMN_NAME); String seq = fkeys.getString(KEY_SEQ); Integer iseq = new Integer(seq); getExportedKeys().addForeignKey(fktable,fkcol,pkcol,iseq); } fkeys.close(); } /** * @return Returns the exportedKeys. */ public ForeignKeys getExportedKeys() { if (exportedKeys == null) { exportedKeys = new ForeignKeys(this); } return exportedKeys; } /** * @return Returns the importedKeys. */ public ForeignKeys getImportedKeys() { if (importedKeys == null) { importedKeys = new ForeignKeys(this); } return importedKeys; } public String toString() { return "Database Table:"+getSqlName()+" to ClassName:"+getClassName(); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { //ignore return null; } } public void setSchema(String schema) { this.schema = schema; } public void setCatalog(String catalog) { this.catalog = catalog; } String catalog = null; String schema = null; private String tableAlias; private ForeignKeys exportedKeys; private ForeignKeys importedKeys; public static final String PKTABLE_NAME = "PKTABLE_NAME"; public static final String PKCOLUMN_NAME = "PKCOLUMN_NAME"; public static final String FKTABLE_NAME = "FKTABLE_NAME"; public static final String FKCOLUMN_NAME = "FKCOLUMN_NAME"; public static final String KEY_SEQ = "KEY_SEQ"; }
然后是column:
public class Column implements java.io.Serializable,Cloneable{ /** * Reference to the containing table */ private Table _table; /** * The java.sql.Types type */ private int _sqlType; /** * The sql typename. provided by JDBC driver */ private String _sqlTypeName; /** * The name of the column */ private String _sqlName; /** * True if the column is a primary key */ private boolean _isPk; /** * True if the column is a foreign key */ private boolean _isFk; /** * @todo-javadoc Describe the column */ private int _size; /** * @todo-javadoc Describe the column */ private int _decimalDigits; /** * True if the column is nullable */ private boolean _isNullable; /** * True if the column is indexed */ private boolean _isIndexed; /** * True if the column is unique */ private boolean _isUnique; /** * Null if the DB reports no default value */ private String _defaultValue; /** * The comments of column */ private String _remarks; /** * @param table * @param sqlType * @param sqlTypeName * @param sqlName * @param size * @param decimalDigits * @param isPk * @param isNullable * @param isIndexed * @param isUnique * @param defaultValue * @param remarks */ public Column(Table table, int sqlType, String sqlTypeName, String sqlName, int size, int decimalDigits, boolean isPk, boolean isNullable, boolean isIndexed, boolean isUnique, String defaultValue,String remarks) { if(sqlName == null) throw new NullPointerException("sqlName must be not null"); _table = table; _sqlType = sqlType; _sqlName = sqlName; _sqlTypeName = sqlTypeName; _size = size; _decimalDigits = decimalDigits; _isPk = isPk; _isNullable = isNullable; _isIndexed = isIndexed; _isUnique = isUnique; _defaultValue = defaultValue; _remarks = remarks; GLogger.trace(sqlName + " isPk -> " + _isPk); initOtherProperties(); } public Column(Column c) { this(c.getTable(), c.getSqlType(), c.getSqlTypeName(), c.getSqlName(), c.getSize(), c.getDecimalDigits(), c.isPk(), c.isNullable(), c.isIndexed(), c.isUnique(), c.getDefaultValue(), c.getRemarks()); } public Column() { } /** * Gets the SqlType attribute of the Column object * * @return The SqlType value */ public int getSqlType() { return _sqlType; } /** * Gets the Table attribute of the DbColumn object * * @return The Table value */ public Table getTable() { return _table; } /** * Gets the Size attribute of the DbColumn object * * @return The Size value */ public int getSize() { return _size; } /** * Gets the DecimalDigits attribute of the DbColumn object * * @return The DecimalDigits value */ public int getDecimalDigits() { return _decimalDigits; } /** * Gets the SqlTypeName attribute of the Column object * * @return The SqlTypeName value */ public String getSqlTypeName() { return _sqlTypeName; } /** * Gets the SqlName attribute of the Column object * * @return The SqlName value */ public String getSqlName() { if(_sqlName == null) throw new NullPointerException(); return _sqlName; } public void setSqlName(String v) { if(StringHelper.isBlank(v)) throw new IllegalArgumentException("sqlName must be not blank"); if(!v.equalsIgnoreCase(_sqlName)) { throw new IllegalArgumentException("cannot change property:sqlName value"); } this._sqlName = v; } /** * Gets the Pk attribute of the Column object * * @return The Pk value */ public boolean isPk() { return _isPk; } /** * Gets the Fk attribute of the Column object * * @return The Fk value */ public boolean isFk() { return _isFk; } /** * Gets the Nullable attribute of the Column object * * @return The Nullable value */ public boolean isNullable() { return _isNullable; } /** * Gets the Indexed attribute of the DbColumn object * * @return The Indexed value */ public boolean isIndexed() { return _isIndexed; } /** * Gets the Unique attribute of the DbColumn object * * @return The Unique value */ public boolean isUnique() { return _isUnique; } /** * Gets the DefaultValue attribute of the DbColumn object * * @return The DefaultValue value */ public String getDefaultValue() { return _defaultValue; } /** * 列的数据库备注 * @return */ public String getRemarks() { return _remarks; } public void setUpdatable(boolean updatable) { this.updatable = updatable; } public void setInsertable(boolean insertable) { this.insertable = insertable; } public void setNullable(boolean v) { this._isNullable = v; } public void setUnique(boolean unique) { _isUnique = unique; } public void setPk(boolean v) { this._isPk = v; } /** * Describe what the method does * * @return Describe the return value * @todo-javadoc Write javadocs for method * @todo-javadoc Write javadocs for return value */ public int hashCode() { if(getTable() != null) { return (getTable().getSqlName() + "#" + getSqlName()).hashCode(); }else { return (getSqlName()).hashCode(); } } /** * Describe what the method does * * @param o * Describe what the parameter does * @return Describe the return value * @todo-javadoc Write javadocs for method * @todo-javadoc Write javadocs for method parameter * @todo-javadoc Write javadocs for return value */ public boolean equals(Object o) { if(this == o) return true; if(o instanceof Column) { Column other = (Column)o; if(getSqlName().equals(other.getSqlName())) { return true; } } return false; } /** * Describe what the method does * * @return Describe the return value * @todo-javadoc Write javadocs for method * @todo-javadoc Write javadocs for return value */ public String toString() { return getSqlName(); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { //ignore return null; } } /** * Describe what the method does * * @return Describe the return value * @todo-javadoc Write javadocs for method * @todo-javadoc Write javadocs for return value */ protected String prefsPrefix() { return "tables/" + getTable().getSqlName() + "/columns/" + getSqlName(); } /** * Sets the Pk attribute of the DbColumn object * * @param flag * The new Pk value */ void setFk(boolean flag) { _isFk = flag; } public String getUnderscoreName() { return getSqlName().toLowerCase(); } /** * 根据列名,根据sqlName计算得出,示例值: BirthDate **/ public String getColumnName() { return columnName; } /** * 第一个字母小写的columName,等价于: StringHelper.uncapitalize(getColumnName()),示例值: birthDate **/ public String getColumnNameFirstLower() { return StringHelper.uncapitalize(getColumnName()); } /** * 全部小写的columName,等价于: getColumnName().toLowerCase(),示例值: birthdate **/ public String getColumnNameLowerCase() { return getColumnName().toLowerCase(); } /** * 使用 getColumnNameFirstLower()替换 * @deprecated use getColumnNameFirstLower() instead */ public String getColumnNameLower() { return getColumnNameFirstLower(); } /** * 得到 jdbcSqlType类型名称,示例值:VARCHAR,DECIMAL, 现Ibatis3使用该属性 */ public String getJdbcSqlTypeName() { return getJdbcType(); } /** * 得到 jdbcSqlType类型名称,示例值:VARCHAR,DECIMAL, 现Ibatis3使用该属性 */ public String getJdbcType() { String result = JdbcType.getJdbcSqlTypeName(getSqlType()); return result; } /** * 列的别名,等价于:getRemarks().isEmpty() ? getColumnNameFirstLower() : getRemarks() * * <br /> * 示例值: birthDate */ public String getColumnAlias() { return columnAlias; } /** * 列的常量名称 * * <br /> * 示例值: BIRTH_DATE */ public String getConstantName() { return StringHelper.toUnderscoreName(getColumnName()).toUpperCase(); } /** * * @deprecated */ public boolean getIsNotIdOrVersionField() { return !isPk(); } /**得到 rapid-validation的验证表达式: required min-value-800 */ public String getValidateString() { return isNullable() ? getNoRequiredValidateString() : "required " + getNoRequiredValidateString(); } /**得到 rapid-validation的验证表达式: min-value-800 */ public String getNoRequiredValidateString() { return ColumnHelper.getRapidValidation(this); } /** 得到JSR303 bean validation(Hibernate Validator)的验证表达式: @NotNull @Min(100) @Max(800) */ public String[] getHibernateValidatorConstraintNames() { return ColumnHelper.removeHibernateValidatorSpecialTags(getHibernateValidatorExprssion()); } /** 得到JSR303 bean validation(Hibernate Validator)的验证表达式: @NotNull @Min(100) @Max(800) */ public String getHibernateValidatorExprssion() { return hibernateValidatorExprssion; } public void setHibernateValidatorExprssion(String v) { hibernateValidatorExprssion = v; } /** 列是否是String类型 */ public boolean getIsStringColumn() { return DatabaseDataTypesUtils.isString(getJavaType()); } /** 列是否是日期类型 */ public boolean getIsDateTimeColumn() { return DatabaseDataTypesUtils.isDate(getJavaType()); } /** 列是否是Number类型 */ public boolean getIsNumberColumn() { return DatabaseDataTypesUtils.isFloatNumber(getJavaType()) || DatabaseDataTypesUtils.isIntegerNumber(getJavaType()); } /** 检查是否包含某些关键字,关键字以逗号分隔 */ public boolean contains(String keywords) { if(keywords == null) throw new IllegalArgumentException("'keywords' must be not null"); return StringHelper.contains(getSqlName(), keywords.split(",")); } public boolean isHtmlHidden() { return isPk() && _table.isSingleId(); } /** * 得到对应的javaType,如java.lang.String, * @return */ public String getJavaType() { return javaType; } /** * 得到简短的javaType的名称,如com.company.model.UserInfo,将返回 UserInfo * @return */ public String getSimpleJavaType() { return StringHelper.getJavaClassSimpleName(getJavaType()); } /** * 得到尽可能简短的javaType的名称,如果是java.lang.String,将返回String, 如com.company.model.UserInfo,将返回 com.company.model.UserInfo * @return */ public String getPossibleShortJavaType() { if(getJavaType().startsWith("java.lang.")) { return getSimpleJavaType(); }else { return getJavaType(); } } public boolean isPrimitive() { return JavaPrimitiveTypeMapping.getWrapperTypeOrNull(getJavaType()) != null; } /** * 得到原生类型的javaType,如java.lang.Integer将返回int,而非原生类型将直接返回getSimpleJavaType() * @return */ public String getPrimitiveJavaType() { return JavaPrimitiveTypeMapping.getPrimitiveType(getSimpleJavaType()); } /** * 得到原生类型的包装类型,如int将返回Integer,而非原生类型将直接返回getSimpleJavaType() * @return */ public String getWrappedJavaType() { return JavaPrimitiveTypeMapping.getWrapperType(getSimpleJavaType()); } /** 得到ActionScript的映射类型,用于Flex代码的生成 */ public String getAsType() { return asType; } /** 得到列的测试数据 */ public String getTestData() { return new TestDataGenerator().getDBUnitTestData(getColumnName(),getJavaType(),getSize()); } /** 列是否可以更新 */ public boolean isUpdatable() { return updatable; } /** 列是否可以插入 */ public boolean isInsertable() { return insertable; } /** 得到枚举(enum)的类名称,示例值:SexEnum */ public String getEnumClassName() { return enumClassName; } /** 枚举值,以分号分隔,示例值:M(1,男);F(0,女) 或者是:M(男);F(女) */ public void setEnumString(String str) { this.enumString = str; } /** 枚举值,以分号分隔,示例值:M(1,男);F(0,女) 或者是:M(男);F(女) */ public String getEnumString() { return enumString; } /** 解析getEnumString()字符串转换为List<EnumMetaDada>对象 */ public List<EnumMetaDada> getEnumList() { return StringHelper.string2EnumMetaData(getEnumString()); } /** 是否是枚举列,等价于:return getEnumList() != null && !getEnumList().isEmpty() */ public boolean isEnumColumn() { return getEnumList() != null && !getEnumList().isEmpty(); } public void setJavaType(String javaType) { this.javaType = javaType; } public void setColumnAlias(String columnAlias) { this.columnAlias = columnAlias; } public void setColumnName(String columnName) { this.columnName = columnName; } public void setAsType(String asType) { this.asType = asType; } public void setEnumClassName(String enumClassName) { this.enumClassName = enumClassName; } // public void setBelongsTo(String foreignKey) { // ReferenceKey ref = ReferenceKey.fromString(foreignKey); // if(ref != null && _table != null) { // _table.getImportedKeys().addForeignKey(ref.tableName, ref.columnSqlName, getSqlName(), ref.columnSqlName.hashCode()); // } // } // // public void setHasAndBelongsToMany(String foreignKey) { // } private ReferenceKey hasOne; public String getHasOne() { return ReferenceKey.toString(hasOne); } /** nullValue for ibatis sqlmap: <result property="age" column="age" nullValue="0" /> */ public String getNullValue() { return JavaPrimitiveTypeMapping.getDefaultValue(getJavaType()); } public boolean isHasNullValue() { return JavaPrimitiveTypeMapping.getWrapperTypeOrNull(getJavaType()) != null; } /** * 设置many-to-one,foreignKey格式: fk_table_name(fk_column) 或者 schema_name.fk_table_name(fk_column) * @param foreignKey * @return */ public void setHasOne(String foreignKey) { hasOne = ReferenceKey.fromString(foreignKey); if(hasOne != null && _table != null) { // Table refTable = TableFactory.getInstance().getTable(hasOne.tableName); // _table.getImportedKeys().addForeignKey(refTable.getSqlName(), hasOne.columnSqlName, getSqlName(), hasOne.columnSqlName.toLowerCase().hashCode()); _table.getImportedKeys().addForeignKey(hasOne.tableName, hasOne.columnSqlName, getSqlName(), hasOne.columnSqlName.toLowerCase().hashCode()); } } private ReferenceKey hasMany = null; public String getHasMany() { return ReferenceKey.toString(hasMany); } /** * 设置one-to-many,foreignKey格式: fk_table_name(fk_column) 或者 schema_name.fk_table_name(fk_column) * @param foreignKey * @return */ public void setHasMany(String foreignKey) { hasMany = ReferenceKey.fromString(foreignKey); if(hasMany != null && _table != null) { // Table refTable = TableFactory.getInstance().getTable(hasMany.tableName); // _table.getExportedKeys().addForeignKey(refTable.getSqlName(), hasMany.columnSqlName, getSqlName(), hasMany.columnSqlName.toLowerCase().hashCode()); _table.getExportedKeys().addForeignKey(hasMany.tableName, hasMany.columnSqlName, getSqlName(), hasMany.columnSqlName.toLowerCase().hashCode()); } } private void initOtherProperties() { String normalJdbcJavaType = DatabaseDataTypesUtils.getPreferredJavaType(getSqlType(), getSize(), getDecimalDigits()); javaType = GeneratorProperties.getProperty("java_typemapping."+normalJdbcJavaType,normalJdbcJavaType).trim(); columnName = StringHelper.makeAllWordFirstLetterUpperCase(StringHelper.toUnderscoreName(getSqlName())); enumClassName = getColumnName()+"Enum"; asType = ActionScriptDataTypesUtils.getPreferredAsType(getJavaType()); columnAlias = StringHelper.removeCrlf(StringHelper.defaultIfEmpty(getRemarks(), getColumnNameFirstLower())); setHibernateValidatorExprssion(ColumnHelper.getHibernateValidatorExpression(this)); } /** 删除聚集函数的相关char,示例转换 count(*) => count, max(age) => max_age, sum(income) => sum_income */ public static String removeAggregationColumnChars(String columSqlName) { return columSqlName.replace('(', '_').replace(")", "").replace("*", ""); } private String enumString = ""; private String javaType; private String columnAlias; private String columnName; private String asType; private String enumClassName; private boolean updatable = true; private boolean insertable = true; private String hibernateValidatorExprssion; // private String rapidValidation; /** * public enum ${enumClassName} { * ${enumAlias}(${enumKey},${enumDesc}); * private String key; * private String value; * } * @author badqiu */ public static class EnumMetaDada { private String enumAlias; private String enumKey; private String enumDesc; public EnumMetaDada(String enumAlias, String enumKey, String enumDesc) { super(); this.enumAlias = enumAlias; this.enumKey = enumKey; this.enumDesc = enumDesc; } public String getEnumAlias() { return enumAlias; } public String getEnumKey() { return enumKey; } public String getEnumDesc() { return enumDesc; } } }
大体上写法就这样的,我把以前我写的模板和配置文件放上去了,小伙伴们可以随意下载,根据自己项目修改模版。
模版和配置下载地方,如果有需要帮忙定制的也可以联系我哟