前言
公司比较小,为了节约成本,所以在领导授意下做了这个。
相对现在存在的各种自动生成框架来说,自己做的用起来更舒服一点,想怎么改就这么改。
什么前端 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;//dao
private String daoFirstLowerName;
private String serviceName;//service
private String serviceFirstLowerName;
private String formName;//表单名称
private String mapperName;//mapper
private String actionName;//action
private String apiName;//接口
private String apiUserName;//用户权限接口
private String daoPackageName;//dao包名
private String entityPackageName;//entity
private String formPackageName;//表单
private String mapperPackageName;//mapper
private String servicePackageName;//service
private String actionPackageName;//action
private 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 block
e.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:springmvc
String 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 block
e.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.tnzt
private 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));
}
}
/**
* 用户操作监听(点了生成按钮)
*/
@Override
public 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;
}
@Override
public 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);
}
@Override
public 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}";
@Autowired
private LockService lockService;
@Autowired
private ${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" >
select
count(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/>'}
总结
萌新第一次发博客 应该会有很多错别字 而且排版也会不人道 请大家多多见谅
看文章的小伙伴 请尽量帮忙优化和去除繁杂代码 比如写出文件也可以开线程等
谢谢大家 希望能收到大家的建议