package com.suke.czx.common.utils; import cn.hutool.core.date.DateUtil; import com.suke.czx.common.exception.RRException; import com.suke.czx.modules.gen.entity.ColumnEntity; import com.suke.czx.modules.gen.entity.GenConfig; import com.suke.czx.modules.gen.entity.InfoRmationSchema; import com.suke.czx.modules.gen.entity.TableEntity; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.WordUtils; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * 代码生成器 工具类 * * @author czx * @email object_czx@163.com * @date 2016年12月19日 下午11:40:24 */ @Component public class GenUtils { public List getTemplates(){ List templates = new ArrayList(); templates.add("template/Entity.java.vm"); templates.add("template/Mapper.java.vm"); templates.add("template/Mapper.xml.vm"); templates.add("template/Service.java.vm"); templates.add("template/ServiceImpl.java.vm"); templates.add("template/Controller.java.vm"); templates.add("template/list.html.vm"); templates.add("template/list.js.vm"); templates.add("template/menu.sql.vm"); return templates; } /** * 生成代码 */ public void generatorCode(GenConfig genConfig,InfoRmationSchema table, List columns, ZipOutputStream zip) { //配置信息 Configuration config = getConfig(); boolean hasBigDecimal = false; //表信息 TableEntity tableEntity = new TableEntity(); tableEntity.setTableName(table.getTableName()); tableEntity.setComments(table.getTableComment()); //表名转换成Java类名 String className = columnToJava(tableEntity.getTableName()); tableEntity.setClassName(className); tableEntity.setClassNameMin(StringUtils.uncapitalize(className)); //列信息 List columsList = new ArrayList<>(); for(ColumnEntity column : columns){ ColumnEntity columnEntity = new ColumnEntity(); columnEntity.setColumnName(column.getColumnName()); columnEntity.setDataType(column.getDataType()); columnEntity.setColumnComment(column.getColumnComment()); columnEntity.setExtra(column.getExtra()); columnEntity.setColumnKey(column.getColumnKey()); //列名转换成Java属性名 String attrName = columnToJava(columnEntity.getColumnName()); columnEntity.setAttrName(attrName); columnEntity.setAttrNameMin(StringUtils.uncapitalize(attrName)); //列的数据类型,转换成Java类型 String attrType = config.getString(columnEntity.getDataType(), "unknowType"); columnEntity.setAttrType(attrType); if (!hasBigDecimal && attrType.equals("BigDecimal")) { hasBigDecimal = true; } //是否主键 if ("PRI".equalsIgnoreCase(column.getColumnKey()) && tableEntity.getPk() == null) { tableEntity.setPk(columnEntity); } columsList.add(columnEntity); } tableEntity.setColumns(columsList); //没主键,则第一个字段为主键 if (tableEntity.getPk() == null) { tableEntity.setPk(tableEntity.getColumns().get(0)); } //设置velocity资源加载器 Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" ); Velocity.init(prop); String mainPath = genConfig.getMainPath(); mainPath = StringUtils.isBlank(mainPath) ? "com.suke.czx" : mainPath; //封装模板数据 Map map = new HashMap<>(); map.put("tableName", tableEntity.getTableName()); map.put("comments", tableEntity.getComments()); map.put("pk", tableEntity.getPk()); map.put("className", tableEntity.getClassName()); map.put("classname", tableEntity.getClassNameMin()); map.put("pathName", tableEntity.getClassNameMin().toLowerCase()); map.put("columns", tableEntity.getColumns()); map.put("hasBigDecimal", hasBigDecimal); map.put("mainPath", mainPath); map.put("package", genConfig.getPackagePath()); map.put("moduleName", genConfig.getModuleName()); map.put("author", genConfig.getAuthor()); map.put("email", genConfig.getEmail()); map.put("datetime", DateUtil.now()); VelocityContext context = new VelocityContext(map); //获取模板列表 List templates = getTemplates(); for (String template : templates) { //渲染模板 StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8" ); tpl.merge(context, sw); try { //添加到zip zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), genConfig.getPackagePath(), genConfig.getModuleName()))); IOUtils.write(sw.toString(), zip, "UTF-8" ); IOUtils.closeQuietly(sw); zip.closeEntry(); } catch (IOException e) { throw new RRException("渲染模板失败,表名:" + tableEntity.getTableName(), e); } } } /** * 列名转换成Java属性名 */ public String columnToJava(String columnName) { return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "" ); } /** * 获取配置信息 */ public Configuration getConfig() { try { return new PropertiesConfiguration("generator.properties" ); } catch (ConfigurationException e) { throw new RRException("获取配置文件失败,", e); } } /** * 获取文件名 */ public String getFileName(String template, String className, String packageName, String moduleName) { String packagePath = "main" + File.separator + "java" + File.separator; if (StringUtils.isNotBlank(packageName)) { packagePath += packageName.replace(".", File.separator) + File.separator + moduleName + File.separator; } if (template.contains("Entity.java.vm" )) { return packagePath + "entity" + File.separator + className + ".java"; } if (template.contains("Mapper.java.vm" )) { return packagePath + "mapper" + File.separator + className + "Mapper.java"; } if (template.contains("Service.java.vm" )) { return packagePath + "service" + File.separator + className + "Service.java"; } if (template.contains("ServiceImpl.java.vm" )) { return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; } if (template.contains("Controller.java.vm" )) { return packagePath + "controller" + File.separator + className + "Controller.java"; } if (template.contains("Mapper.xml.vm" )) { return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + moduleName + File.separator + className + "Mapper.xml"; } if (template.contains("list.html.vm" )) { return "x-springboot-ui" + File.separator + "modules" + File.separator + moduleName + File.separator + className.toLowerCase() + ".html"; } if (template.contains("list.js.vm" )) { return "x-springboot-ui" + File.separator + "js" + File.separator + "modules" + File.separator + moduleName + File.separator + className.toLowerCase() + ".js"; } if (template.contains("menu.sql.vm" )) { return className.toLowerCase() + "_menu.sql"; } return null; } }