代码自动生成(二)

来源:互联网 发布:剑灵天女捏脸图文数据 编辑:程序博客网 时间:2024/05/16 01:04

在上一篇文章  代码自动生成(一)中废了很多话,下面注解入正题:

首先定义列Col类,积累列中相应的信息,具体如下:

public class Col {  private Integer index;  private String name;  private String fieldName;  private String methodName;  private String desc;  private Type type;  private String default_;  private String isPK = "no";  private String allowNull = "no";  private Boolean hasNext = true;      /** 基本参数的构造 * @author hym * @time 2017年7月20日 下午7:37:27 * @param index * @param fieldName * @param type */public Col(Integer index,String fieldName,Type type){  this.index=index;  this.fieldName=fieldName;  this.type=type;  }  /**构造校验 * @author hym * @time 2017年7月22日 下午5:19:20 * @param tab * @param index * @param defs * @param isColMap */public Col(String tab, int index, List<Object> defs, Boolean isColMap) {    int size = defs.size();    this.index = index;    if (size < 2) {      throw new RuntimeException("表'" + tab + "'的第'" + index + "'字段没有定义字段名");    }    name = (String) defs.get(1);    if (name == null || name.trim().length() == 0) {      throw new RuntimeException("表'" + tab + "'的第'" + index + "'字段没有定义字段名");    }    desc = (String) defs.get(2);    if (size < 4) {      throw new RuntimeException("表'" + tab + "'的'" + name + "'字段没有定义类型");    }    String typeStr = (String) defs.get(3);    if (typeStr == null || typeStr.trim().length() == 0) {      throw new RuntimeException("表'" + tab + "'的'" + name + "'字段没有定义字类型");    }    typeStr = typeStr.trim().toLowerCase();    type = Type.get(typeStr);    if (type == null) {      throw new RuntimeException("表'" + tab + "'的'" + name + "'字段类型定义错误");    }    fieldName = format();    if (size >= 6) {      default_ = defs.get(5).toString().trim();      if (default_.length() == 0) {        default_ = null;      }    }    if (size >= 7) {      isPK = defs.get(6).toString().trim().toLowerCase();      if (isPK.length() == 0) {        isPK = "no";      }    }    if (size >= 8) {      allowNull = defs.get(7).toString().trim().toLowerCase();      if (allowNull.length() == 0) {        allowNull = "no";      }    }    if (isColMap) {      name = removeDBKeyword(name);    }  }  public Integer getIndex() {    return index;  }  public void setIndex(Integer index) {    this.index = index;  }  public String getName() {    return new StringBuffer(name).toString();  }  public String getFieldName() {    return fieldName;  }  public void setFieldName(String fieldName) {    this.fieldName = fieldName;  }  public String getMethodName() {    return methodName;  }  public void setMethodName(String methodName) {    this.methodName = methodName;  }  private String format() {    String _name = this.getName();    int idx = -1;    while ((idx = _name.indexOf("_")) != -1) {      String pre = _name.substring(0, idx);      String tmpSuf = _name.substring(idx + 1).trim();      String suf_ = "";      if (tmpSuf.length() > 0) {        String suf = tmpSuf.substring(0, 1).toUpperCase();        if (tmpSuf.length() > 1) {          suf_ = suf + tmpSuf.substring(1);        } else {          suf_ = suf;        }      }      _name = pre + suf_;    }    methodName = _name.substring(0, 1).toUpperCase() + _name.substring(1);    return _name.substring(0, 1).toLowerCase() + _name.substring(1);  }  private String removeDBKeyword(String name) {    String result = name;    if (DBKeyword.get(name.toUpperCase()) != null) {      result = "`" + name + "`";    }    return result;  }  public void setName(String name) {    this.name = name;  }  public String getDesc() {    return desc;  }  public void setDesc(String desc) {    this.desc = desc;  }  public Type getType() {    return type;  }  public void setType(Type type) {    this.type = type;  }  public String getDefault() {    return default_;  }  public void setDefault(String default_) {    this.default_ = default_;  }  public String getIsPK() {    return isPK;  }  public void setPK(String isPK) {    this.isPK = isPK;  }  public String getIsAllowNull() {    return allowNull;  }  public void setAllowNull(String allowNull) {    this.allowNull = allowNull;  }public Boolean getHasNext() {return hasNext;}public void setHasNext(Boolean hasNext) {this.hasNext = hasNext;}}


Type类是定义mysql列数据类型和java中数据类型的转换,写的比较单一,该项可以再以后进行扩展改变,因为数据库除了mysql还有oracle,sqlserver等;

public class Type {  private String sqlType;  private String javaType;  private static HashMap<String, String> typeMap=new HashMap<>();   static{  //基本的sql数据类型  typeMap.put("VARCHAR", "String");  typeMap.put("CHAR", "String");  typeMap.put("BLOB", "byte[]");  typeMap.put("TEXT", "String");  typeMap.put("INT", "Integer");  typeMap.put("INT UNSIGNED", "Integer");  typeMap.put("INTEGER", "Long");  typeMap.put("INTEGER UNSIGNED", "Long");  typeMap.put("TINYINT", "Integer");  typeMap.put("TINYINT UNSIGNED", "Integer");  typeMap.put("SMALLINT", "Integer");  typeMap.put("SMALLINT UNSIGNED", "Integer");  typeMap.put("MEDIUMINT", "Integer");  typeMap.put("MEDIUMINT UNSIGNED", "Integer");  typeMap.put("FLOAT", "Float");  typeMap.put("FLOAT UNSIGNED", "Float");  typeMap.put("DOUBLE", "Double");  typeMap.put("BIT", "Boolean");  typeMap.put("BIGINT", "java.math.BigInteger");  typeMap.put("DECIMAL", "java.math.BigDecimal");  typeMap.put("BOOLEAN", "Long");  typeMap.put("DATE", "java.sql.Date");  typeMap.put("TIME", "java.sql.Time");  typeMap.put("DATETIME", "java.sql.Timestamp") ;  typeMap.put("TIMESTAMP", "java.sql.Timestamp");  typeMap.put("YEAR", "java.sql.Date");  typeMap.put("OTHER", "String");  }  /**  * @author hym * @time 2017年7月20日 下午5:21:52 * @param sqlType * @param javaType */public Type(String sqlType, String javaType) {    this.sqlType = sqlType.toLowerCase();    this.javaType = javaType;  }  public String getSqlType() {    return sqlType;  }  public void setSqlType(String sqlType) {    this.sqlType = sqlType;  }  public String getJavaType() {    return javaType;  }  public void setJavaType(String javaType) {    this.javaType = javaType;  }    /** *   当返回值找不到的时候,直接返回other-string * @author hym * @time 2017年7月20日下午5:22:09 * @param sqlType * @return */public static Type get(String sqlType) {String javaType=typeMap.get(sqlType.toUpperCase());if (StringUtils.isEmpty(javaType)) {javaType=typeMap.get("OTHER");}    Type result = new Type(sqlType, javaType);    return result;  }}

当我们准备好工具类之后,那么就进入主类了,如下:

public class AutoGenerationJavaCode {     private String url;    private String name;    private String passWord;    private String driver;    private String sql;    private String tableName;    private String templateDir;    private String autoGeneratedFile;    //包的基础路径  比如com.xx等    private String basePath;    private static String[][] fileNameArray = new String[6][2];        static {        fileNameArray[0][0] = "entityTemplate.ftl";        fileNameArray[0][1] = ".java";        fileNameArray[1][0] = "serviceTemplate.ftl";        fileNameArray[1][1] = "Service.java";        fileNameArray[2][0] = "serviceImplTemplate.ftl";        fileNameArray[2][1] = "ServiceImpl.java";        fileNameArray[3][0] = "daoTemplate.ftl";        fileNameArray[3][1] = "Dao.java";        fileNameArray[4][0] = "daoImplTemplate.ftl";        fileNameArray[4][1] = "DaoImpl.java";                fileNameArray[5][0] = "mapper.ftl";        fileNameArray[5][1] = "Mapper.xml";    }    public AutoGenerationJavaCode(String url, String name, String passWord, String driver, String tableName,           String autoGeneratedFile,String basePath) {        this.url = url;        this.name = name;        this.passWord = passWord;        this.driver = driver;        this.sql = "select * from " + tableName;        this.tableName = tableName;        this.templateDir = this.getClass().getResource("").getPath().replace("target/classes/com/xx/common/code/autocode/", "")        +"src/main/java/com/xx/common/code/template";        this.autoGeneratedFile = autoGeneratedFile;        this.basePath=basePath;    }      public void autoGenerationJavaCode() throws IOException, TemplateException, ClassNotFoundException,            SQLException {        Configuration cfg = new Configuration();        cfg.setDefaultEncoding("utf-8");              String className = dealClassName(dealTableName());            String fileName = className;      //  Map<String, Object> columnMap = getColumn();        //设置模板文件路径        cfg.setDirectoryForTemplateLoading(new File(templateDir));             Map<String, Object> rootMap = new HashMap<String, Object>();        rootMap.put("className", className);        //rootMap.put("columnMap", columnMap);        rootMap.put("columns", getColumnList());        rootMap.put("basePath", basePath);                for (int i = 0; i < fileNameArray.length; i++) {        String packageName=null;        String filePath=null;        //设定包名            switch(fileNameArray[i][0]){            case "entityTemplate.ftl":            packageName=basePath+".entity";            filePath=autoGeneratedFile+"/entity";            break;            case "daoTemplate.ftl":            packageName=basePath+".dao";            filePath=autoGeneratedFile+"/dao";            break;            case "daoImplTemplate.ftl":            packageName=basePath+".dao.impl";            filePath=autoGeneratedFile+"/dao/impl";            break;            case "serviceTemplate.ftl":            packageName=basePath+".service";            filePath=autoGeneratedFile+"/service";            break;            case "serviceImplTemplate.ftl":            packageName=basePath+".service.impl";            filePath=autoGeneratedFile+"/service/impl";                        break;            case "mapper.ftl":            packageName=basePath;            filePath=autoGeneratedFile+"/mapper";               rootMap.put("tableName", tableName);            break;            }            rootMap.put("packageName", packageName);            File dir=new File(filePath);            //检查目录是否存在,不存在则创建            if (!dir.exists()) {                dir.mkdir();            }            Template temp = cfg.getTemplate(fileNameArray[i][0]);                   File docFile = new File(filePath + "//" + fileName + fileNameArray[i][1]);            Writer docout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));                        //输出文件            temp.process(rootMap, docout);        }        System.out.println("==============所有的文件已成功生成===============");    }        public List<Col> getColumnList() throws ClassNotFoundException, SQLException {        Connection conn;        PreparedStatement pStemt = null;        Class.forName(driver);        conn = DriverManager.getConnection(url, name, passWord);        pStemt = conn.prepareStatement(sql);        ResultSetMetaData rsmd = pStemt.getMetaData();                List<Col> listColumn=new ArrayList<Col>();        int size = rsmd.getColumnCount();         for (int i = 0; i < size; i++) {           // String columnName = dealColumnName(rsmd, i);            Col col=getColumnInfo(rsmd, i);            if(i==size-1){            col.setHasNext(false);            }                        listColumn.add(col);        }        conn.close();        return listColumn;    }        /**     * 获取列信息   需要设置多属性,该处生成mapper.xml的时候需要各种属性     * @author hym     * @time 2017年7月20日下午7:48:39     * @param rsmd     * @param i     * @return     * @throws SQLException     */    private Col getColumnInfo(ResultSetMetaData rsmd,int i) throws SQLException{        String columnName = rsmd.getColumnName(i + 1).toLowerCase();        String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1)));        String convertedChar = charAfterLine.toUpperCase();        String fieldName = columnName.replace("_" + charAfterLine, convertedChar);//映射到类中的名称    String columntype=rsmd.getColumnTypeName(i+1);//sql的列类型    Type type=new Type(columntype, Type.get(columntype).getJavaType());    Col col=new Col(i, fieldName, type);    col.setMethodName(dealClassName(fieldName));    col.setName(columnName);//表中的列名    if (columnName.equalsIgnoreCase("id")) {    col.setPK("yes");}        return col;    }        /**     * 将表名转换为DMO的字段名,比如 operate_type 转换后为 operateType     * @author hym     * @time 2017年7月22日下午4:22:14     * @param rsmd     * @param i     * @return     * @throws SQLException     */    private String dealColumnName(ResultSetMetaData rsmd, int i) throws SQLException {        String columnName = rsmd.getColumnName(i + 1).toLowerCase();        String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1)));        String convertedChar = charAfterLine.toUpperCase();        columnName = columnName.replace("_" + charAfterLine, convertedChar);        return columnName;    }        /**     * 将表名转换为类型类名 比如 t_operate_log 转换后为 operateLog ,类名首字母应为大写,这里在freemarker的模板里直接转换      * @author hym     * @time 2017年7月22日下午4:22:05     * @return     */    private String dealTableName() {        String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1);        String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1)));        String convertedChar = charAfterLine.toUpperCase();        className = className.replace("_" + charAfterLine, convertedChar);        return className;    }                public static void main(String[] args) {    String tableName="t_operate_table_test";    String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1);        String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1)));        String convertedChar = charAfterLine.toUpperCase();        className = className.replace("_" + charAfterLine, convertedChar);}        /**     * 将类名转换为文件名,java公共类名与其文件名应该相同,这里将首字母转换为大写 如operateLog 转换后为 OperateLog     * @author hym     * @time 2017年7月22日下午4:22:25     * @param className     * @return     */    private String dealClassName(String className) {        String first = className.substring(0, 1).toUpperCase();        String rest = className.substring(1, className.length());        String fileName = new StringBuffer(first).append(rest).toString();        return fileName;    }}

Ok,上面的基本完成了生成所需的java类文件;

测试代码如下:

public static void main(String[] args) throws ClassNotFoundException, IOException, TemplateException, SQLException {String url="jdbc:mysql://10.67.18.17:3306/xx";String username="xx";String password="xx";String driver="com.mysql.jdbc.Driver";String tableName="t_test_operate";String basePath="com.xx.test";String templateDir=System.getProperty("user.dir")+"/src/main/java/"+"com/xx/common/code/template";String generateFilePath=System.getProperty("user.dir")+"/src/main/java/"+basePath.replace(".", "/");AutoGenerationJavaCode autoGenerationJavaCode=new AutoGenerationJavaCode(url, username, password, driver, tableName, generateFilePath, "com.xx.test");autoGenerationJavaCode.autoGenerationJavaCode();}


考虑到可能会用到不同类型的数据库,后面会对上面的类进行改造;


阅读全文
0 0
原创粉丝点击