软件编程
位置:首页>> 软件编程>> java编程>> Java SpringBoot实现带界面的代码生成器详解

Java SpringBoot实现带界面的代码生成器详解

作者:一只y  发布时间:2023-09-28 11:54:14 

标签:SpringBoot,代码生成器
目录
  • 1.项目gitthub地址链接: https://github.com/baisul/generateCode.git切换到master分支

  • 2.环境

  • 2.1 springboot+freemarker+mysql

  • 2.2 要装node.js,vue文件运行依赖node.js

  • 3.以下就只拿生成java实体类来作为例子

  • 4.application.xml

  • 5.pom.xml

  • 6.Utils

  • 7.生成模板

  • 8.Controller

  • 9.Model

  • 10.index.html(数据库连接生成代码的界面)

  • 11.接口

  • 12.图形化界面

  • 总结

1.项目gitthub地址链接: https://github.com/baisul/generateCode.git切换到master分支

2.环境

2.1 springboot+freemarker+mysql

2.2 要装node.js,vue文件运行依赖node.js

3.以下就只拿生成java实体类来作为例子

4.application.xml


server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

5.pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.5.4</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.yl</groupId>
   <artifactId>generate_code</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>generate_code</name>
   <description>Demo project for Spring Boot</description>
   <properties>
       <java.version>1.8</java.version>
   </properties>
   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-freemarker</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <scope>runtime</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>com.google.guava</groupId>
           <artifactId>guava</artifactId>
           <version>30.1-jre</version>
       </dependency>
   </dependencies>
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>
</project>

6.Utils


package com.yl.generate_code.utils;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
public class CORFSConfiguration extends WebMvcConfigurerAdapter {
   @Override
   public void addCorsMappings(CorsRegistry registry) {
       //所有请求都允许跨域
       registry.addMapping("/**")
               .allowedOrigins("*")
               .allowedMethods("*")
               .allowedHeaders("*");
   }
}

package com.yl.generate_code.utils;
import com.yl.generate_code.model.Db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtils {
   private static Connection connection;
   public static Connection getConnection() {
       return connection;
   }
   public static Connection init(Db db) {
       if (connection == null) {
           try {
               Class.forName("com.mysql.cj.jdbc.Driver");
               connection = DriverManager.getConnection( db.getUrl(),db.getUsername(), db.getPassword());
           } catch (ClassNotFoundException e) {
               e.printStackTrace();
           } catch (SQLException e) {
               e.printStackTrace();
           }
       }
       return connection;
   }
}

7.生成模板


package ${packetName}.model;
import java.util.Date;
/**
* @Description: ${modelName}实体类
* @Author: wfj
* @CreateDate ${createDate}
* @Version: 1.0V
*/
public class ${modelName} {
   <#if columns??>
       <#list columns as column>
           <#if column.type='VARCHAR' || column.type='TEXT' || column.type='CHAR'>
               /**
               * ${column.remark}
               */
               private String ${column.propertyName?uncap_first};
           </#if>
           <#if column.type='INT'>
               /**
               * ${column.remark}
               */
               private Integer ${column.propertyName?uncap_first};
           </#if>
           <#if column.type='DATETIME'>
               /**
               * ${column.remark}
               */
               private Date ${column.propertyName?uncap_first};
           </#if>
           <#if column.type='BIGINT'>
               /**
               * ${column.remark}
               */
               private Long ${column.propertyName?uncap_first};
           </#if>
           <#if column.type='DOUBLE'>
               /**
               * ${column.remark}
               */
               private Double ${column.propertyName?uncap_first};
           </#if>
           <#if column.type='BIT'>
               /**
               * ${column.remark}
               */
               private Boolean ${column.propertyName?uncap_first};
           </#if>
       </#list>
       <#list columns as column>
           <#if column.type='VARCHAR' || column.type='TEXT' || column.type='CHAR'>
              public String get${column.propertyName}() {
                   return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(String ${column.propertyName?uncap_first}) {
                   this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
           <#if column.type='INT'>
               public Integer get${column.propertyName}() {
               return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(Integer ${column.propertyName?uncap_first}) {
               this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
           <#if column.type='DATETIME'>
               public Date get${column.propertyName}() {
               return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(Date ${column.propertyName?uncap_first}) {
               this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
           <#if column.type='BIGINT'>
               public Long get${column.propertyName}() {
               return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(Long ${column.propertyName?uncap_first}) {
               this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
           <#if column.type='DOUBLE'>
               public Double get${column.propertyName}() {
               return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(Double ${column.propertyName?uncap_first}) {
               this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
           <#if column.type='BIT'>
               public Boolean get${column.propertyName}() {
               return ${column.propertyName?uncap_first};
               }
               public void set${column.propertyName}(Boolean ${column.propertyName?uncap_first}) {
               this.${column.propertyName?uncap_first} = ${column.propertyName?uncap_first};
               }
           </#if>
       </#list>
   </#if>
}

8.Controller


package com.yl.generate_code.controller;
import com.google.common.base.CaseFormat;
import com.yl.generate_code.model.Db;
import com.yl.generate_code.model.ResultModel;
import com.yl.generate_code.model.TableClass;
import com.yl.generate_code.utils.DBUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
public class DBController {
   @PostMapping("/connect")
   public ResultModel connect(@RequestBody Db db) {
       Connection connection = DBUtils.init(db);
       if (connection == null) {
           return ResultModel.fail("数据库连接失败");
       } else {
           return ResultModel.success("数据库连接成功");
       }
   }
   @PostMapping("/config")
   public ResultModel config(@RequestBody Map<String,Object> map) {
       String packetName = (String)map.get("packetName");
       try {
           //获取数据库连接
           Connection connection = DBUtils.getConnection();
           //获取数据库元数据
           DatabaseMetaData metaData = connection.getMetaData();
           //获取数据库所有的表
           ResultSet rs = metaData.getTables(connection.getCatalog(), null, null, null);
           List<TableClass> list = new ArrayList<>();
           while (rs.next()) {
               TableClass tableClass = new TableClass();
               tableClass.setPacketName(packetName);
               //获取表名
               String tableName = rs.getString("TABLE_NAME");
               //数据库表下划线的字段转成驼峰,且首字母大写
               String modelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName);
               tableClass.setTableName(tableName);
               tableClass.setModelName(modelName);
               tableClass.setServiceName(modelName + "Service");
               tableClass.setMapperName(modelName + "Mapper");
               tableClass.setControllerName(modelName + "Controller");
               list.add(tableClass);
           }
           return ResultModel.success("数据库信息读取成功",list);
       } catch (SQLException e) {
           e.printStackTrace();
           return ResultModel.fail("数据库信息读取失败");
       }
   }
}

package com.yl.generate_code.controller;
import com.yl.generate_code.model.ResultModel;
import com.yl.generate_code.model.TableClass;
import com.yl.generate_code.service.GenerateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
public class GenerateCodeController {
   @Autowired
   private GenerateCodeService generateCodeService;
   @PostMapping("/generateCode")
   public ResultModel generateCode(@RequestBody List<TableClass> list, HttpServletRequest request) {
       return generateCodeService.generateCode(list,request.getServletContext().getRealPath("/"));
   }
}

9.Model


package com.yl.generate_code.model;
import java.io.Serializable;
public class ColumnClass implements Serializable {
   //实体类属性名
   private String propertyName;
   //实体类属性名对应的表的字段名
   private String columnName;
   //字段类型
   private String type;
   //备注
   private String remark;
   //该字段是否为主键
   private Boolean isPrimary;
   public String getPropertyName() {
       return propertyName;
   }
   public void setPropertyName(String propertyName) {
       this.propertyName = propertyName;
   }
   public String getColumnName() {
       return columnName;
   }
   public void setColumnName(String columnName) {
       this.columnName = columnName;
   }
   public String getType() {
       return type;
   }
   public void setType(String type) {
       this.type = type;
   }
   public String getRemark() {
       return remark;
   }
   public void setRemark(String remark) {
       this.remark = remark;
   }
   public Boolean getPrimary() {
       return isPrimary;
   }
   public void setPrimary(Boolean primary) {
       isPrimary = primary;
   }
   @Override
   public String toString() {
       return "ColumnClass{" +
               "propertyName='" + propertyName + '\'' +
               ", columnName='" + columnName + '\'' +
               ", type='" + type + '\'' +
               ", remark='" + remark + '\'' +
               ", isPrimary=" + isPrimary +
               '}';
   }
}

package com.yl.generate_code.model;
import java.io.Serializable;
public class Db implements Serializable {
   private String username;
   private String password;
   private String url;
   public String getUsername() {
       return username;
   }
   public void setUsername(String username) {
       this.username = username;
   }
   public String getPassword() {
       return password;
   }
   public void setPassword(String password) {
       this.password = password;
   }
   public String getUrl() {
       return url;
   }
   public void setUrl(String url) {
       this.url = url;
   }
}

package com.yl.generate_code.model;
import java.io.Serializable;
public class ResultModel implements Serializable {
   private Integer code;
   private String msg;
   private Object obj;
   public static ResultModel success(String msg,Object obj) {
       return new ResultModel(200,msg,obj);
   }
   public static ResultModel success(String msg) {
       return new ResultModel(200,msg,null);
   }
   public static ResultModel fail(String msg,Object obj) {
       return new ResultModel(500,msg,obj);
   }
   public static ResultModel fail(String msg) {
       return new ResultModel(500,msg,null);
   }
   private ResultModel() {
   }
   public ResultModel(Integer code, String msg, Object obj) {
       this.code = code;
       this.msg = msg;
       this.obj = obj;
   }
   public Integer getCode() {
       return code;
   }
   public void setCode(Integer code) {
       this.code = code;
   }
   public String getMsg() {
       return msg;
   }
   public void setMsg(String msg) {
       this.msg = msg;
   }
   public Object getObj() {
       return obj;
   }
   public void setObj(Object obj) {
       this.obj = obj;
   }
}

package com.yl.generate_code.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TableClass implements Serializable {
   private String tableName;
   private String modelName;
   private String serviceName;
   private String mapperName;
   private String controllerName;
   private String packetName;
   private String createDate;
   private List<ColumnClass> columns = new ArrayList<>();
   public String getTableName() {
       return tableName;
   }
   public void setTableName(String tableName) {
       this.tableName = tableName;
   }
   public String getModelName() {
       return modelName;
   }
   public void setModelName(String modelName) {
       this.modelName = modelName;
   }
   public String getServiceName() {
       return serviceName;
   }
   public void setServiceName(String serviceName) {
       this.serviceName = serviceName;
   }
   public String getMapperName() {
       return mapperName;
   }
   public void setMapperName(String mapperName) {
       this.mapperName = mapperName;
   }
   public String getControllerName() {
       return controllerName;
   }
   public void setControllerName(String controllerName) {
       this.controllerName = controllerName;
   }
   public String getPacketName() {
       return packetName;
   }
   public void setPacketName(String packetName) {
       this.packetName = packetName;
   }
   public List<ColumnClass> getColumns() {
       return columns;
   }
   public void setColumns(List<ColumnClass> columns) {
       this.columns = columns;
   }
   public String getCreateDate() {
       return createDate;
   }
   public void setCreateDate(String createDate) {
       this.createDate = createDate;
   }
}

10.index.html(数据库连接生成代码的界面)


<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <!--引入vue.js,elementui和axios-->
   <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
   <!-- 引入样式 -->
   <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
   <!-- 引入组件库 -->
   <script src="https://unpkg.com/element-ui/lib/index.js"></script>
   <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
   <table>
       <tr>
           <td><el-tag size="mini">数据库用户名:</el-tag></td>
           <td><el-input size="mini" v-model="db.username"></el-input></td>
       </tr>
       <tr>
           <td><el-tag size="mini">数据库密码:</el-tag></td>
           <td><el-input size="mini" v-model="db.password"></el-input></td>
       </tr>
       <tr>
           <td><el-tag size="mini">数据库连接地址:</el-tag></td>
           <td><el-input size="mini" v-model="db.url">
               <template slot="prepend">jdbc:mysql://</template>
               <template slot="append">?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai</template>
           </el-input></td>
       </tr>
   </table>
   <div style="display: flex">
       <el-button type="primary" size="mini" @click="connect" :disabled="!enableButton">连接数据库</el-button>
       <div style="color: red;font-weight: bold" >{{msg}}</div>
       <el-input v-model="packetName" size="mini" style="width:300px"></el-input>
       <el-button size="mini" type="primary" @click="config">配置</el-button>
   </div>
   <el-table
           :data="tableData"
           stripe
           border
           style="width: 100%">
       <el-table-column
               prop="tableName"
               label="表名称"
               width="180">
       </el-table-column>
       <el-table-column
               label="实体类名称"
               width="180">
           <template slot-scope="scope">
               <el-input v-model="scope.row.modelName"></el-input>
           </template>
       </el-table-column>
       <el-table-column
               label="mapper名称">
           <template slot-scope="scope">
               <el-input v-model="scope.row.mapperName"></el-input>
           </template>
       </el-table-column>
       <el-table-column
               label="service名称">
           <template slot-scope="scope">
               <el-input v-model="scope.row.serviceName"></el-input>
           </template>
       </el-table-column>
       <el-table-column
               label="controller名称">
           <template slot-scope="scope">
               <el-input v-model="scope.row.controllerName"></el-input>
           </template>
       </el-table-column>
   </el-table>
   <div>
       <el-button type="success" size="mini" @click="generateCode">生成代码</el-button>
       <div style="color: green;font-weight: bold">{{result}}</div>
       <div>{{codePath}}</div>
   </div>
</div>
<script>
   new Vue({
       el:"#app",
       data() {
           return{
               result: '',
               codePath: '',
               tableData:[],
               packetName: 'com.yl',
               msg : "数据库未连接",
               enableButton: true,
               db: {
                   username: "root",
                   password: "root",
                   url : "localhost:3306/demo"
               }
           }
       },
       methods: {
           connect() {
               let _this = this
               this.db.url = "jdbc:mysql://" + this.db.url + "?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"
               axios.post("/connect",this.db).then(res => {
                   console.log(res.data)
                   _this.db = {
                       username: "root",
                       password: "root",
                       url : "localhost:3306/demo"
                   }
                   _this.msg = res.data.msg
                   _this.enableButton = false
               }).catch(err => {
                   console.log(err)
               })
           },
           config() {
               let _this = this
               axios.post("/config",{packetName: _this.packetName}).then(res => {
                   console.log(res.data)
                   _this.msg = res.data.msg
                   _this.tableData = res.data.obj
               }).catch(err => {
                   console.log(err)
               })
           },
           generateCode() {
               let _this = this
               axios.post("/generateCode",_this.tableData).then(res => {
                   console.log(res.data)
                   _this.result = res.data.msg
                   _this.codePath = res.data.obj
               }).catch(err => {
                   console.log(err)
               })
           }
       }
   })
</script>
</body>
</html>

11.接口


package com.yl.generate_code.service;
import com.yl.generate_code.model.ResultModel;
import com.yl.generate_code.model.TableClass;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public interface GenerateCodeService {
   ResultModel generateCode(List<TableClass> list, String realpath);
}

package com.yl.generate_code.service.impl;
import com.google.common.base.CaseFormat;
import com.yl.generate_code.model.ColumnClass;
import com.yl.generate_code.model.ResultModel;
import com.yl.generate_code.model.TableClass;
import com.yl.generate_code.service.GenerateCodeService;
import com.yl.generate_code.utils.DBUtils;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class GenerateCodeServiceImpl implements GenerateCodeService {
   Configuration cfg = null;
   {
       cfg = new Configuration(Configuration.VERSION_2_3_31);
       cfg.setTemplateLoader(new ClassTemplateLoader(GenerateCodeServiceImpl.class,"/templates"));
       cfg.setDefaultEncoding("utf-8");
   }
   @Override
   public ResultModel generateCode(List<TableClass> list, String realpath) {
       try {
           Template modelTemplate = cfg.getTemplate("Model.java.ftl");
           Template serviceTemplate = cfg.getTemplate("Service.java.ftl");
           Template serviceImplTemplate = cfg.getTemplate("ServiceImpl.java.ftl");
           Template mapperTemplate = cfg.getTemplate("Mapper.java.ftl");
           Template mapperXmlTemplate = cfg.getTemplate("Mapper.xml.java.ftl");
           Template controllerTemplate = cfg.getTemplate("Controller.java.ftl");
           Connection connection = DBUtils.getConnection();
           DatabaseMetaData metaData = connection.getMetaData();
           for (TableClass tableClass : list) {
               //根据表名获取该表的所有字段
               ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableClass.getTableName(), null);
               //获取该表的所有主键
               ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), null, tableClass.getTableName());
               List<ColumnClass> columnClasses = new ArrayList<>();
               while (columns.next()) {
                   //获取字段名
                   String column_name = columns.getString("COLUMN_NAME");
                   //获取字段类型
                   String type_name = columns.getString("TYPE_NAME");
                   //获取字段注释
                   String remark = columns.getString("REMARKS");
                   ColumnClass columnClass = new ColumnClass();
                   columnClass.setColumnName(column_name);
                   columnClass.setType(type_name);
                   columnClass.setRemark(remark);
                   columnClass.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL,column_name));
                   //指标挪到第一
                   primaryKeys.first();
                   while (primaryKeys.next()) {
                       String primaryKey = primaryKeys.getString("COLUMN_NAME");
                       if (column_name.equals(primaryKey)) {
                           columnClass.setPrimary(true);
                       }
                   }
                   columnClasses.add(columnClass);
               }
               tableClass.setColumns(columnClasses);
               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
               tableClass.setCreateDate(sdf.format(new Date()));
               String path = realpath + "/" + tableClass.getPacketName().replace(".","/");
               generate(modelTemplate,tableClass,path+"/model/",1);
               generate(serviceTemplate,tableClass,path+"/service/",1);
               generate(serviceImplTemplate,tableClass,path+"/service/impl",1);
               generate(mapperTemplate,tableClass,path+"/mapper/",1);
               generate(mapperXmlTemplate,tableClass,path+"/mapper/",2);
               generate(controllerTemplate,tableClass,path+"/controller/",1);
           }
           return ResultModel.success("代码已生成",realpath);
       } catch (Exception e) {
           e.printStackTrace();
           return ResultModel.fail("代码生成失败");
       }
   }
   private void generate(Template template,TableClass tableClass,String path,Integer flag) throws IOException, TemplateException {
       File file = new File(path);
       if (!file.exists()) {
           file.mkdirs();
       }
       String fileName;
       if (flag == 1) {
           fileName = path + "/" + tableClass.getModelName() + template.getName().replace(".ftl","").replace("Model","");
       } else {
           fileName = path + "/" + tableClass.getModelName() + template.getName().replace(".ftl","").replace(".java","");
       }
       FileOutputStream fos = new FileOutputStream(fileName);
       OutputStreamWriter  out = new OutputStreamWriter(fos);
       template.process(tableClass,out);
       fos.close();
       out.close();
   }
}

12.图形化界面

Java SpringBoot实现带界面的代码生成器详解

来源:https://blog.csdn.net/weixin_41359273/article/details/120356930

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com