赞
踩
为了简化日常编写代码,根据公司的自身情况,编写了一个自动生成代码的简易工具。
主要需要熟悉freemarker模板引擎,JDBC等相关知识;
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.8</version>
</dependency>
<!-- 这个是生成驼峰命名的工具 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
ColumnClass 用来封装 数据库表元数据的信息,如字段名称,字段类型,字段注释等等。
public class ColumnClass { /** 数据库字段名称 **/ private String columnName; /** 数据库字段类型 **/ private String columnType; /** 数据库字段首字母小写且去掉下划线字符串 **/ private String changeColumnName; /** 数据库字段注释 **/ private String columnComment; /** * 列的长度 */ private int columnSize; /** * 是否允许为空 */ private String nullable; /** * 主键名 */ private String pkName; ...get/set方法 }
package cn.sh.cjvision.CodeGenerator.jdbc; import cn.sh.cjvision.CodeGenerator.ColumnClass; import cn.sh.cjvision.CodeGenerator.FreeMarkerTemplateUtils; import com.google.common.base.CaseFormat; import org.apache.commons.jexl2.UnifiedJEXL; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; //import com.evada.inno.pm.code.generate.model.ColumnClass; import freemarker.template.Template; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.sql.*; import java.time.LocalDate; import java.util.*; import static cn.sh.cjvision.CodeGenerator.FreeMarkerTemplateUtils.createDir; public class CodeGenerateUtils { /** * 链接地址 */ @Value("${spring.datasource.url}") private String URL; /** * 用户名 */ @Value("@{spring.datasource.username}") private String USER; /** * 密码 */ @Value("@{spring.datasource.password}") private String PASSWORD; /** * 连接驱动 */ @Value("@{spring.datasource.driver-class-name}") private String DRIVER; /** * 作者 */ private final String AUTHOR = "wowoToffon"; /** * 时间 */ private final String CURRENT_DATE = LocalDate.now().toString(); /** * 表名 */ private final String tableName = "BOOK"; /** * 包名 */ private final String packageName = "cn.sh.cjvision"; /** * 表中文注释 */ private final String tableAnnotation = "书"; /** * 生成位置 */ private final String diskPath = "E:\\MyProject\\Quartz\\Quartz\\app-quartz\\src\\main\\java\\cn\\sh\\cjvision"; /** * 将类似为 A_TABLE 转换为驼峰命名 aTable */ private final String changeTableName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName); /** * 获取jdbc链接 * @return * @throws Exception */ public Connection getConnection() throws Exception { Class.forName(DRIVER); Properties props =new Properties(); props.put("user", USER); props.put("password", PASSWORD); // 允许获取注解(这个是重点,在oracle中不加这个,获得注释就是 null) props.put("remarksReporting","true"); Connection connection = DriverManager.getConnection(URL, props); return connection; } public static void main(String[] args) throws Exception { CodeGenerateUtils codeGenerateUtils = new CodeGenerateUtils(); codeGenerateUtils.generate(); } public void generate() throws Exception { Connection connection = getConnection(); //生成Model文件 generateModelFile(connection); // 生成Controller文件 generateControllerFile(); // 生成service文件 generateServiceFile(); } public List<ColumnClass> setColumnClass(Connection connection) throws SQLException { DatabaseMetaData databaseMetaData = connection.getMetaData(); // 获取表中列值信息 ResultSet resultSet = databaseMetaData.getColumns(null, "%", tableName, "%"); // 获取表主键信息 ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, "BOOK"); List<ColumnClass> columnClassList = new LinkedList<>(); ColumnClass columnClass = null; while (resultSet.next()) { columnClass = new ColumnClass(); //获取字段名称 columnClass.setColumnName(resultSet.getString("COLUMN_NAME")); //获取字段类型 columnClass.setColumnType(resultSet.getString("TYPE_NAME").split("\\(")[0]); //转换字段名称,如 sys_name 变成 SysName columnClass.setChangeColumnName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,(resultSet.getString("COLUMN_NAME")))); //字段在数据库的注释 columnClass.setColumnComment(resultSet.getString("REMARKS")); // 字段长度 columnClass.setColumnSize(resultSet.getInt("COLUMN_SIZE")); // 是否为必填 columnClass.setNullable(resultSet.getString("NULLABLE")); columnClassList.add(columnClass); } while (primaryKeys.next()) { int i = 0; columnClass = columnClassList.get(i); columnClass.setPkName(primaryKeys.getString("PK_NAME")); i++; } return columnClassList; } private void generateModelFile(Connection connection) throws Exception { DatabaseMetaData databaseMetaData = connection.getMetaData(); ResultSet resultSet = databaseMetaData.getColumns(null, "%", tableName, "%"); String newPath = createDir(diskPath, "bean"); final String suffix = ".java"; final String path = newPath + changeTableName + suffix; final String templateName = "Model.ftl"; File mapperFile = new File(path); Map<String, Object> dataMap = new HashMap<>(); dataMap.put("model_column", setColumnClass(connection)); generateFileByTemplate(templateName, mapperFile, dataMap); } private void generateServiceFile() throws Exception { String newPath = createDir(diskPath, "service"); final String suffix = "Service.java"; final String path = newPath + changeTableName + suffix; final String templateName = "Service.ftl"; File mapperFile = new File(path); Map<String, Object> dataMap = new HashMap<>(); generateFileByTemplate(templateName, mapperFile, dataMap); } private void generateControllerFile() throws Exception { String newPath = createDir(diskPath, "controller"); final String suffix = "Controller.java"; final String path = newPath + changeTableName + suffix; final String templateName = "Controller.ftl"; File mapperFile = new File(path); Map<String, Object> dataMap = new HashMap<>(); generateFileByTemplate(templateName, mapperFile, dataMap); } private void generateFileByTemplate(final String templateName, File file, Map<String, Object> dataMap) throws Exception { Template template = FreeMarkerTemplateUtils.getTemplate(templateName); FileOutputStream fos = new FileOutputStream(file); dataMap.put("table_name_small", tableName); dataMap.put("table_name", changeTableName); dataMap.put("author", AUTHOR); dataMap.put("date", CURRENT_DATE); dataMap.put("package_name", packageName); dataMap.put("table_annotation", tableAnnotation); Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240); template.process(dataMap, out); } }
FreeMarkerTemplateUtils工具类用来配置模板所在的路径
package cn.sh.cjvision.CodeGenerator; // import com.evada.inno.core.exception.BusinessException; import freemarker.cache.ClassTemplateLoader; import freemarker.cache.NullCacheStorage; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateExceptionHandler; import java.io.File; import java.io.IOException; public class FreeMarkerTemplateUtils { private FreeMarkerTemplateUtils(){} private static final Configuration CONFIGURATION = new Configuration(); static{ //这里比较重要,用来指定加载模板所在的路径 CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreeMarkerTemplateUtils.class, "/templates")); CONFIGURATION.setDefaultEncoding("UTF-8"); CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE); } public static Template getTemplate(String templateName) throws IOException { try { return CONFIGURATION.getTemplate(templateName); } catch (IOException e) { throw e; } } public static void clearCache() { CONFIGURATION.clearTemplateCache(); } /** * 创建 文件夹 * @param FileAddress * @param fileName * @return */ public static String createDir (String FileAddress, String fileName){ FileAddress = FileAddress + "/" +fileName + "/"; File file = new File(FileAddress); if(file.exists()){ System.out.println("存在该目录"); return FileAddress; } /*if (!FileAddress.endsWith(File.separator)) { FileAddress = FileAddress + File.separator; }*/ if(file.mkdir()){ System.out.println("创建目录" + FileAddress + "创建成功"); }else { System.out.println("创建失败"); } return FileAddress; } }
Freemarker的模板文件,后缀都是以ftl结尾的。
创建Model.ftl
package ${package_name}.bean; import cn.sh.cjvision.framework.bean.bean.BaseBean; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import org.hibernate.annotations.GenericGenerator; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; import cn.sh.cjvision.framework.utils.constant.AppConstants; import javax.persistence.*; import java.util.Date; /** * 描述:${table_annotation}模型 * @author ${author} * @date ${date} */ @Entity @Table(name = "${table_name_small}") @ApiModel public class ${table_name} extends BaseBean { <#if model_column?exists> <#list model_column as model> /** *${model.columnComment!} */ <#if (model.columnType = 'VARCHAR2' || model.columnType = 'VARCHAR' || model.columnType = 'NUMBER' || model.columnType = 'TEXT')> <#if model.pkName?exists> @Id @GeneratedValue(generator = "${model.columnName}") @GenericGenerator(name = "${model.columnName}", strategy = AppConstants.SEQ_GENERATOR_STR) <#else > @Column(name = "${model.columnName}") <#if (model.nullable = '0')> @NotBlank(message = "${model.columnComment!}不能为空") @ApiModelProperty(value = "${model.columnComment!}不能为空", required = true) </#if> </#if> @Length(max = ${model.columnSize},message = "最长为${model.columnSize}") private String ${model.changeColumnName?uncap_first}; </#if> <#if model.columnType = 'TIMESTAMP' > <#if (model.nullable = '0')> @NotNull(message = "${model.columnComment!}不能为空") @ApiModelProperty(value = "${model.columnComment!}不能为空", required = true) </#if> @Column(name = "${model.columnName}",columnDefinition = "TIMESTAMP") private Date ${model.changeColumnName?uncap_first}; </#if> </#list> </#if> <#if model_column?exists> <#list model_column as model> <#if (model.columnType = 'VARCHAR2' || model.columnType = 'TEXT')> public String get${model.changeColumnName}() { return this.${model.changeColumnName?uncap_first}; } public void set${model.changeColumnName}(String ${model.changeColumnName?uncap_first}) { this.${model.changeColumnName?uncap_first} = ${model.changeColumnName?uncap_first}; } </#if> <#if model.columnType = 'TIMESTAMP' > public Date get${model.changeColumnName}() { return this.${model.changeColumnName?uncap_first}; } public void set${model.changeColumnName}(Date ${model.changeColumnName?uncap_first}) { this.${model.changeColumnName?uncap_first} = ${model.changeColumnName?uncap_first}; } </#if> </#list> </#if> }
Service.flt文件
package ${package_name}.service;
import cn.sh.cjvision.framework.repository.CustomRepository;
import ${package_name}.bean.${table_name}Bean;
public interface ${table_name}Service extends CustomRepository<${table_name}Bean, String>
{
}
Controller.flt文件
package ${package_name}.controller; import ${package_name}.bean.${table_name}Bean; import cn.sh.cjvision.framework.annotation.log.LogWrite; import cn.sh.cjvision.framework.controller.BaseController; import cn.sh.cjvision.framework.utils.out.OutPutJson; import ${package_name}.service.${table_name}Service; import com.alibaba.fastjson.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.swagger.annotations.Api; import org.hibernate.validator.constraints.NotBlank; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @RequestMapping("/app/${table_name?uncap_first}") @Validated @Api(tags = "${table_annotation}") public class ${table_name}Controller { private final static Logger logger = LoggerFactory.getLogger(${table_name}Controller.class); @Autowired private ${table_name}Service ${table_name?uncap_first}Service; @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * 描述:根据Id 查询 * @param id ${table_annotation}id */ @PostMapping(value = "get${table_name}ById") @LogWrite(moduleName = "获取${table_annotation}", op = LogWrite.OP.QUERY) public JSONObject findById(@NotBlank(message = "ID不能为空") String id)throws Exception { JSONObject obj = new JSONObject(); ${table_name}Bean ${table_name?uncap_first}Bean = ${table_name?uncap_first}Service.findOne(id); obj.put("${table_name?uncap_first}Bean", ${table_name?uncap_first}Bean); return OutPutJson.success("获取成功", obj); } /** * 描述:创建${table_annotation} * @param */ @PostMapping(value = "add${table_name}") @LogWrite(moduleName = "新增${table_annotation}", op = LogWrite.OP.ADD) public JSONObject add${table_name}(@Validated ${table_name}Bean ${table_name?uncap_first}Bean) throws Exception { JSONObject obj = new JSONObject(); try{ ${table_name}Bean ${table_name?uncap_first}Save = ${table_name?uncap_first}Service.save(${table_name?uncap_first}Bean); obj.put("${table_name?uncap_first}Bean", ${table_name?uncap_first}Save); return OutPutJson.success("新增成功", obj); } catch (Exception e){ logger.error("URL:/app/${table_name?uncap_first}/add${table_name} 异常 " + e.getMessage(), e); return OutPutJson.failure("新增失败:" + e.getMessage()); } } /** * 描述:删除${table_annotation} * @param id ${table_annotation}id */ @PostMapping(value = "del${table_name}ByIds") @LogWrite(moduleName = "删除${table_annotation}", op = LogWrite.OP.DELETE) public JSONObject del${table_name}ByIds(@RequestBody List<String> ids) throws Exception { Map<String, Object> map = new HashMap<>(1); if(ids.size() > 0){ map.put("ids", ids); namedParameterJdbcTemplate.update("DELETE FROM ${date} WHERE RWRY_ID IN (:ids)", map); } return OutPutJson.success("移除成功"); } /** * 描述:编辑${table_annotation} * @param */ @PostMapping(value = "update${table_name}") @LogWrite(moduleName = "编辑${table_annotation}", op = LogWrite.OP.UPDATE) public JSONObject update${table_name}(@Validated ${table_name}Bean ${table_name?uncap_first}Bean) throws Exception { JSONObject obj = new JSONObject(); try{ ${table_name}Bean ${table_name?uncap_first}Update = ${table_name?uncap_first}Service.saveAndFlush(${table_name?uncap_first}Bean); obj.put("${table_name?uncap_first}Bean", ${table_name?uncap_first}Update); return OutPutJson.success("编辑成功", obj); } catch (Exception e){ logger.error("URL:/app/${table_name?uncap_first}/update${table_name} 异常 " + e.getMessage(), e); return OutPutJson.failure("编辑失败:" + e.getMessage()); } } }
注意:
参考:
JDBC元数据操作(一)-- DatabaseMetaData接口详解
Java之利用Freemarker模板引擎实现代码生成器,提高效率(我主要看的这篇,在他的基础上加了生成文件夹, 没有用他的驼峰名)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。