rapid-generator代码生成器实战篇

背景

平时业务需求开发,经常面临的枯燥而又机械的创建各种实体类,写一些无脑的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;
      }
   }
}

大体上写法就这样的,我把以前我写的模板和配置文件放上去了,小伙伴们可以随意下载,根据自己项目修改模版。

模版和配置下载地方,如果有需要帮忙定制的也可以联系我哟

  • 30
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Mybatis-Plus Generator是一个非常强大的代码生成器工具,可以帮助开发人员快速生成基于Mybatis-Plus框架的CRUD代码。 下面是一个Mybatis-Plus Generator 3.5.1的实例: 首先,需要在pom.xml文件中添加相应的依赖: ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> </dependency> ``` 然后,在项目的配置文件(如application.properties或application.yml)中配置数据库连接信息: ``` spring.datasource.url=jdbc:mysql://localhost:3306/my_database spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 接下来,创建一个GeneratorConfig类,并在其中进行相应的配置: ```java public class GeneratorConfig { public static void main(String[] args) { // 代码生成器 AutoGenerator autoGenerator = new AutoGenerator(); // 全局配置 GlobalConfig globalConfig = new GlobalConfig(); String outputDir = System.getProperty("user.dir") + "/src/main/java"; globalConfig.setOutputDir(outputDir); globalConfig.setAuthor("your_name"); globalConfig.setOpen(false); autoGenerator.setGlobalConfig(globalConfig); // 数据源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/my_database"); dataSourceConfig.setUsername("root"); dataSourceConfig.setPassword("123456"); dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver"); autoGenerator.setDataSource(dataSourceConfig); // 包配置 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.example"); autoGenerator.setPackageInfo(packageConfig); // 策略配置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setNaming(NamingStrategy.underline_to_camel); strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); strategyConfig.setRestControllerStyle(true); autoGenerator.setStrategy(strategyConfig); // 执行代码生成器 autoGenerator.execute(); } } ``` 最后,运行GeneratorConfig类中的main方法,即可生成相应的实体类、Mapper接口、Service接口以及Controller类。 这样,使用Mybatis-Plus Generator 3.5.1代码生成器,我们可以快速生成与数据库表对应的Java代码,省去了手写的繁琐工作,提高了开发效率。使用起来非常方便,适用于大部分的项目开发。 ### 回答2: Mybatis-Plus是基于Mybatis的增强工具,可以简化开发过程中对数据库的操作。其中,Mybatis-Plus Generator是一款代码生成器,可以根据数据库表结构自动生成Java实体类、Mapper接口以及XML映射文件。 Mybatis-Plus Generator 3.5.1版本是最新发布的版本,具有一些新的特性和优化,可以更加方便、快捷地生成代码。下面以一个示例来说明如何使用这个代码生成器: 首先,我们需要在项目的pom.xml文件中添加Mybatis-Plus Generator的依赖: ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> </dependency> ``` 然后,我们需要在项目的配置文件中配置数据库连接信息、生成代码的包名等相关配置: ``` mybatis-plus: # 数据库连接信息 datasource: url: jdbc:mysql://localhost:3306/testdb username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # 生成代码的包名 global-config: output-dir: src/main/java author: your_name open: false entity-name: %sEntity mapper-name: %sMapper xml-name: %sMapper service-name: %sService service-impl-name: %sServiceImpl controller-name: %sController ``` 接下来,我们可以使用Mybatis-Plus Generator提供的工具类进行代码生成。可以通过以下方式调用: ``` AutoGenerator generator = new AutoGenerator(); // 设置全局配置 generator.setGlobalConfig(config); // 设置数据源配置 generator.setDataSource(dataSourceConfig); // 设置包名配置 generator.setPackageInfo(packageConfig); // 设置策略配置 generator.setStrategy(strategyConfig); // 执行生成 generator.execute(); ``` 最后,执行代码生成命令,即可完成代码的自动生成。生成的代码会按照配置的包名和格式生成在指定目录下。 通过使用Mybatis-Plus Generator 3.5.1代码生成器,我们可以简化开发过程中的手动编写实体类、Mapper接口和XML映射文件的工作量,提高开发效率。同时,它也提供了丰富的配置选项,可以根据具体项目的需求进行定制,生成符合项目要求的代码。 ### 回答3: mybatis-plus-generator是MyBatis-Plus框架中的一个代码生成器工具,可以根据数据库表结构自动生成对应的实体类、Mapper接口、Service接口以及ServiceImpl类等代码。以下是一个使用mybatis-plus-generator 3.5.1生成代码的示例: 1. 首先,需要在项目的pom.xml文件中添加mybatis-plus-generator的依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> </dependency> ``` 2. 创建一个配置类,设置代码生成所需的参数,如数据库连接信息、代码输出路径、包名等等。例如: ```java public class GeneratorConfig { public static void main(String[] args) { // 数据源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis_test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai"); dataSourceConfig.setDriverName("com.mysql.jdbc.Driver"); dataSourceConfig.setUsername("root"); dataSourceConfig.setPassword("password"); // 代码生成器配置 AutoGenerator autoGenerator = new AutoGenerator(); autoGenerator.setDataSource(dataSourceConfig); autoGenerator.setGlobalConfig(new GlobalConfig().setOutputDir("D:/code").setAuthor("mybatis-plus-generator").setOpen(false)); autoGenerator.setPackageInfo(new PackageConfig().setParent("com.example.demo").setModuleName("entity")); autoGenerator.setStrategy(new StrategyConfig().setNaming(NamingStrategy.underline_to_camel).setColumnNaming(NamingStrategy.underline_to_camel)); // 执行生成代码 autoGenerator.execute(); } } ``` 3. 运行配置类的main方法即可生成代码,生成的代码将会按照设置的路径和包名进行输出。 总的来说,使用mybatis-plus-generator能够大大加速开发过程,减少手写代码的工作量,提高项目代码的一致性和规范性。而3.5.1版本是mybatis-plus-generator的一个较新的版本,一般来说,较新的版本往往修复了一些bug并提供了更好的性能和功能。因此,推荐使用mybatis-plus-generator 3.5.1来进行代码生成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值