切换导航
临窗旋墨
首页
分类
归档
诗稿
留言板
关于
登录
gitee
github
QQ
本站建设:代码生成功能集成
文章来源
:
原创
作者:
临窗旋墨
发布时间:
2021-06-22
阅读:
581
标签:
springboot
[TOC] ## 003-代码生成功能集成 > 2019-11-14 ### 1- 代码生成思路 网上关于代码自动生成的开源项目很多,基本可以拿来之后修改模板文件直接使用.本项目的代码自动生成主要是17年左右借鉴人人开源上面的代码而来. 基本思路都是一样的: 1. 连接数据库获取数据库表的全部信息(本项目只实现mysql版本) * 如需支持多种数据库,则定义dao接口,不同的数据库做不同的实现,根据配置文件指定Primary 2. 解析表的基本信息,列的基本信息映射成对象 3. 编写各层模板,根据解析的数据对模板进行填充 4. 导出填充后的模板 ### 2-本项目中代码生成功能的大概实现 #### 2.1 配置文件与映射 `generator-config.properties` ```properties #代码生成器,配置信息 #包名 packageName=pers.vic #模块名 moduleName=system #作者 author=Vic.xu #Email email=xuduochoua@163.com #表前缀(类名不会包含表前缀) tablePrefix= #需要填充的模板 templates[0]=generator/templates/Entity.java.vm #略 #数据类型转换,配置信息:数据库类型->java类型 tinyint=Integer #略 ``` #### 2.2 解析表后的实体 1. `TableEntity` 对应一张表的基本数据:表名/备注/主键/对应的类名/创建时间/关联的`ColumnEntity`列表等 2. `ColumnEntity`对应列的属性:列名/列属性/备注/属性名/属性类型/是否主键/对应的`ColumnExtend`等 3. `ColumnExtend`列的扩展:本项目额外增加的根据备注对列做的额外的处理说明 #### 2.3service层大体代码 ```java @Service public class GeneratorService{ @Resource private ConfigurationOfGenerator configurationOfGenerator; @Resource private GeneratorMapper generatorMapper; public List<TableEntity> list(Lookup lookup) { List<TableEntity> datas = generatorMapper.queryList(lookup); return datas; } private List<ColumnEntity> queryColumns(String tableName) { return generatorMapper.queryColumns(tableName); } private TableEntity queryTable(String tableName) { return generatorMapper.queryTable(tableName); } /** * 根据表名生成代码 * * @param moduleName * @param packageName */ public byte[] generatorCode(String[] tableNames, String packageName, String moduleName) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); for (String tableName : tableNames) { // 查询表信息 TableEntity table = queryTable(tableName); // 查询列信息 List<ColumnEntity> columns = queryColumns(tableName); // 生成代码 generatorCode(table, packageName, moduleName, columns, zip); } IOUtils.closeQuietly(zip); return outputStream.toByteArray(); } private void generatorCode(TableEntity table, String packageName, String moduleName, List<ColumnEntity> columns, ZipOutputStream zip) { Map<String, Object> map = getTemplateData(table, packageName, moduleName, columns); VelocityContext context = new VelocityContext(map); // 获取模板列表 List<String> templates = getTemplates(); for (String template : templates) { // 渲染模板 StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8"); tpl.merge(context, sw); try { // 添加到zip String fileName = getFileName(template, table.getClassName(), configurationOfGenerator.getPackageName(), configurationOfGenerator.getModuleName()); zip.putNextEntry(new ZipEntry(fileName)); IOUtils.write(sw.toString(), zip, "UTF-8"); IOUtils.closeQuietly(sw); zip.closeEntry(); } catch (Exception e) { throw new RuntimeException("渲染模板失败,表名:" + table.getTableName(), e); } } } //获得渲染模板的数据 private Map<String, Object> getTemplateData(TableEntity table, String packageName, String moduleName, List<ColumnEntity> columns) { // 配置信息 Configuration config = getConfig(); boolean hasBigDecimal = false; String className = tableToJava(table.getTableName(), configurationOfGenerator.getTablePrefix()); table.setClassName(className); // 第一个字母小写 table.setClassname(StringUtils.uncapitalize(className)); // 列信息 for (ColumnEntity column : columns) { // 列名转换成Java属性名 String attrName = columnToJava(column.getColumnName()); column.setAttrName(attrName); column.setAttrname(StringUtils.uncapitalize(attrName)); // 列的数据类型,转换成Java类型 String attrType = config.getString(column.getDataType(), "unknowType"); column.setAttrType(attrType); if (!hasBigDecimal && attrType.equals("BigDecimal")) { hasBigDecimal = true; } if ("Date".equals(attrType)) { table.setHasDate(true); } // 是否主键 if ("PRI".equalsIgnoreCase(column.getColumnKey()) && table.getPk() == null) { table.setPk(column); } // 根据列是否是图片和日期 判断表中是否含有图片和日期 ColumnExtend extend = ColumnExtend.initExtends(column); table.findExtend(extend); } // 没主键,则第一个字段为主键 table.setColumns(columns); if (table.getPk() == null) { table.setPk(columns.get(0)); } // 设置velocity资源加载器 Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); // 封装模板数据 Map<String, Object> map = new HashMap<String, Object>(); map.put("table", table); map.put("tableName", table.getTableName()); map.put("comments", table.getComments()); map.put("pk", table.getPk()); map.put("className", table.getClassName()); map.put("classname", table.getClassname()); map.put("pathName", table.getClassname().toLowerCase()); map.put("columns", table.getColumns()); map.put("hasBigDecimal", hasBigDecimal); if (StringUtils.isEmpty(packageName)) { map.put("package", config.getString("packageName")); } else { map.put("package", packageName); } if (StringUtils.isEmpty(packageName)) { map.put("moduleName", config.getString("moduleName")); } else { map.put("moduleName", moduleName); } map.put("author", config.getString("author")); map.put("email", config.getString("email")); map.put("datetime", DateFormatUtils.format(new Date(), "yyyy-mm-dd HH:mm")); return map; } /** * 获取文件名 */ public static String getFileName(String template, String className, String packageName, String moduleName) { String packagePath = "generator" + File.separator + className; /* * 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 + File.separator + className + ".java"; } // 查询条件 if (template.contains("Lookup.java.vm")) { return packagePath + File.separator + className + "Lookup.java"; } // mapper.java if (template.contains("Mapper.java.vm")) { return packagePath + File.separator + className + "Mapper.java"; } // service if (template.contains("Service.java.vm")) { return packagePath + File.separator + className + "Service.java"; } // controller if (template.contains("Controller.java.vm")) { return packagePath + File.separator + className + "Controller.java"; } // mapper.xnl if (template.contains("Mapper.xml.vm")) { return packagePath + File.separator + className + "Mapper.xml"; } // list.jsp if (template.contains("list.jsp.vm")) { return packagePath + File.separator + "list.jsp"; } // form.jsp if (template.contains("form.jsp.vm")) { return packagePath + File.separator + "form.jsp"; } return null; } /** * 获取要填充的模板 * @return */ public List<String> getTemplates() { return configurationOfGenerator.getTemplates(); } /** * 表名转换成Java类名 */ private String tableToJava(String tableName, String tablePrefix) { if (StringUtils.isNotBlank(tablePrefix)) { tableName = tableName.replaceFirst(tablePrefix, ""); } return columnToJava(tableName); } /** * 列名转换成Java属性名 */ public static String columnToJava(String columnName) { // return WordUtils.capitalizeFully(columnName, new char[] { '_' }).replace("_", "");//aaBBcc-->aabbcc 不是我想要的 return underlineToCamel(columnName); } /** * 下划线转驼峰 但是不小写 * * @param str * @return */ static String UNDERLINE = "_"; public static String underlineToCamel(String str) { if (StringUtils.isEmpty(str)) { return str; } StringBuffer sb = new StringBuffer(); for (String s : str.split(UNDERLINE)) { sb.append(StringUtils.capitalize(s)); } return sb.toString(); } /** * 获取配置信息 */ public static Configuration getConfig() { try { return new PropertiesConfiguration("config/generator-config.properties"); } catch (ConfigurationException e) { throw new RuntimeException("获取配置文件失败,", e); } } public Map<String, String> findTableDetail(String tableName, String packageName, String moduleName) { // 查询表信息 TableEntity table = queryTable(tableName); // 查询列信息 List<ColumnEntity> columns = queryColumns(tableName); Map<String, Object> map = getTemplateData(table, packageName, moduleName, columns); VelocityContext context = new VelocityContext(map); // 获取模板列表 List<String> templates = getTemplates(); Map<String, String> data = new LinkedHashMap<String, String>(); for (String template : templates) { // 渲染模板 StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8"); tpl.merge(context, sw); try { // 添加到zip String fileName = getFileName(template, table.getClassName(), configurationOfGenerator.getPackageName(), configurationOfGenerator.getModuleName()); data.put(fileName.replace("generator" + File.separator, "").replace(File.separator, "_"), sw.toString()); } catch (Exception e) { throw new RuntimeException("渲染模板失败,表名:" + table.getTableName(), e); } } return data; } } ```
发表评论
Copyright © 2020 许秋冬
皖ICP备20011253号