忽然想起以前工作的时候突发奇想写的一个一个代码生成器,也记录一下吧。
首先文件如下:
package ${packageName}; import java.util.Date; public class ${className}{ <#-- 循环类型及属性 --> <#list attrs as attr> private ${attr.type} ${attr.name}; //${attr.remarks} #list> <#-- 循环生成set get方法 --> <#list attrs as attr> public void set${attr.name}(${attr.type} ${attr.name}) { this.${attr.name} = ${attr.name}; } public ${attr.type} get${attr.name}() { return ${attr.name}; } #list> }
package cn.itrip.beans.util; import java.io.File; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateExceptionHandler; public class FreeMarkerInit { private static FreeMarkerInit single= new FreeMarkerInit(); private FreeMarkerInit() {} //静态工厂方法 public static FreeMarkerInit getInstance() { return single; } public Template getDefinedTemplate(String templateName) throws Exception{ //配置类 Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); cfg.setDirectoryForTemplateLoading(new File("E:/springBootLearn/itrip-test/itripbeans/src/main/resources/template/")); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); return cfg.getTemplate(templateName); } }
Freemarker提供了3种加载模板目录的方法。 它使用Configuration类加载模板。
三种方法分别是:
public void setClassForTemplateLoading(Class clazz, String pathPrefix);
public void setDirectoryForTemplateLoading(File dir) throws IOException;
public void setServletContextForTemplateLoading(Object servletContext, String path);
第一种:基于类路径,HttpWeb包下的framemaker.ftl文件
configuration.setClassForTemplateLoading(this.getClass(), "/HttpWeb");
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板
第二种:基于文件系统
configuration.setDirectoryForTemplateLoading(new File("/template"))
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板
第三种:基于Servlet Context,指的是基于WebRoot下的template下的framemaker.ftl文件
HttpServletRequest request = ServletActionContext.getRequest();
configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template");
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板
package cn.itrip.beans.util; import java.sql.*; import java.util.ArrayList; import java.util.List; /** * 负责获取表的元信息 * 列的元信息 */ public class MetadataUtil { private static Connection conn; private static DatabaseMetaData meta; static { try { Class.forName("com.mysql.jdbc.Driver"); }catch (ClassNotFoundException e){ e.printStackTrace(); System.out.println("数据库连接失败!"); } } public static void openConnection(){ try { if (conn==null||conn.isClosed()){ conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/itripdb", "root","root"); meta=conn.getMetaData(); } }catch (SQLException e){ e.printStackTrace(); } } //获取注解 public static String getCommentByTableName(String tableName) throws Exception{ openConnection(); Statement stmt=conn.createStatement(); ResultSet rs=stmt.executeQuery("SHOW CREATE TABLE "+tableName); String comment=null; if (rs!=null&&rs.next()){ comment=rs.getString(2); } rs.close(); stmt.close(); conn.close(); return comment; } //获取所有表名称 public static ListgetTableNames(){ openConnection(); ResultSet rs=null; List nameList=new ArrayList<>(); try { rs=meta.getTables(null,null,null,new String[]{"TABLE"}); while (rs.next()){ String tName=rs.getString("TABLE_NAME"); nameList.add(tName); } }catch (Exception e){ e.printStackTrace(); } return nameList; } /** * 列信息数组的集合。List中每个元素是一个数组,代表一个列的信息; * 每个数组的元素1是列名,元素2是注释,元素3是类型 * @return */ public static List getTableColumnsInfo(String tableName) throws Exception{ openConnection(); ResultSet rs=meta.getColumns(null,"%",tableName,"%"); List columnInfoList=new ArrayList<>(); while (rs.next()){ String[] colInfo=new String[3]; colInfo[0] =rs.getString("COLUMN_NAME"); colInfo[1] =rs.getString("REMARKS"); colInfo[2] =rs.getString("TYPE_NAME"); columnInfoList.add(colInfo); } return columnInfoList; } public static DatabaseMetaData getMeta() { return meta; } public static void setMeta(DatabaseMetaData meta) { MetadataUtil.meta = meta; } public static Connection getConn() { return conn; } public static void setConn(Connection conn) { MetadataUtil.conn = conn; } }
package cn.itrip.beans.util; /** * java类名、属性名、方法名转换工具类 * * @author imagines */ public class JavaNameUtil { /** * 将数据库(表、字段)转换以java命名方式帕斯卡或者骆驼 * @param unberscoreName * @param isPascal 是否将首字母转化大写,true则转化为骆驼命名,false则转换为帕斯卡命名 * @return 骆驼或帕斯卡命名字符串 */ public static String translate(String unberscoreName, boolean isPascal) { StringBuilder result = new StringBuilder(); //从第一个字母 if (unberscoreName != null && unberscoreName.length() !=0) { boolean flag = false; char firstChar = unberscoreName.charAt(0); //得到首字母 if (isPascal) { result.append(Character.toUpperCase(firstChar)); } else { result.append(firstChar); } //从第二个字母以后开始 for (int i = 1, length = unberscoreName.length(); i < length; i++) { char ch = unberscoreName.charAt(i); if ('_' == ch) { flag = true; } else { if (flag) { //标记上一个是下划线,就转化为大写。 result.append(Character.toUpperCase(ch)); flag = false; } else { result.append(ch); } } } } return result.toString(); } /** * 调用translate() 转换为帕斯卡命名 * @param unberscoreName 数据库(表名、字段名) * @return */ public static String toPascal(String unberscoreName) { return translate(unberscoreName, true); } /** * 调用translate() 转换为骆驼命名 * @param unberscoreName 数据库(表名、字段名) * @return */ public static String toCamel(String unberscoreName) { return translate(unberscoreName, false); } /** * * 将获取数据库类型转化为java类型 * @param dbTypeName 实际的数据库类型 * @return */ public static String dbTypeChangeJavaType(String dbTypeName){ String javaType=null; switch(dbTypeName){ case "VARCHAR" :javaType="String";break; case "BIGINT" :javaType="Long";break; case "INT" :javaType="Integer";break; case "DATETIME" :javaType="Date";break; default:javaType="String";break; } return javaType; } public static void main(String[] args) { String javaname = JavaNameUtil.toPascal("imagines_age_name"); System.out.println(javaname); } }
import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import cn.itrip.beans.util.Attribute; import cn.itrip.beans.util.FreeMarkerInit; import cn.itrip.beans.util.JavaNameUtil; import cn.itrip.beans.util.MetadataUtil; import freemarker.template.Template; public class TemplateTest { //生成bean public void gen1() throws Exception{ //生成路径 String savePath="E://springBootLearn//itrip-test//itripbeans//src//main//java//cn//itrip//beans//pojo"; //获取模板 Template temp = FreeMarkerInit.getInstance().getDefinedTemplate("javabean.ftl"); //获取表名集合 Liststrs=MetadataUtil.getTableNames(); for (String str1: strs ) { //Attribute里面封装模板使用属性 List strList=MetadataUtil.getTableColumnsInfo(str1); List attr_list = new ArrayList (); for (String[] c:strList ) { attr_list.add(new Attribute(JavaNameUtil.dbTypeChangeJavaType(c[2]), JavaNameUtil.toCamel(c[0]),c[1])); } //装换为帕斯卡命名 String str=JavaNameUtil.toPascal(str1); Map root = new HashMap (); root.put("packageName", "cn.itrip.beans.pojo"); root.put("className", str); root.put("attrs", attr_list); OutputStream fos = new FileOutputStream( new File(savePath, str+".java")); Writer out = new OutputStreamWriter(fos); temp.process(root, out); fos.flush(); fos.close(); } } public static void main(String[] args) { TemplateTest test = new TemplateTest(); try { test.gen1(); } catch (Exception e) { e.printStackTrace(); } } }