前言

公司比较小,为了节约成本,所以在领导授意下做了这个。

相对现在存在的各种自动生成框架来说,自己做的用起来更舒服一点,想怎么改就这么改。

什么前端 android什么的都能用到。

好吧 是领导叫我写技术文档的 但是不想碰word

工具采用jdbc连接数据库,freemarker作为输出模板,swing做界面操作。

效果

准备

面向过程的解释:

1.swing生成一个网格界面 ,读取配置为输入框赋值

2.用户填写配置进入界面 点击生成按钮

3.事件监听生效,并保存用户本次配置

4.根据用户配置调用不同模板配置

5.连接数据库 查询表和列信息

6.通过模板配置,获取到页面模板

7.通过freemarker生成模板并输出

8.通过开发工具 导出为jar(或者可运行jar都可以)

9.……下载exe4J……

10.根据官方文档或者软件提示 将jar转换成exe 软件中可以将jre一起打包 以免用户电脑没有安装java环境

<!-- 页面模板 --><dependency><groupId>freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.9</version></dependency><!-- 可以省下get set toString等代码--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.0</version><scope>provided</scope></dependency><!-- 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency><!-- 基本工具 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version></dependency>

数据库

首先准备2个类接收数据库表和列的信息

1.表信息

package com.tnzt.config.generator.core.entity;import java.util.Date;
import java.util.List;import com.tnzt.config.generator.core.util.StringHelper;import lombok.Data;/*** @author zth*/
//lombok注解
@Data
public class Table {private String tableName;//表名称private String tableComment;//表描述//生成辅助private String path;//路径private String entityName;//实体名称private String entityFirstLowerName;private String daoName;//daoprivate String daoFirstLowerName;private String serviceName;//serviceprivate String serviceFirstLowerName;private String formName;//表单名称private String mapperName;//mapperprivate String actionName;//actionprivate String apiName;//接口private String apiUserName;//用户权限接口private String daoPackageName;//dao包名private String entityPackageName;//entityprivate String formPackageName;//表单private String mapperPackageName;//mapperprivate String servicePackageName;//serviceprivate String actionPackageName;//actionprivate String apiPackageName;//接口private String apiUserPackageName;//用户权限接口private String pagePackageName;//页面private String actionRequestMapping;//action请求地址private String apiRequestMapping;//接口请地址private Date genDateTime = new Date();private List<Column> columns = null;//字段列表private Column primaryColumn;//主键列表//设置列信息public void setColumns(List<Column> columns) {this.columns = columns;for(Column c:columns){if(c.getPrimary()==1){setPrimaryColumn(c);}}}//设置各种路径,freemarker模板中用到public void setDefault(Config config){if(tableName==null||tableName.equals("")){return ;}String[] tableNameArry = StringHelper.getSplit(tableName,config.getSplitFlag());path = "";if(tableNameArry.length>1){for(int i=1;i<tableNameArry.length;i++){if(i==1){entityName=StringHelper.firstToUpper(tableNameArry[i]);} else {entityName+=StringHelper.firstToUpper(tableNameArry[i]);}}path="."+tableNameArry[0];} else{entityName=StringHelper.firstToUpper(tableName);}entityFirstLowerName=StringHelper.firstToLower(entityName);daoName=entityName+config.getDaoName();daoFirstLowerName=StringHelper.firstToLower(daoName);serviceName=entityName+config.getServiceName();serviceFirstLowerName=StringHelper.firstToLower(serviceName);mapperName=entityName+config.getMapperName();actionName=entityName+config.getActionName();apiName=entityName+config.getApiName();apiUserName=entityName+config.getApiUserName();formName=entityName+config.getFormName();daoPackageName=config.getDaoPackageName()+path;entityPackageName=config.getEntityPackageName()+path;formPackageName=config.getFormPackageName()+path;servicePackageName=config.getServicePackageName()+path;mapperPackageName=config.getMapperPackageName()+path;actionPackageName=config.getActionPackageName()+path;apiPackageName=config.getActionPackageName()+".api"+path;apiUserPackageName=config.getActionPackageName()+".api.user"+path;pagePackageName="page";actionRequestMapping=path.replace(".", "/")+"/"+entityFirstLowerName+"/";apiRequestMapping=path.replace(".", "/")+"/api/"+entityFirstLowerName+"/";}}

2.列信息

package com.tnzt.config.generator.core.entity;import lombok.Data;/*** @author zth*/
@Data
public class Column {//字段名private String name;//首字母大写字段名private String nameTopBig;//数据库中得字段名private String dbName;//db字段类型private String dbType;//javaBean字段类型private String javaType;//javaBean字段类型private String jdbcType;//字段注释private String comment;//是否主键 0不是1是主键private int primary;}

3 .查询sql

package com.tnzt.config.generator.core.util;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;import com.tnzt.config.generator.core.entity.Column;
import com.tnzt.config.generator.core.entity.Config;
import com.tnzt.config.generator.core.entity.Table;/*** @author zth**/
public class DbHelper {/*** 根据表名获得字段名和注释列表* @param tableName* @return*/public static List<Column> getTableColumns(String tableName,Config config,Connection conn){//根据表名获得字段名和注释列表String sql = "select COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT,COLUMN_KEY from information_schema.columns where table_name = ? and TABLE_SCHEMA = ?";PreparedStatement ppst = null;List<Column> columns = new ArrayList<Column>();Column column = null;boolean primaryFlag = false;int primaryNum = 0;try {//查询ppst = conn.prepareStatement(sql);ppst.setString(1, tableName);ppst.setString(2, config.getTableSchema());ResultSet rs = ppst.executeQuery();while(rs.next()){ column = new Column();column.setName(rs.getString("COLUMN_NAME"));column.setDbName(rs.getString("COLUMN_NAME"));column.setNameTopBig(StringHelper.firstToUpper(column.getName()));column.setDbType(rs.getString("DATA_TYPE"));if("PRI".equals(rs.getString("COLUMN_KEY"))){column.setPrimary(1);
//                 mc.setPrimaryColumn(column);primaryFlag = true;primaryNum++;}else{column.setPrimary(0);}//数字型if("int".equals(column.getDbType())){column.setJavaType("Integer");column.setJdbcType("INTEGER");}else if("bigint".equals(column.getDbType()) ){column.setJavaType("Long");column.setJdbcType("BIGINT");}else if("tinyint".equals(column.getDbType())){   column.setJavaType("Short");column.setJdbcType("TINYINT");}else if("smallint".equals(column.getDbType())){ column.setJavaType("Integer");column.setJdbcType("INTEGER");}else if("varchar".equals(column.getDbType())){column.setJavaType("String");column.setJdbcType("VARCHAR");}else if("text".equals(column.getDbType())){column.setJavaType("String");column.setJdbcType("LONGVARCHAR");}else if("char".equals(column.getDbType())){column.setJavaType("String");column.setJdbcType("CHAR");}else if("date".equals(column.getDbType()) || "time".equals(column.getDbType())){column.setJavaType("Date");column.setJdbcType("DATE");}else if("datetime".equals(column.getDbType()) ||"timestamp".equals(column.getDbType())){column.setJavaType("Date");column.setJdbcType("TIMESTAMP");}
//             else if("datetime".equals(column.getDbType()) || "date".equals(column.getDbType()) || "time".equals(column.getDbType())){
//                 column.setJavaType("Date");
//                 column.setJdbcType("DATE");
//             }else if("timestamp".equals(column.getDbType())){
//                 column.setJavaType("Date");
//                 column.setJdbcType("TIMESTAMP");
//             }else if("decimal".equals(column.getDbType())){column.setJavaType("BigDecimal");column.setJdbcType("DECIMAL");}else if("float".equals(column.getDbType())){column.setJavaType("float");column.setJdbcType("FLOAT");}else{column.setJavaType(column.getDbType());column.setJdbcType(column.getDbType());}column.setComment(rs.getString("COLUMN_COMMENT")==null?"":rs.getString("COLUMN_COMMENT"));columns.add(column);}   if(columns.size()<=0){System.out.println("["+tableName+"]是一个空表,没有任何字段");}if(!primaryFlag){System.out.println("["+tableName+"]表缺少主键");}else{if(primaryNum>1){System.out.println("["+tableName+"]表有["+primaryNum+"]个主键,生成工具暂时不能对多主键进行友好支持");}}rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return columns;    }/*** 获取所有表名与表注释* @param config* @param conn* @return*/public static List<Table> getTableList(Config config,Connection conn){List<Table> tables=new ArrayList<Table>();String sql = "select table_name,table_comment from information_schema.tables  where  TABLE_SCHEMA = ? ";PreparedStatement ppst = null;try {ppst = conn.prepareStatement(sql);ppst.setString(1, config.getTableSchema());ResultSet rs = ppst.executeQuery();while(rs.next()){ Table table=new Table();table.setTableName(rs.getString("table_name"));table.setTableComment(rs.getString("table_comment"));tables.add(table);} rs.close();} catch (SQLException e) {e.printStackTrace();}return tables;}}       

freemarker输出

下面是如何将数据库数据获得,并通过freemakrder模板输出

package com.tnzt.config.generator.core.util;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.apache.commons.lang3.StringUtils;import com.tnzt.config.generator.core.entity.Config;
import com.tnzt.config.generator.core.entity.Table;import freemarker.template.Template;/*** @author zth**/
public class EntityGenerator {//数据库驱动public static final String DBDRIVER = "com.mysql.jdbc.Driver";//模板包名public static  String TEMPLATEPath = "com/config/freemarker/ssm";public void generator(Config config,String DBURL,String DBUSER,String DBPASS,int type) throws ClassNotFoundException, SQLException{//1、使用CLASS 类加载驱动程序 这玩意大家很熟悉吧 最早的无框架jdbc搞法Class.forName(DBDRIVER);  Connection con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、连接数据库  if(con == null){return;}//获取表List<Table> tables=DbHelper.getTableList(config, con);for(Table table:tables){table.setDefault(config);//获取列table.setColumns(DbHelper.getTableColumns(table.getTableName(), config, con));//开始生成System.out.println("==========Entity生成==========");write(table,config,config.getEntityTemPateName(),table.getEntityPackageName(),table.getEntityName()+".java");System.out.println("==========Dao生成==========");write(table,config,config.getDaoTemPateName(),table.getDaoPackageName(),table.getDaoName()+".java");System.out.println("==========Service生成==========");write(table,config,config.getServiceTemPateName(),table.getServicePackageName(),table.getServiceName()+".java");System.out.println("==========Mapper生成==========");write(table,config,config.getMapperTemPateName(),table.getMapperPackageName(),table.getMapperName()+".xml");System.out.println("==========Form生成==========");write(table,config,config.getFormTemPateName(),table.getFormPackageName(),table.getFormName()+".java");System.out.println("==========Action生成==========");write(table,config,config.getActionTemPateName(),table.getActionPackageName(),table.getActionName()+".java");//页面生成 type 0:springboot 1:springmvcString viewDir="/"+config.getDefaultPackageName().replace(".", "_");viewDir = viewDir.substring(0,viewDir.length());String pageDir=viewDir+"/"+table.getPagePackageName()+"/"+table.getEntityFirstLowerName();switch (type) {case 1:System.out.println("==========Api生成==========");write(table,config,config.getApiTemPateName(),table.getApiPackageName(),table.getApiName()+".java");System.out.println("==========ApiUser生成==========");write(table,config,config.getApiUserTemPateName(),table.getApiUserPackageName(),table.getApiUserName()+".java");System.out.println("==========Page index.ftl生成==========");write(table,config,config.getIndexTemPateName(),pageDir,"index.html");System.out.println("==========Page build.ftl生成==========");write(table,config,config.getBuildTemPateName(),pageDir,"build.html");System.out.println("==========Page edit.ftl生成==========");write(table,config,config.getEditTemPateName(),pageDir,"edit.html");System.out.println("==========Page show.ftl生成==========");write(table,config,config.getShowTemPateName(),pageDir,"show.html");System.out.println("==========Page form.ftl生成==========");write(table,config,config.getPformTemPateName(),pageDir,"form.html");break;default:break;}}}/*** 写出代码文件* @param table* @param config* @param ftl* @param packageName* @param fileName*/private void write(Table table,Config config,String ftl,String packageName,String fileName){File file;if(StringUtils.isNotEmpty(table.getTableName())){String entityFolder=config.getSrcPath()+"/gcoder/"+packageName.replace(".", "/");String entityFile=entityFolder+"/"+fileName;file = new File(entityFolder);if(!file.exists()){file.mkdirs();}System.out.println("生成:"+entityFile);Map<String, Object> root = new HashMap<>();root.put("config", config);root.put("table", table);root.put("columns", table.getColumns());try {//freemarker写出loadContentByTemplate(config,root,ftl,entityFile);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/*** freemarker模板写出* @param config* @param root* @param TemplateName* @param targetFile* @throws Exception*/@SuppressWarnings("deprecation")private void loadContentByTemplate(Config config,Map<String, Object> root,String TemplateName,String targetFile)throws  Exception{InputStream is = null;BufferedReader br = null;Writer out = null;try {//加载freemarker模板文件//由于模板文件被打包在jar里面了 所有通过jvm加载 以流的方式读取模板is=this.getClass().getResourceAsStream(config.getTemplatePath()+TemplateName);   br=new BufferedReader(new InputStreamReader(is,"UTF-8")); Template template = new Template(TemplateName, br);//如果模板文件放在jar包外面 则用路劲写出
//          Template template = cfg.getTemplate(TemplateName); //输出模板out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8"));  template.process(root,out);out.flush();} catch (IOException e) {e.printStackTrace();}finally {out.close();br.close();is.close();}}}

配置类相关

1.主配置类

package com.tnzt.config.generator.core.entity;import lombok.Data;/*** @author zth**/
@Data
public class Config {private String defaultPackageName;private String tableSchema;private String srcPath;private String templatePath;private String daoPackageName;//dao包名private String entityPackageName;//entity包名private String formPackageName;//form包名private String mapperPackageName;//mapper包名private String servicePackageName;//service包名private String actionPackageName;//action包名private String author="zth";private String version="v1.0.0";private String description="自动生成的代码";//路径生成配置private String splitFlag = "_";private String daoName = "Dao";//dao名称private String formName = "Form";//表单名称private String mapperName = "Mapper";//mapper名称private String serviceName = "ServiceBean";//service名称private String actionName = "Action";//Action名称private String apiName = "ApiAction";//Action名称private String apiUserName = "ApiUserAction";//Action名称private String defaultEntityPackageName = ".entity";//entity路径private String defaultDaoPackageName = ".dao";//dao路径private String defaultServicePackageName = "service";//service路径private String defaultMapperPackageName = ".mapper";//mapper路径private String defaultActionPackageName = ".action";//控制器路径private String defaultFormPackageName = ".form";//表单路径private String entityTemPateName = "entity.ftl";//entity模板名private String daoTemPateName = "dao.ftl";//dao模板名private String serviceTemPateName = "service.ftl";//service模板名private String mapperTemPateName = "mapper.ftl";//mapper模板名private String actionTemPateName = "action.ftl";//控制器模板名private String formTemPateName = "form.ftl";//表单模板名private String apiTemPateName = "api.ftl";//控制器模板名private String apiUserTemPateName = "api.ftl";//控制器模板名private String indexTemPateName = "index.ftl";//首页模板名private String buildTemPateName = "build.ftl";//新增页模板名private String editTemPateName = "edit.ftl";//编辑页模板名private String showTemPateName = "show.ftl";//详情页模板名private String pformTemPateName = "pform.ftl";//表单页模板名private String corePackageName = "com.tnzt.ssm.core.web.action";}

springboot配置类

package com.tnzt.config.generator.springboot;import com.tnzt.config.generator.core.entity.Config;import lombok.Data;
import lombok.EqualsAndHashCode;/*** @author zth**/
@Data
@EqualsAndHashCode(callSuper=false)
public class SpringBootConfig extends Config{private String TEMPTEMPLATEPath = "/com/tnzt/config/freemarker/springboot/";private String defaultPackageName;//默认包名private String daoName = "Mapper";//dao名称private String formName = "Form";//表单名称private String mapperName = "Mapper";//mapper名称private String serviceName = "Service";//service名称private String actionName = "Controller";//Action名称private String defaultEntityPackageName = ".entity";//dao路径private String defaultDaoPackageName = ".mapper";//dao路径private String defaultServicePackageName = ".services";//service路径private String defaultMapperPackageName = ".mapperdb";//mapper路径private String defaultActionPackageName = ".controllers";//控制器路径private String defaultFormPackageName = ".form";//表单路径private String actionTemPateName = "controller.ftl";public SpringBootConfig() { super.setTemplatePath(TEMPTEMPLATEPath);}public void setDefault(){setDefaultPackageName(defaultPackageName);setEntityPackageName(defaultPackageName+getDefaultEntityPackageName());setDaoPackageName(defaultPackageName+getDefaultDaoPackageName());setServicePackageName(defaultPackageName+getDefaultServicePackageName());setMapperPackageName(defaultPackageName+getDefaultMapperPackageName());setActionPackageName(defaultPackageName+getDefaultActionPackageName());setFormPackageName(defaultPackageName+getDefaultFormPackageName());super.setDaoName(daoName);super.setFormName(formName);super.setMapperName(mapperName);super.setServiceName(serviceName);super.setActionName(actionName);super.setActionTemPateName(actionTemPateName);}
}

springmvc+mybatis项目配置类 与springboot不同的地方也就是模板存放的目录 和一些模板的名称有变化而已

package com.tnzt.config.generator.ssm;import com.tnzt.config.generator.core.entity.Config;import lombok.Data;
import lombok.EqualsAndHashCode;/*** @author zth**/
@Data
@EqualsAndHashCode(callSuper=false)
public class SsmConfig extends Config{private String TEMPTEMPLATEPath = "/com/tnzt/config/freemarker/ssm/";private String defaultPackageName;//默认包名private String daoName = "Dao";//dao名称private String formName = "Form";//表单名称private String mapperName = "Mapper";//mapper名称private String serviceName = "Service";//service名称private String actionName = "Action";//Action名称private String apiName = "ApiAction";//api名称private String apiUserName = "ApiUserAction";//apiUser名称private String defaultEntityPackageName = ".entity";//dao路径private String defaultDaoPackageName = ".dao";//dao路径private String defaultServicePackageName = ".service";//service路径private String defaultMapperPackageName = ".mapper";//mapper路径private String defaultActionPackageName = ".action";//控制器路径private String defaultFormPackageName = ".form";//表单路径private String defaultApiActionPackageName = ".action.api";//api控制器路径private String defaultApiUserActionPackageName = ".action.api.user";//apiUser控制器路径public SsmConfig() { super.setTemplatePath(TEMPTEMPLATEPath);}public void setDefault(){setDefaultPackageName(defaultPackageName);setEntityPackageName(defaultPackageName+getDefaultEntityPackageName());setDaoPackageName(defaultPackageName+getDefaultDaoPackageName());setServicePackageName(defaultPackageName+getDefaultServicePackageName());setMapperPackageName(defaultPackageName+getDefaultMapperPackageName());setActionPackageName(defaultPackageName+getDefaultActionPackageName());setFormPackageName(defaultPackageName+getDefaultFormPackageName());super.setDaoName(daoName);super.setFormName(formName);super.setMapperName(mapperName);super.setServiceName(serviceName);super.setActionName(actionName);}
}

swing工具界面

其实上面的内容已经可以完成自动生成任务了 但是给人用的话 还需要稍微包装一下

界面生成

package com.tnzt.config.jframe;import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;import org.apache.commons.lang3.StringUtils;import com.tnzt.config.generator.core.entity.Config;
import com.tnzt.config.generator.core.util.EntityGenerator;
import com.tnzt.config.generator.core.util.PropertiesConfig;
import com.tnzt.config.thread.GpopConfigThread;/*** @author zth**/
public abstract class Jwindow extends JFrame implements ActionListener{private static final long serialVersionUID = 1L;//界面相关//界面提示文字组件private JLabel schma,address, userName, password,src,defaultPackage,gtype;//界面接收信息组件private JTextField textSchma,textAddress,textUserName, textUserPassword,textSrc,textDefaultPackage;  //下拉框private JComboBox<String> comboboxGtype;//提交按钮private JButton submit;//网格界面布局器private GridBagLayout g = new GridBagLayout();//网格界面容器private GridBagConstraints c = new GridBagConstraints();//配置相关//配置文件 存放在当前用户的用户目录 用来保存上一次用的操作配置private Properties properties;//各个组件对应的properties中的key//哪个数据库private static String schma_key = "schma";//哪个ip地址private static String address_key = "address";//数据库账号private static String userName_key = "userName";//数据库密码private static String password_key = "password";//代码生成输出的文件路径private static String src_key = "src";//代码中默认的包名 如本文的 com.tnztprivate static String defaultPackage_key = "defaultPackage";//用哪个模板生成代码private static String gtype_key = "gtype";/*** 界面生成* @param str* @throws IOException*/public Jwindow(String str) throws IOException{super(str); //设置界面 宽 高setSize(350, 280);  //用户单击窗口的关闭按钮时程序执行的操作setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置界面setLayout(g); //配置界面中的内容addComponent(); //加载配置loadConfig();}// 在这个方法中将会添加所有的组件; // 使用的网格包布局;希望楼主能看懂; @SuppressWarnings({ "unchecked", "rawtypes" })private void addComponent(){// 数据库名字schma = new JLabel("数据库名:"); add(g, c, schma, 0, 1, 1, 1); // 数据库名字输入textSchma = new JTextField("huilian",15);add(g, c, textSchma, 1, 1, 2, 1); // 数据库连接地址address = new JLabel("主机名或IP地址:"); add(g, c, address, 0, 2, 1, 1); // 数据库连接地址输入textAddress = new JTextField("10.7.13.48:8066",15); add(g, c, textAddress, 1, 2, 2, 1); // 用户名 userName = new JLabel("数据库用户名 :"); add(g, c, userName, 0, 3, 1, 1); // 用户名输入框 textUserName = new JTextField("huilian",15); add(g, c, textUserName, 1, 3, 2, 1); // 密码: password = new JLabel("数据库密码:"); add(g, c, password, 0, 4, 1, 1); // 密码输入框 textUserPassword = new JTextField("MLjmhddGBfdMHbdPkKhbd",15); add(g, c, textUserPassword, 1, 4, 2, 1); // 目标路径: src = new JLabel("目标路径:"); add(g, c, src, 0, 5, 1, 1); // 目标路径入框 textSrc = new JTextField("D:/",15); add(g, c, textSrc, 1, 5, 2, 1); // 默认包名: defaultPackage = new JLabel("默认包名:"); add(g, c, defaultPackage, 0, 6, 1, 1); // 默认包名入框 textDefaultPackage = new JTextField("tf56.huilian",15); add(g, c, textDefaultPackage, 1, 6, 2, 1); // 框架: gtype = new JLabel("生成框架:"); add(g, c, gtype, 0, 7, 1, 1); // 框架下拉列表 comboboxGtype = new JComboBox(); comboboxGtype.addItem("springboot");comboboxGtype.addItem("ssm");add(g, c, comboboxGtype, 1, 7, 2, 1);// submit按钮submit = new JButton("快速生成");c.insets = new Insets(8, 0, 4, 0);add(g, c, submit, 1, 8, 1, 1);submit.addActionListener(this); setVisible(true); setLocationRelativeTo(null);// 设居中显示;}private void add(GridBagLayout g, GridBagConstraints c, JComponent jc,int x, int y, int gw, int gh){c.gridx = x;c.gridy = y;c.anchor = GridBagConstraints.WEST;c.gridwidth = gw;c.gridheight = gh;g.setConstraints(jc, c);add(jc);}private void loadConfig() throws IOException {properties = PropertiesConfig.loadProperties();//定义并设置数据if(properties.isEmpty()) {return;}String schma_value = properties.getProperty(schma_key);if(StringUtils.isNotBlank(schma_value)) {textSchma.setText(schma_value);}String address_value = properties.getProperty(address_key);if(StringUtils.isNotBlank(address_value)) {textAddress.setText(address_value);}String userName = properties.getProperty(userName_key);if(StringUtils.isNotBlank(userName)) {textUserName.setText(userName);}String password_value = properties.getProperty(password_key);if(StringUtils.isNotBlank(password_value)) {textUserPassword.setText(password_value);}String src_value = properties.getProperty(src_key);if(StringUtils.isNotBlank(src_value)) {textSrc.setText(src_value);}String defaultPackage_value = properties.getProperty(defaultPackage_key);if(StringUtils.isNotBlank(defaultPackage_value)) {textDefaultPackage.setText(defaultPackage_value);}String gtype_value = properties.getProperty(gtype_key);if(StringUtils.isNotBlank(gtype_value)) {comboboxGtype.setSelectedIndex(Integer.parseInt(gtype_value));}}/** *  用户操作监听(点了生成按钮)*/@Overridepublic void actionPerformed(ActionEvent event) {//各种数据取出来String DBUSER = textUserName.getText();String DBPASS = textUserPassword.getText();String SRCPath = textSrc.getText();String TABLE_SCHEMA=textSchma.getText();String DEFAULT_PACKAGE=textDefaultPackage.getText();String DBURL= "jdbc:mysql://"+textAddress.getText()+"/"+TABLE_SCHEMA+"?characterEncoding=utf8";int type = comboboxGtype.getSelectedIndex();Map<String, Object> map = new HashMap<String, Object>();map.put(schma_key, TABLE_SCHEMA);map.put(address_key, textAddress.getText());map.put(userName_key, DBUSER);map.put(password_key, DBPASS);map.put(src_key, SRCPath);map.put(defaultPackage_key, DEFAULT_PACKAGE);map.put(gtype_key, type);try {//开启线程保存用的操作配置 GpopConfigThread t = new GpopConfigThread(map);new Thread(t).start();;//根据获取的用户设置建立相关配置Config config = buildConfig(DEFAULT_PACKAGE, SRCPath, TABLE_SCHEMA,type);if(config == null) {JOptionPane.showMessageDialog(null, "请选择模板类型", "提示", 0);}//执行生成代码EntityGenerator e = new EntityGenerator();e.generator(config,DBURL,DBUSER,DBPASS,type);JOptionPane.showMessageDialog(null, "自动生成成功---->"+SRCPath+"/gcoder", "提示", 1);} catch (Exception e) {e.printStackTrace();JOptionPane.showMessageDialog(null, e.getMessage(), "提示", 0);}}/*** 建立相关配置* @param DEFAULT_PACKAGE* @param SRCPath* @param TABLE_SCHEMA* @param type* @return*/public abstract Config buildConfig(String DEFAULT_PACKAGE,String SRCPath,String TABLE_SCHEMA,int type);}

配置文件相关

package com.tnzt.config.generator.core.util;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;/*** @author zth**/
public class PropertiesConfig{//配置保存的目录private static String config_dir = "gcoder";//配置文件名称private static String config_name = "gcoder.propertise";//获取当前用户目录private static String config_dir_path = System.getProperty("user.home")+File.separator+config_dir;//文件路径private static String config_path = config_dir_path+File.separator+config_name;/*** 保存设置* @param pops* @throws IOException*/public static void setConfig(Map<String, Object> pops) throws IOException {  FileOutputStream fout = null;try {        fout = new FileOutputStream(config_path);Properties properties = new Properties();Iterator<String> i = pops.keySet().iterator();while (i.hasNext()) {String key = i.next();Object value = pops.get(key);if(value ==null) {continue;}properties.setProperty(key, String.valueOf(value));}properties.store(fout, null);   } catch (IOException e) {  e.printStackTrace();  }finally {fout.close();  }} /*** 读取设置* @return* @throws IOException*/public static Properties loadProperties() throws IOException {FileInputStream fin = null;Properties properties = null;try {properties = new Properties();File f = new File(config_path);if(!f.exists()) {File dir = new File(config_dir_path);dir.mkdirs();f.createNewFile();}fin = new FileInputStream(f);properties.load(fin);} catch (Exception e) {e.printStackTrace();}finally {fin.close();}return properties;}
}

配置保存线程

package com.tnzt.config.thread;import java.io.IOException;
import java.util.Map;import com.tnzt.config.generator.core.util.PropertiesConfig;/*** @author zth**/
public class GpopConfigThread implements Runnable{private Map<String, Object> params;public GpopConfigThread(Map<String, Object> params) {this.params = params;}@Overridepublic void run() {try {PropertiesConfig.setConfig(params);} catch (IOException e) {e.printStackTrace();}}}

主运行类(可运行jar的main方法)

package com.tnzt.config.main;import java.io.IOException;import com.tnzt.config.generator.core.entity.Config;
import com.tnzt.config.generator.springboot.SpringBootConfig;
import com.tnzt.config.generator.ssm.SsmConfig;
import com.tnzt.config.jframe.Jwindow;/*** @author zth**/
public class MainProcessor extends Jwindow{private static final long serialVersionUID = 1L;public MainProcessor(String str) throws IOException {super(str);}@Overridepublic Config buildConfig(String DEFAULT_PACKAGE, String SRCPath, String TABLE_SCHEMA, int type) {switch (type) {case 0:SpringBootConfig springBootConfig=new SpringBootConfig();springBootConfig.setDefaultPackageName(DEFAULT_PACKAGE);springBootConfig.setDefault();springBootConfig.setSrcPath(SRCPath);springBootConfig.setTableSchema(TABLE_SCHEMA);return springBootConfig;case 1:SsmConfig ssmConfig=new SsmConfig();ssmConfig.setDefaultPackageName(DEFAULT_PACKAGE);ssmConfig.setDefault();ssmConfig.setSrcPath(SRCPath);ssmConfig.setTableSchema(TABLE_SCHEMA);return ssmConfig;default:return null;}}public static void main(String[] args) throws IOException {new MainProcessor("代码自动生成工具");}}

相关的一些工具类

package com.tnzt.config.generator.core.util;import org.apache.commons.lang3.StringUtils;/*** @author zth**/
public class StringHelper {/*** 分割字符串* @param splitStr* @param splitFlag* @return*/public static String[] getSplit(String splitStr,String splitFlag){return splitStr.split(splitFlag);}/**首字母大写* @param str* @return*/public static String firstToUpper(String str){if(StringUtils.isBlank(str)) {return str;}return str.substring(0, 1).toUpperCase()+str.substring(1);}/**首字母小写* @param str* @return*/public static String firstToLower(String str){if(StringUtils.isBlank(str)) {return str;}return str.substring(0, 1).toLowerCase()+str.substring(1);}
}

freemarker模板写法

因为是模板嘛 不和任何语言挂钩 所以生成java文件 html页面 什么的都可以

这个下面贴几个有代表性的的模板

action类

package ${table.actionPackageName};import ${table.servicePackageName}.${table.serviceName};
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import ${table.entityPackageName}.${table.entityName};
import tf56.ehuodi.domain.ResultPojo;
import tf56.ehuodi.utils.RequestUtils;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import tf56.ehuodiOperate.utils.NumberUtils;
import tf56.huilian.services.LockService;/*** ${table.actionName}* ${table.tableComment}* @author  ${config.author}* @version ${config.version}* 描述:${config.description}* 时间:${table.genDateTime?string("yyyy-MM-dd HH:mm:ss")}*/
@RestController
@RequestMapping("${table.actionRequestMapping}")
public class ${table.actionName}{private static final Logger LOGGER = LoggerFactory.getLogger(${table.actionName}.class);private static String insert_lock_key = "${table.actionName}_lock_insert${table.entityName}";@Autowiredprivate LockService lockService;@Autowiredprivate ${table.serviceName} ${table.serviceFirstLowerName};/******************************开发的代码区域 开始***************************//******************************开发的代码区域 结束***************************//***************************自动生成的代码区域 开始**************************/<#assign num=0 /><#list columns as column><#if column.name == 'updateJobcard' || column.name == 'updateUsername'><#assign num=num+1 /></#if></#list>/*** 新增 ${table.tableComment}* @param ${table.entityFirstLowerName}* @return*/@RequestMapping(value = "/insert",method= RequestMethod.POST)public String insert(HttpServletRequest req, @Valid ${table.entityName} ${table.entityFirstLowerName}) {LOGGER.info("新增 ${table.tableComment} 入参:{}",${table.entityFirstLowerName});if(${table.entityFirstLowerName}.get${table.primaryColumn.nameTopBig}()!=null){return ResultPojo.Err("id不可传入").toJson();}if (!lockService.lock(insert_lock_key)) {return ResultPojo.Err("当前已有操作进行中").toJson();}try{ResultPojo res = ${table.serviceFirstLowerName}.insert(${table.entityFirstLowerName});return res.toJson();}catch(Exception e){LOGGER.info("${table.tableComment} 新增 失败 :",e);return ResultPojo.Err("创建失败").toJson();}finally {lockService.unlock(insert_lock_key);}}/*** 删除 ${table.tableComment}* @param id* @return*/@RequestMapping(value = "/delete",method= RequestMethod.POST)public String delete(String ${table.primaryColumn.name}) {LOGGER.info("删除 ${table.tableComment} 入参:{}",${table.primaryColumn.name});ResultPojo res = ${table.serviceFirstLowerName}.delete(${table.primaryColumn.name});return res.toJson();}/*** 编辑 ${table.tableComment}* @param ${table.entityFirstLowerName}* @return*/@RequestMapping(value = "/update",method= RequestMethod.POST)public String update(HttpServletRequest req,@Valid ${table.entityName} ${table.entityFirstLowerName}) {LOGGER.info("修改 ${table.tableComment} 入参:{}",${table.entityFirstLowerName}); <#if num == 2>setUser(req,${table.entityFirstLowerName}); //写入 操作用户</#if>ResultPojo<Integer> res = ${table.serviceFirstLowerName}.update(${table.entityFirstLowerName});return res.toJson();}/*** 通用列表查询 ${table.tableComment}* @param HttpServletRequest* @return*/@RequestMapping(value = "/selectList",method= RequestMethod.POST)public String selectList(HttpServletRequest request) {Map<String, String> params = RequestUtils.getParamMapFromRequest(request);return ${table.serviceFirstLowerName}.selectList(params);}/*** 通用单体查询 ${table.tableComment}* @param ${table.primaryColumn.name}* @return*/@RequestMapping(value = "/selectOne",method= RequestMethod.POST)public String selectOne(String ${table.primaryColumn.name}) {return ${table.serviceFirstLowerName}.selectOne(${table.primaryColumn.name});}<#if num == 2>private void setUser(HttpServletRequest req,${table.entityName} ${table.entityFirstLowerName}){String username = (String) req.getParameter("username");String jobCard = (String) req.getParameter("jobCard");${table.entityFirstLowerName}.setUpdateJobcard(jobCard);${table.entityFirstLowerName}.setUpdateUsername(username);}  </#if>/***************************自动生成的代码区域 结束**************************/}

dao里面就个类名和继承不需要内容就不贴了

贴个实体类的

package ${table.entityPackageName};
<#assign isDate=false isBigDecimal=false>
<#list columns as column><#if column.name!="id"&&column.name!="createdAt"&&column.name!="updatedAt"><#if column.javaType=="Date" && !isDate>
import java.util.Date;<#assign isDate=true></#if><#if column.javaType=="BigDecimal" && !isBigDecimal>
import java.math.BigDecimal;<#assign isBigDecimal=true></#if></#if>
</#list>
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;/*** ${table.tableComment}* @author  ${config.author}* @version ${config.version}* 描述:${config.description}* @since ${table.genDateTime?string("yyyy-MM-dd HH:mm:ss")}*/
@Data
public class ${table.entityName}{<#list columns as column>//${column.comment}<#if column.javaType=="Date">@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")</#if>private ${column.javaType} ${column.name};</#list>}

mybatie 的 mapper 这个和实体dao其实 mybatis generator 插件也可以生成的

就看里面需要什么方法了

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<!--  * ${table.mapperName}* ${table.tableComment}* @author  ${config.author}* @version ${config.version}* 描述:${config.description}* 时间:${table.genDateTime?string("yyyy-MM-dd HH:mm:ss")}
-->
<mapper namespace="${table.daoPackageName}.${table.mapperName}" ><resultMap id="BaseResultMap" type="${table.entityPackageName}.${table.entityName}" > <#list columns as column><#if column.primary==1><id column="${column.dbName}" property="${column.name}" jdbcType="${column.jdbcType}" /><!--${column.comment}--></#if><#if column.primary==0><result column="${column.dbName}" property="${column.name}" jdbcType="${column.jdbcType}" /><!--${column.comment}--></#if></#list></resultMap><!--****************************开发的代码区域 开始****************************--><!--****************************开发的代码区域 结束****************************--><!--***************************自动生成的代码区域 开始**************************--><!-- 插入数据 --><insert id="insert" parameterType="${table.entityPackageName}.${table.entityName}"> insert into <include refid="table_name" /><trim prefix="(" suffix=")" suffixOverrides="," ><#list columns as column><#if column.dbName != 'createDate' && column.dbName != 'updateDate'&& column.dbName != 'stampDate'><if test="${column.name} != null" >${column.dbName},</if><#else>${column.dbName},</#if></#list></trim><trim prefix="values (" suffix=")" suffixOverrides="," ><#list columns as column><#if column.dbName != 'createDate' && column.dbName != 'updateDate'&& column.dbName != 'stampDate'><if test="${column.name} != null" >${'#'}${'{'}${column.name}${'}'},</if><#else>NOW(),</#if></#list></trim></insert><!-- 根据主键删除数据 --><delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >delete from <include refid="table_name" /><include refid="primaryCondition"/> </delete><!-- 根据主键修改数据 --><update id="updateByPrimaryKeySelective" parameterType="${table.entityPackageName}.${table.entityName}" >update <include refid="table_name" /><set><#list columns as column><#if column.dbName != 'updateDate'&& column.dbName != 'stampDate'><if test="${column.name} != null" >${column.dbName} = ${'#'}${'{'}${column.name}${'}'},</if><#else>${column.dbName} = NOW(),</#if></#list></set><include refid="primaryCondition"/> </update><!-- 根据条件查询数量 --><select id="selectCountByCondition" resultType="java.lang.Integer" parameterType="java.util.Map" >selectcount(1)from <include refid="table_name" /><include refid="selectByCondition_where" /></select><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select<include refid="Base_Column_List" />from <include refid="table_name" /><include refid="primaryCondition"/> </select><select id="selectByCondition" resultMap="BaseResultMap" parameterType="java.util.Map" >select<include refid="Base_Column_List" />from <include refid="table_name" /><include refid="selectByCondition_where" /></select><!-- 以下引用sql --><!-- 表名 --><sql id="table_name">${table.tableName}</sql><!-- 主键条件 --><sql id="primaryCondition"><where>${table.primaryColumn.name} = ${'#'}${'{'}${table.primaryColumn.name}${'}'}</where></sql><!-- 全部列名 --><sql id="Base_Column_List" ><#list columns as column>${column.dbName}<#if column_has_next>,</#if></#list></sql><!-- 通用条件判断 --><sql id="selectByCondition_where"><where><#list columns as column><if test="${column.name}!=null"><#if column_index != 0> and </#if>${column.dbName} = ${'#'}{${column.name}}</if></#list></where><if test="orderBy!=null">order by ${r'#{orderBy}'}</if><if test="skipCount != null and pageSize != null">LIMIT ${r'#{skipCount}'}${r'#{pageSize}'}</if></sql><!--***************************自动生成的代码区域 结束**************************--></mapper>

service也没啥 就是调调基类的方法

最后搞个页面把

${r'<@c.header/>'}
<script type="text/javascript">$(function(){$("#searchBtn").click(function(){$("#searchForm").attr("action","${r'${request.contextPath}'}${table.actionRequestMapping}index.do");$("#searchForm").submit();});$("#createBtn").click(function(){$("#searchForm").attr("action","${r'${request.contextPath}'}${table.actionRequestMapping}build.do");$("#searchForm").submit();});$("#deleteBtn").click(function(){confirm("你确定要删除吗?","confirmTip",function(){if($("input[group='idGroup']:checked").length > 0){var array = new Array();$("input[group='idGroup']:checked").each(function(){array.push(this.value);});$("#searchForm").attr("action","${r'${request.contextPath}'}${table.actionRequestMapping}delete.do?ids="+array.toString());$("#searchForm").submit();}else{Alert('请选择要删除的数据!','alertTip');}});})});    <#list columns as column><#if column.name=="state">function stateUpdate(id,state){$("#searchForm").attr("action","${r'${request.contextPath}'}${table.actionRequestMapping}stateUpdate.do?id="+id+"&state="+state);$("#searchForm").submit();}</#if></#list>
</script>
<div class="admin-content"><div class="admin-biaogelist"><div class="listbiaoti am-cf contextposition"><dl class="am-icon-home topposition"> 当前位置:管理><a href="Javascript: void(0);">${table.tableComment}管理</a></dl></div> <form id="searchForm" name="searchForm" method="post"><input type="hidden" id="curPage" name="curPage" value="${r'${form.curPage}'} "><div class="am-g" id="form" ><div class="am-u-md-12 searchbuttondiv"><div class="am-btn-toolbars am-btn-toolbar am-kg am-cf serchbuttontoolbardiv"><ul><li><div class=""><button id="searchBtn" type="button" class="am-btn am-btn-secondary am-btn-md am-margin-right-sm am-margin-bottom-sm"><span class="am-icon-search"></span> 搜索</button>${r'<@shiro.hasPermission name="'}${table.entityName}${r':delete">'} <button id="deleteBtn" type="button" class="am-btn am-btn-warning am-btn-md am-margin-right-sm am-margin-bottom-sm"><span class="am-icon-trash"></span> 删除</button>${r'</@shiro.hasPermission>'}${r'<@shiro.hasPermission name="'}${table.entityName}${r':add">'} <button id="createBtn" type="button" class="am-btn am-btn-success am-btn-md am-margin-right-sm am-margin-bottom-sm"><span class="am-icon-plus"></span> 新 增</button>${r'</@shiro.hasPermission>'}</div></li></ul></div></div></div></form>  <form class="am-form am-g" id="contextForm" name="contextForm"><table width="100%" id="headlocktable" class="am-table am-table-bordered am-table-radius am-table-striped am-table-hover am-text-center"><thead class="fixed-thead"><tr class="" class="index-table-head"><th class="table-check am-text-center contexttd"><input type="checkbox" οnclick="formcheckclick(this)"/></th><#list columns as column><#if column.name!="id"&&column.name!="createdAt"&&column.name!="updatedAt"&&column.comment?index_of("[imgs]")==-1&&column.comment?index_of("[richtextarea]")==-1><th class="table-title am-text-center contexttd">${column.comment?replace('[textarea]','')}<!--<a href="javascript:sort('${column.dbName}','${r'${sort}'}')">${column.comment}</a>--></th></#if></#list><th style="width:200px;" class="table-set am-text-center contexttd">操作</th> </tr> </thead><tbody class="scroll-tbody">${r'<#list page.data as obj>'}<tr><td class="table-check am-text-center contexttd"><input type="checkbox"  group="idGroup" value="${r'${obj'}.id}"/></td><#list columns as column><#if column.name!="createdAt"&&column.name!="updatedAt"&&column.comment?index_of("[imgs]")==-1><#if column.javaType=="Date"><td class="table-title-id am-text-center contexttd">${r'${obj.'}${column.name}?datetime}</td><#elseif column.name=="id"><#elseif column.name=="state"><td class="table-title-id am-text-center contexttd">${r'${obj.state.desc}'}</td><#elseif column.comment?index_of("[img]")!=-1><td class="table-title am-text-center contexttd">${r'<#if obj.'}${column.name}${r'??>'}<img src='${r'${obj.'}${column.name}${r'Path}'}'/>${r'</#if>'}</td><#elseif column.comment?index_of("[richtextarea]")!=-1><#else>    <td class="table-title-id am-text-center contexttd">${r'${obj.'}${column.name}}</td></#if></#if></#list><td class="am-text-center contexttd"><div class="am-btn-toolbar"><div class="am-btn-group am-btn-group-xs nofloat" >${r'<@shiro.hasPermission name="'}${table.entityName}${r':show">'}<button title="查看" class="am-btn am-btn-default am-btn-xs am-round" type="button" οnclick="javascript:showData(${r'${obj.id}'});"><a href="javascript:void(0);" ><span class="am-icon-search am-text-success"></span></a></button>${r'</@shiro.hasPermission>'}${r'<@shiro.hasPermission name="'}${table.entityName}${r':edit">'}<button title="修改" class="am-btn am-btn-default am-btn-xs  am-round" type="button" οnclick="javascript:updateData(${r'${obj.id}'});"><a href="javascript:void(0);" ><span class="am-icon-edit am-text-secondary"></span></a></button>${r'</@shiro.hasPermission>'}${r'<@shiro.hasPermission name="'}${table.entityName}${r':delete">'} <button title="删除" class="am-btn am-btn-default am-btn-xs   am-round" type="button" οnclick="javascript:deleteData(${r'${obj.id}'});"><a href="javascript:void(0);" ><span class="am-icon-trash am-text-warning"></span></a></button>${r'</@shiro.hasPermission>'}<#list columns as column><#if column.name=="state">${r'<@shiro.hasPermission name="'}${table.entityName}${r':edit">'}${r'<#if obj.state.value==0>'}<button title="启用" class="am-btn am-btn-default am-btn-xs   am-round" type="button" οnclick="javascript:stateUpdate(${r'${obj.id}'},1);"><a href="javascript:void(0);" ><span class="am-icon-rocket am-text-secondary"></span></a></button>${r'<#else>'}<button title="禁用" class="am-btn am-btn-default am-btn-xs   am-round" type="button" οnclick="javascript:stateUpdate(${r'${obj.id}'},0);"><a href="javascript:void(0);" ><span class="am-icon-ban am-text-secondary" style="color:gray"></span></a></button>${r'</#if>'}${r'</@shiro.hasPermission>'}</#if></#list></div></div></td></tr>${r'</#list>'}</tbody></table><div class="am-u-sm-7 am-u-md-7 am-u-lg-7 am-margin-bottom-sm tabletail"><p class="am-margin-top-sm am-margin-bottom-sm"><span class="remarktext"> 备注:操作图标含义</span><a class="am-icon-search remarkshow" title="查看"> 查看</a>   <a class="am-icon-edit remarkedit" title="修改">修改</a>   <a class="am-icon-trash remarkdelete" title="删除"> 删除</a>    <#list columns as column><#if column.name=="state"><a class="am-icon-rocket" style="color:#0e90d2" title="启用"> 启用</a>    <a class="am-icon-ban" style="color:gray" title="禁用"> 禁用</a>    </#if></#list></p></div><div class="am-u-sm-5 am-u-md-5 am-u-lg-5 am-margin-bottom-sm tabletail">${r'<@c.pagination/>'}</div></form></div>
</div>
${r'<@c.footer/>'}

总结

萌新第一次发博客 应该会有很多错别字 而且排版也会不人道 请大家多多见谅

看文章的小伙伴 请尽量帮忙优化和去除繁杂代码 比如写出文件也可以开线程等

谢谢大家 希望能收到大家的建议

代码生成工具jdbc+freemarker+swing相关推荐

  1. 一款自定义模版的代码生成工具

    codegen 一款自定义模版(freemarker)的代码生成工具 快速入门 clone代码 git clone git@github.com:YaoLin1/codegen.git 编译 在cod ...

  2. Hibernate代码生成工具 设计全攻略

    1.简述Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,提供HQL查询语言,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.使用Hibernat ...

  3. mybatis java8_Java 8 开发的 Mybatis 注解代码生成工具

    MybatisAnnotationTools MybatisAnnotationTools 是基于 Java8 开发的一款可以用于自动化生成 MyBatis 注解类的工具,支持配置数据源.类路径,表名 ...

  4. 使用iBatis的自动化代码生成工具Abator

    原来还不知道iBatis也有像Hibernate类似的自动化代码生成工具,今天找到Abator这工具也挺不错的,在ecelipse上面小试了一把: 1.获得Abator http://ibatis.a ...

  5. 支持自定义代码生成工具

    项目地址 https://github.com/kylin-hunter/k-commons/tree/main/k-code-generator 文章目录 项目地址 前言 一.架构 二.使用步骤 1 ...

  6. ZeusAutoCode代码生成工具(开源)

    ZeusAutoCode代码生成工具 一.简介 Zeus代码生成器是一款自动代码生成工具,旨在快速生成基础的CRUD代码,在此基础上也提供了一些高级功能,做到灵活配置,生成可扩展性强的代码. 后端是基 ...

  7. 狼奔代码生成工具使用心得

    狼奔代码生成工具(http://ltfwan.d33140.jit8.cn)是一款为程序员设计的代码生成器,更是一款软件项目智能开发平台,它可以自动生成ASP.NET页面及后台代码,采用了面向服务的架 ...

  8. 调整代码生成工具Database2Sharp的Winform界面生成,使其易于列表工具栏的使用。...

    在Winform界面开发的时候,有时候我们客户喜欢把功能放在列表界面的顶部,这样界面和功能整齐放置,也是一种比较美观的方式,基于这种方式的考虑,改造了代码生成工具的Winform界面生成规则,把增删改 ...

  9. CLR_via_C#.3rd 翻译[1.5 本地代码生成工具NGen.exe]

    1.5 The Native Code Generator Tool: NGen.exe 本地代码生成工具NGen.exe NGen.exe是和.NET框架绑定在一起的.当用户的机器上安装了一个应用程 ...

最新文章

  1. 百度搜索引擎广告SEM调用架构示意图
  2. 如何调试Android Native Framework
  3. 下载python的步骤ios_下载及安装Python详细步骤
  4. Spring简单总结
  5. erlang精要(5)-列表推导式
  6. P5707 【深基2.例12】上学迟到(python3实现)
  7. 解决tomcat不支持中文路径的问题
  8. 用三国杀讲分布式算法,太舒适了吧?
  9. hdu 1232 经典并查集应用
  10. ADB与按键精灵手机助手连接手机调试问题记录
  11. C语言显示图书信息的讲解,C语言图书信息管理系统解析.pdf
  12. 自己用java写一个http和https代理服务器
  13. Java mail outlook发邮件提示升级TLS1.2
  14. 关于微信小程序自定义交易组件升级处理的相关问题,及解决思路
  15. Node.js Web 模块(客户端 服务端实例)
  16. “美国国家标准化组织(ANSI)”是一个核准多种行业标准的组织,我们可以把数据库看成这样一种有组织的机制
  17. Windows应急响应
  18. C语言实现埃拉托色尼筛选法(剔除数组中的非质数)
  19. S3DIS 点云数据集的手动修复问题
  20. PDF Search for Mac(PDF文件搜索工具)

热门文章

  1. C# 调用Windows media play 播放器方法
  2. 关于傅立叶系数的计算公式
  3. 使用系统打印服务器配置,打印服务器配置教程.pdf
  4. SilverLight合计行设计
  5. cube的意思中文翻译_cube是什么意思_cube的翻译_音标_读音_用法_例句_爱词霸在线词典...
  6. 数据结构—查找(顺序查找和折半查找)
  7. java点击车次显示详情_Web项目专项训练——火车车次信息管理系统代码分享
  8. 使用自定义RRT*全局规划器建图导航
  9. python 存储bmp格式图片
  10. canvas坐标转换屏幕坐标_Canvas坐标系转换