教你用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的代碼生成器
前言
逆向工程從數(shù)據(jù)庫(kù)表直接生成代碼,是日常開發(fā)中常用的敏捷開發(fā)手段,常見的例如:mybatis-plus的代碼生成器等
為什么要自己寫代碼生成器呢?MP的生成器不香嗎?香!
但是自己寫的工具用起來最順手,可以隨意擴(kuò)展,想怎么玩就怎么玩,只要自己有想法,玩出花來都沒問題,當(dāng)然了,能力有限,現(xiàn)在還只能實(shí)現(xiàn)簡(jiǎn)單版本,更多騷操作自己發(fā)揮!
思路:
1、建立jdbc連接,執(zhí)行查詢sql,獲取表結(jié)構(gòu)信息。
2、在指定的路徑上創(chuàng)建文件。
3、按照我們的布局排版要求,根據(jù)表結(jié)構(gòu)信息拼接文件的內(nèi)容。
4、將字符輸出到文件中。
以上即可完成一個(gè)文件的自動(dòng)生成
編碼
通用部分
幾個(gè)內(nèi)部工具類

file工具類:創(chuàng)建、讀取文件
字符串工具類:駝峰標(biāo)識(shí)、下劃線互轉(zhuǎn),首字母大寫,數(shù)據(jù)庫(kù)字段類型轉(zhuǎn)java類型等
jdbc連接:連接數(shù)據(jù)庫(kù)
表注釋、表結(jié)構(gòu)信息實(shí)體類、執(zhí)行sql獲取表結(jié)構(gòu)信息的方法

表結(jié)構(gòu)信息
private String columnName;//字段名 private String dataType;//字段類型 private String columnComment;//字段注釋 private String columnKey;//主鍵 private String extra;//主鍵類型
mysql查詢表注釋、表字段信息使用的是
表字段信息
SELECT
column_name,
data_type,
column_comment,
column_key,
extra
FROM
information_schema.COLUMNS
WHERE
table_schema = (
SELECT DATABASE
())
AND table_name =?
表注釋
SELECT
table_comment
FROM
information_schema.TABLES
WHERE
table_schema = (
SELECT DATABASE
())
AND table_name =?
需要支持其他數(shù)據(jù)庫(kù)類型的,自己調(diào)整就好了,例如oracle獲取表注釋、表結(jié)構(gòu)sql如下:
-- 表、表注釋
SELECT
t.table_name,
t1.comments
FROM
user_tables t
JOIN user_tab_comments t1 ON t.table_name = t1.table_name;
-- 表字段、字段注釋
SELECT
t.table_name,
c.column_name,
c.data_type,
cc.comments
FROM
USER_TAB_COLUMNS c
JOIN user_tables t ON c.table_name = t.table_name
JOIN user_col_comments cc ON cc.table_name = t.table_name
WHERE
cc.column_name = c.column_name;
另外,數(shù)據(jù)連接、基礎(chǔ)路徑的配置也是一樣
/** * 數(shù)據(jù)連接相關(guān),需要手動(dòng)設(shè)置 */ private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8"; private static final String USERNAME = "root"; private static final String PASSWORD = "123456"; private static final String DRIVER_CLASSNAME = "com.mysql.cj.jdbc.Driver"; /** * 基礎(chǔ)路徑,需要手動(dòng)設(shè)置 */ private String basePackage = "cn\\huanzi\\qch\\baseadmin\\";//根包位置 private String filePackage = basePackage + "sys\\";//文件所在包位置
2.0版本多一個(gè)模板文件路徑
private String tlfPath = System.getProperty("user.dir") + "\\src\\main\\resources\\tlf\\";//模板文件位置
main函數(shù)也一樣,調(diào)用構(gòu)造參數(shù),傳入表名,調(diào)用入口函數(shù)
public static void main(String[] args) {
// String[] tables = {"sys_user","sys_menu","sys_authority","sys_user_menu","sys_user_authority","sys_shortcut_menu","sys_setting"};
String[] tables = {"tb_user"};
for (String table : tables) {
String msg = new AutoGenerator(table).create();
System.out.println(msg);
}
}
V1.0版本
AutoGenerator,1.0版本采用原始的在代碼拼接字符串,然后創(chuàng)建文件將字符串輸出的方法,比較原始但個(gè)人覺得可玩性較高
幾個(gè)創(chuàng)建方法,就拿實(shí)體類來舉例

/**
* 創(chuàng)建pojo實(shí)體類
*/
private void createPojo(List<TableInfo> tableInfos) {
//創(chuàng)建文件
File file = FileUtil.createFile(filePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");
//拼接文件內(nèi)容
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "pojo;\n" +
"\n" +
"import lombok.Data;\n" +
"import javax.persistence.*;\n" +
"import java.io.Serializable;\n" +
"import java.util.Date;\n" +
"\n" +
"@Entity\n" +
"@Table(name = \"" + tableName + "\")\n" +
"@Data\n" +
"public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + " implements Serializable {\n"
);
//遍歷設(shè)置屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
stringBuffer.append(" @Id\n");
}
//自增
if ("auto_increment".equals(tableInfo.getExtra())) {
stringBuffer.append(" @GeneratedValue(strategy= GenerationType.IDENTITY)\n");
}
stringBuffer.append(" private ").append(StringUtil.typeMapping(tableInfo.getDataType())).append(" ").append(StringUtil.camelCaseName(tableInfo.getColumnName())).append(";//").append(tableInfo.getColumnComment()).append("\n\n");
}
stringBuffer.append("}");
//寫入文件內(nèi)容
FileUtil.fileWriter(file, stringBuffer);
}
其他的也一樣,無非就:創(chuàng)建文件、拼接文件內(nèi)容、輸出文件內(nèi)容
入口函數(shù),供main函數(shù)直接調(diào)用
/**
* 快速創(chuàng)建,供外部調(diào)用,調(diào)用之前先設(shè)置一下項(xiàng)目的基礎(chǔ)路徑
*/
private String create() {
System.out.println("生成路徑位置:" + filePath);
//獲取表信息
List<TableInfo> tableInfo = getTableInfo();
//開始生成代碼
createPojo(tableInfo);
createVo(tableInfo);
createRepository(tableInfo);
createService(tableInfo);
createController(tableInfo);
return tableName + " 后臺(tái)代碼生成完畢!";
}
V2.0版本
AutoGeneratorPlus,2.0版本升級(jí)了,設(shè)置了模板文件、文件內(nèi)容的字符串從模板讀取,再根據(jù)關(guān)鍵字替換參數(shù),最后再輸出到創(chuàng)建的文件中,這個(gè)版本就比較好理解,大部分的代碼生成器也都這樣干
需要先定義模板文件(文件名后綴無所謂,自己隨便定義),拿entity來舉例

package cn.huanzi.qch.baseadmin.sys.${entityToLowerCase}.pojo;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* ${tableComment} 實(shí)體類
*
* ${author}
* ${date}
*/
@Entity
@Table(name = "${tableName}")
@Data
public class ${entity} implements Serializable {
#for
#ifPri
#ifAutoIncrement
private ${tableInfo.dataType} ${tableInfo.columnName};//${tableInfo.columnComment}
#end
}
${},用于取參數(shù),替換成我們的值
#for、#if,循環(huán)遍歷表字段以及判斷是否為主鍵、是否主鍵自增
各種關(guān)鍵字隨便定義,我們?cè)谧x取模板文件處理時(shí)能對(duì)上就行
文件內(nèi)容處理

/**
* 讀取模板,設(shè)置內(nèi)容,生成文件
* @param templatePath 模板文件路徑
* @param outputFile 文件生成路徑
* @param tableInfos 表字段信息
* @param customParameter 自定義參數(shù)
*/
private void writer(String templatePath, String outputFile,List<TableInfo> tableInfos,Map<String,String> customParameter){
//主鍵
TableInfo prikey = new TableInfo();
//for循環(huán)標(biāo)識(shí)
boolean forFlag = false;
StringBuilder forContent = new StringBuilder();
//駝峰標(biāo)識(shí)映射后的表名
String replacement = StringUtil.captureName(StringUtil.camelCaseName(tableName));
//遍歷屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
prikey = tableInfo;
break;
}
}
try(FileReader fileReader = new FileReader(templatePath);
BufferedReader reader = new BufferedReader(fileReader)) {
//生成文件
File file = FileUtil.createFile(outputFile);
StringBuffer stringBuffer = new StringBuffer();
//讀取模板文件,拼接文件內(nèi)容
Object[] lines = reader.lines().toArray();
for (Object o : lines) {
String line = String.valueOf(o);
/* 設(shè)置值 */
//${tableName} 表名稱,例如:tb_user
if(line.contains("${tableName}")){
line = line.replaceAll("\\$\\{tableName}", tableName);
}
//${tableComment} 表注釋,例如:tb_user
if(line.contains("${tableComment}")){
line = line.replaceAll("\\$\\{tableComment}", tableComment);
}
//${entity} 實(shí)體類名稱,例如:TbUser
if(line.contains("${entity}")){
line = line.replaceAll("\\$\\{entity}", replacement);
}
//${entityFirstToLowerCase} 實(shí)體類名稱首字母小寫,例如:tbUser
if(line.contains("${entityFirstToLowerCase}")){
line = line.replaceAll("\\$\\{entityFirstToLowerCase}", StringUtil.camelCaseName(tableName));
}
//${entityToLowerCase} 實(shí)體類名稱全小寫,例如:tbuser
if(line.contains("${entityToLowerCase}")){
line = line.replaceAll("\\$\\{entityToLowerCase}", replacement.toLowerCase());
}
//${priDataType} 實(shí)體類主鍵類型,例如:String
if(line.contains("${priDataType}")){
line = line.replaceAll("\\$\\{priDataType}", StringUtil.typeMapping(prikey.getDataType()));
}
//處理自定義參數(shù)
line = customParameter(line,customParameter);
//先取得循環(huán)體的內(nèi)容
if(forFlag){
forContent.append(line).append("\n");
}
//是否為for循環(huán)遍歷表字段
if(line.contains("#for")){
forFlag = true;
}
if(line.contains("#end")){
forFlag = false;
line = line.replaceAll("#end", "");
}
//遍歷循環(huán)體的內(nèi)容,并設(shè)置值
if(!forFlag && forContent.length() > 0){
//遍歷表字段
for (TableInfo tableInfo : tableInfos) {
String tableColumns = forContent.toString()
//表字段信息:類型、名稱、注釋
.replaceAll("\\$\\{tableInfo.dataType}", StringUtil.typeMapping(tableInfo.getDataType()))
.replaceAll("\\$\\{tableInfo.columnName}", StringUtil.camelCaseName(tableInfo.getColumnName()))
.replaceAll("\\$\\{tableInfo.columnComment}", tableInfo.getColumnComment());
//清除多余#end,以及換行符
tableColumns = tableColumns.replaceAll("#end", "").replaceAll("\n", "");
//設(shè)置是否主鍵、是否自增
String pri = "",autoIncrement="";
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
pri = " @Id\n";
//自增id
if ("auto_increment".equals(tableInfo.getExtra())){
autoIncrement = "@GeneratedValue(strategy= GenerationType.IDENTITY)\n";
}
}
tableColumns = tableColumns
.replaceAll("#ifPri", pri)
.replaceAll("#ifAutoIncrement", autoIncrement);
//處理自定義參數(shù)
tableColumns = customParameter(tableColumns,customParameter);
//前補(bǔ)tab,后補(bǔ)換行符
stringBuffer.append(" ").append(tableColumns.trim()).append("\n\n");
}
//置空
forContent.setLength(0);
}
if(!forFlag){
stringBuffer.append(line).append("\n");
}
}
//寫入數(shù)據(jù)到到文件中
FileUtil.fileWriter(file, stringBuffer);
}catch (Exception e){
e.printStackTrace();
}
}
內(nèi)置了幾個(gè)重要參數(shù)
${tableName} 表名稱,例如:tb_user
${tableComment} 表注釋,例如:tb_user
${entity} 實(shí)體類名稱,例如:TbUser
${entityFirstToLowerCase} 實(shí)體類名稱首字母小寫,例如:tbUser
${entityToLowerCase} 實(shí)體類名稱全小寫,例如:tbuser
${priDataType} 實(shí)體類主鍵類型,例如:String
還有三個(gè)表字段信息:類型、名稱、注釋
${tableInfo.dataType}
${tableInfo.columnName}
${tableInfo.columnComment}
支持自定義參數(shù)Map<String,String> customParameter,例如模板文件中的注釋:
/**
* ${author}
* ${date}
*/
入口函數(shù)
/**
* 快速創(chuàng)建,供外部調(diào)用,調(diào)用之前先設(shè)置一下項(xiàng)目的基礎(chǔ)路徑
*/
private String create() {
System.out.println("生成路徑位置:" + filePath);
//獲取表信息
List<TableInfo> tableInfo = getTableInfo();
//駝峰標(biāo)識(shí)映射后的表名
String captureName = StringUtil.captureName(StringUtil.camelCaseName(tableName));
//自定義參數(shù)
HashMap<String, String> customParameter = new HashMap<>();
customParameter.put("author","作者:Auto Generator By 'huanzi-qch'");
customParameter.put("date","生成日期:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//讀取模板、生成代碼
writer(tlfPath+"controller.tlf",
filePath + "controller\\" + captureName + "Controller.java",
tableInfo,customParameter);
writer(tlfPath+"entity.tlf",
filePath + "pojo\\" + captureName + ".java",
tableInfo,customParameter);
writer(tlfPath+"entityvo.tlf",
filePath + "vo\\" + captureName + "Vo.java",
tableInfo,customParameter);
writer(tlfPath+"repository.tlf",
filePath + "repository\\" + captureName + "Repository.java",
tableInfo,customParameter);
writer(tlfPath+"service.tlf",
filePath + "service\\" + captureName + "Service.java",
tableInfo,customParameter);
writer(tlfPath+"serviceimpl.tlf",
filePath + "service\\" + captureName + "ServiceImpl.java",
tableInfo,customParameter);
return tableName + " 后臺(tái)代碼生成完畢!";
}
比較復(fù)雜的就是#for、#if的處理,我這里只是簡(jiǎn)單實(shí)現(xiàn),不過也完全夠我們用了
效果
V1.0版本

V2.0版本

后記
大部分項(xiàng)目的代碼都是可以復(fù)用的,特別是像我們這種封裝了一套通用代碼,單表直接繼承實(shí)現(xiàn)CRUD、分頁(yè)等功能,每個(gè)模塊高度相似的代碼,代碼生成器就成了敏捷開發(fā)中重要的一步,直接根據(jù)數(shù)據(jù)庫(kù)表生成我們想要的代碼,省去了一步步創(chuàng)建文件、復(fù)制粘貼文件內(nèi)容的繁瑣步驟,實(shí)現(xiàn)快速開發(fā)!
自己寫的代碼生成器,擴(kuò)展性更強(qiáng),滿足每個(gè)業(yè)務(wù)模塊的代碼要求不成問題
開源
在這里貼出完整代碼,全都在一個(gè)類里面,并且沒有其他依賴包,很純!
v1.0AutoGenerator

View Code
package cn.huanzi.qch.baseadmin.autogenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* 代碼生成工具 V1.0
*/
public class AutoGenerator {
/**
* 程序自動(dòng)設(shè)置
*/
private String tableName;//表名
private String tableComment;//表注釋
private String filePath;//最終文件生成位置
/**
* 數(shù)據(jù)連接相關(guān),需要手動(dòng)設(shè)置
*/
private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static final String DRIVER_CLASSNAME = "com.mysql.cj.jdbc.Driver";
/**
* 基礎(chǔ)路徑,需要手動(dòng)設(shè)置
*/
private String basePackage = "cn\\huanzi\\qch\\baseadmin\\";//根包位置
private String filePackage = basePackage + "sys\\";//文件所在包位置
/**
* 構(gòu)造參數(shù),設(shè)置表名
*/
private AutoGenerator(String tableName) {
//設(shè)置表名
this.tableName = tableName;
//文件所在包位置
filePackage = filePackage + StringUtil.camelCaseName(tableName).toLowerCase() + "\\";
//拼接完整最終位置 System.getProperty("user.dir") 獲取的是項(xiàng)目所在路徑,如果我們是子項(xiàng)目,則需要添加一層路徑
filePath = System.getProperty("user.dir") + "\\src\\main\\java\\" + filePackage;
}
/**
* 創(chuàng)建pojo實(shí)體類
*/
private void createPojo(List<TableInfo> tableInfos) {
//創(chuàng)建文件
File file = FileUtil.createFile(filePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");
//拼接文件內(nèi)容
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "pojo;\n" +
"\n" +
"import lombok.Data;\n" +
"import javax.persistence.*;\n" +
"import java.io.Serializable;\n" +
"import java.util.Date;\n" +
"\n" +
"@Entity\n" +
"@Table(name = \"" + tableName + "\")\n" +
"@Data\n" +
"public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + " implements Serializable {\n"
);
//遍歷設(shè)置屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
stringBuffer.append(" @Id\n");
}
//自增
if ("auto_increment".equals(tableInfo.getExtra())) {
stringBuffer.append(" @GeneratedValue(strategy= GenerationType.IDENTITY)\n");
}
stringBuffer.append(" private ").append(StringUtil.typeMapping(tableInfo.getDataType())).append(" ").append(StringUtil.camelCaseName(tableInfo.getColumnName())).append(";//").append(tableInfo.getColumnComment()).append("\n\n");
}
stringBuffer.append("}");
//寫入文件內(nèi)容
FileUtil.fileWriter(file, stringBuffer);
}
/**
* 創(chuàng)建vo類
*/
private void createVo(List<TableInfo> tableInfos) {
File file = FileUtil.createFile(filePath + "vo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo.java");
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "vo;\n" +
"\n" +
"import "+ basePackage.replaceAll("\\\\", ".") +" common.pojo.PageCondition;"+
"import lombok.Data;\n" +
"import java.io.Serializable;\n" +
"import java.util.Date;\n" +
"\n" +
"@Data\n" +
"public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo extends PageCondition implements Serializable {\n"
);
//遍歷設(shè)置屬性
for (TableInfo tableInfo : tableInfos) {
stringBuffer.append(" private ").append(StringUtil.typeMapping(tableInfo.getDataType())).append(" ").append(StringUtil.camelCaseName(tableInfo.getColumnName())).append(";//").append(tableInfo.getColumnComment()).append("\n\n");
}
stringBuffer.append("}");
FileUtil.fileWriter(file, stringBuffer);
}
/**
* 創(chuàng)建repository類
*/
private void createRepository(List<TableInfo> tableInfos) {
File file = FileUtil.createFile(filePath + "repository\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository.java");
StringBuffer stringBuffer = new StringBuffer();
String t = "String";
//遍歷屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
t = StringUtil.typeMapping(tableInfo.getDataType());
}
}
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "repository;\n" +
"\n" +
"import " + basePackage.replaceAll("\\\\", ".") + "common.repository.*;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
"import org.springframework.stereotype.Repository;\n" +
"\n" +
"@Repository\n" +
"public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository extends CommonRepository<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
);
stringBuffer.append("\n");
stringBuffer.append("}");
FileUtil.fileWriter(file, stringBuffer);
}
/**
* 創(chuàng)建service類
*/
private void createService(List<TableInfo> tableInfos) {
File file = FileUtil.createFile(filePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service.java");
StringBuffer stringBuffer = new StringBuffer();
String t = "String";
//遍歷屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
t = StringUtil.typeMapping(tableInfo.getDataType());
}
}
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "service;\n" +
"\n" +
"import " + basePackage.replaceAll("\\\\", ".") + "common.service.*;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
"\n" +
"public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service extends CommonService<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
);
stringBuffer.append("\n");
stringBuffer.append("}");
FileUtil.fileWriter(file, stringBuffer);
//Impl
File file1 = FileUtil.createFile(filePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl.java");
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1.append(
"package " + filePackage.replaceAll("\\\\", ".") + "service;\n" +
"\n" +
"import " + basePackage.replaceAll("\\\\", ".") + "common.service.*;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "repository." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository;\n" +
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.stereotype.Service;\n" +
"import org.springframework.transaction.annotation.Transactional;\n" +
"import javax.persistence.EntityManager;\n" +
"import javax.persistence.PersistenceContext;\n" +
"\n" +
"@Service\n" +
"@Transactional\n" +
"public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl extends CommonServiceImpl<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> implements " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service{"
);
stringBuffer1.append("\n\n");
stringBuffer1.append(
" @PersistenceContext\n" +
" private EntityManager em;\n");
stringBuffer1.append("" +
" @Autowired\n" +
" private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository " + StringUtil.camelCaseName(tableName) + "Repository;\n");
stringBuffer1.append("}");
FileUtil.fileWriter(file1, stringBuffer1);
}
/**
* 創(chuàng)建controller類
*/
private void createController(List<TableInfo> tableInfos) {
File file = FileUtil.createFile(filePath + "controller\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller.java");
StringBuffer stringBuffer = new StringBuffer();
String t = "String";
//遍歷屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
t = StringUtil.typeMapping(tableInfo.getDataType());
}
}
stringBuffer.append(
"package " + filePackage.replaceAll("\\\\", ".") + "controller;\n" +
"\n" +
"import " + basePackage.replaceAll("\\\\", ".") + "common.controller.*;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
"import " + filePackage.replaceAll("\\\\", ".") + "service." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service;\n" +
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.web.bind.annotation.*;\n" +
"\n" +
"@RestController\n" +
"@RequestMapping(\"/sys/" + StringUtil.camelCaseName(tableName) + "/\")\n" +
"public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller extends CommonController<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
);
stringBuffer.append("\n");
stringBuffer.append("" +
" @Autowired\n" +
" private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service " + StringUtil.camelCaseName(tableName) + "Service;\n");
stringBuffer.append("}");
FileUtil.fileWriter(file, stringBuffer);
}
/**
* file工具類
*/
private static class FileUtil {
/**
* 創(chuàng)建文件
*
* @param pathNameAndFileName 路徑跟文件名
* @return File對(duì)象
*/
private static File createFile(String pathNameAndFileName) {
File file = new File(pathNameAndFileName);
try {
//獲取父目錄
File fileParent = file.getParentFile();
if (!fileParent.exists()) {
fileParent.mkdirs();
}
//創(chuàng)建文件
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
file = null;
System.err.println("新建文件操作出錯(cuò)");
e.printStackTrace();
}
return file;
}
/**
* 字符流寫入文件
*
* @param file file對(duì)象
* @param stringBuffer 要寫入的數(shù)據(jù)
*/
private static void fileWriter(File file, StringBuffer stringBuffer) {
//字符流
try {
FileWriter resultFile = new FileWriter(file, false);//true,則追加寫入 false,則覆蓋寫入
PrintWriter myFile = new PrintWriter(resultFile);
//寫入
myFile.println(stringBuffer.toString());
myFile.close();
resultFile.close();
} catch (Exception e) {
System.err.println("寫入操作出錯(cuò)");
e.printStackTrace();
}
}
}
/**
* 字符串處理工具類
*/
private static class StringUtil {
/**
* 數(shù)據(jù)庫(kù)類型->JAVA類型
*
* @param dbType 數(shù)據(jù)庫(kù)類型
* @return JAVA類型
*/
private static String typeMapping(String dbType) {
String javaType;
if ("int|integer".contains(dbType)) {
javaType = "Integer";
} else if ("float|double|decimal|real".contains(dbType)) {
javaType = "Double";
} else if ("date|time|datetime|timestamp".contains(dbType)) {
javaType = "Date";
} else {
javaType = "String";
}
return javaType;
}
/**
* 駝峰轉(zhuǎn)換為下劃線
*/
private static String underscoreName(String camelCaseName) {
StringBuilder result = new StringBuilder();
if (camelCaseName != null && camelCaseName.length() > 0) {
result.append(camelCaseName.substring(0, 1).toLowerCase());
for (int i = 1; i < camelCaseName.length(); i++) {
char ch = camelCaseName.charAt(i);
if (Character.isUpperCase(ch)) {
result.append("_");
result.append(Character.toLowerCase(ch));
} else {
result.append(ch);
}
}
}
return result.toString();
}
/**
* 首字母大寫
*/
private static String captureName(String name) {
char[] cs = name.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
/**
* 下劃線轉(zhuǎn)換為駝峰
*/
private static String camelCaseName(String underscoreName) {
StringBuilder result = new StringBuilder();
if (underscoreName != null && underscoreName.length() > 0) {
boolean flag = false;
for (int i = 0; i < underscoreName.length(); i++) {
char ch = underscoreName.charAt(i);
if ("_".charAt(0) == ch) {
flag = true;
} else {
if (flag) {
result.append(Character.toUpperCase(ch));
flag = false;
} else {
result.append(ch);
}
}
}
}
return result.toString();
}
}
/**
* JDBC連接數(shù)據(jù)庫(kù)工具類
*/
private static class DBConnectionUtil {
static {
// 1、加載驅(qū)動(dòng)
try {
Class.forName(DRIVER_CLASSNAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 返回一個(gè)Connection連接
*/
static Connection getConnection() {
Connection conn = null;
// 2、連接數(shù)據(jù)庫(kù)
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 關(guān)閉Connection,Statement連接
*/
public static void close(Connection conn, Statement stmt) {
try {
conn.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 關(guān)閉Connection,Statement,ResultSet連接
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
try {
close(conn, stmt);
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 表結(jié)構(gòu)信息實(shí)體類
*/
private class TableInfo {
private String columnName;//字段名
private String dataType;//字段類型
private String columnComment;//字段注釋
private String columnKey;//主鍵
private String extra;//主鍵類型
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getColumnComment() {
return columnComment;
}
public void setColumnComment(String columnComment) {
this.columnComment = columnComment;
}
public String getColumnKey() {
return columnKey;
}
public void setColumnKey(String columnKey) {
this.columnKey = columnKey;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
/**
* 獲取表結(jié)構(gòu)信息
* 目前僅支持mysql
*/
private List<TableInfo> getTableInfo() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
ArrayList<TableInfo> list = new ArrayList<>();
try {
conn = DBConnectionUtil.getConnection();
//表字段信息
String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_schema = (select database()) and table_name=?";
ps = conn.prepareStatement(sql);
ps.setString(1, tableName);
rs = ps.executeQuery();
while (rs.next()) {
TableInfo tableInfo = new TableInfo();
//列名,全部轉(zhuǎn)為小寫
tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
//列類型
tableInfo.setDataType(rs.getString("data_type"));
//列注釋
tableInfo.setColumnComment(rs.getString("column_comment"));
//主鍵
tableInfo.setColumnKey(rs.getString("column_key"));
//主鍵類型
tableInfo.setExtra(rs.getString("extra"));
list.add(tableInfo);
}
//表注釋
sql = "select table_comment from information_schema.tables where table_schema = (select database()) and table_name=?";
ps = conn.prepareStatement(sql);
ps.setString(1, tableName);
rs = ps.executeQuery();
while (rs.next()) {
//表注釋
tableComment = rs.getString("table_comment");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(rs != null){
DBConnectionUtil.close(conn, ps, rs);
}
}
return list;
}
/**
* 快速創(chuàng)建,供外部調(diào)用,調(diào)用之前先設(shè)置一下項(xiàng)目的基礎(chǔ)路徑
*/
private String create() {
System.out.println("生成路徑位置:" + filePath);
//獲取表信息
List<TableInfo> tableInfo = getTableInfo();
//開始生成代碼
createPojo(tableInfo);
createVo(tableInfo);
createRepository(tableInfo);
createService(tableInfo);
createController(tableInfo);
return tableName + " 后臺(tái)代碼生成完畢!";
}
public static void main(String[] args) {
// String[] tables = {"sys_user","sys_menu","sys_authority","sys_user_menu","sys_user_authority","sys_shortcut_menu","sys_setting"};
String[] tables = {"tb_user"};
for (String table : tables) {
String msg = new AutoGenerator(table).create();
System.out.println(msg);
}
}
}
v2.0 AutoGeneratorPlus
View Code
package cn.huanzi.qch.baseadmin.autogenerator;
import java.io.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 代碼生成工具 V2.0
*/
public class AutoGeneratorPlus {
/**
* 程序自動(dòng)設(shè)置
*/
private String tableName;//表名
private String tableComment;//表注釋
private String filePath;//最終文件生成位置
/**
* 數(shù)據(jù)連接相關(guān),需要手動(dòng)設(shè)置
*/
private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static final String DRIVER_CLASSNAME = "com.mysql.cj.jdbc.Driver";
/**
* 基礎(chǔ)路徑,需要手動(dòng)設(shè)置
*/
private String tlfPath = System.getProperty("user.dir") + "\\src\\main\\resources\\tlf\\";//模板文件位置
private String basePackage = "cn\\huanzi\\qch\\baseadmin\\";//根包位置
private String filePackage = basePackage + "sys\\";//文件所在包位置
/**
* 構(gòu)造參數(shù),設(shè)置表名
*/
private AutoGeneratorPlus(String tableName) {
//設(shè)置表名
this.tableName = tableName;
//文件所在包位置
filePackage = filePackage + StringUtil.camelCaseName(tableName).toLowerCase() + "\\";
//拼接完整最終位置 System.getProperty("user.dir") 獲取的是項(xiàng)目所在路徑,如果我們是子項(xiàng)目,則需要添加一層路徑
filePath = System.getProperty("user.dir") + "\\src\\main\\java\\" + filePackage;
}
/**
* 讀取模板,設(shè)置內(nèi)容,生成文件
* @param templatePath 模板文件路徑
* @param outputFile 文件生成路徑
* @param tableInfos 表字段信息
* @param customParameter 自定義參數(shù)
*/
private void writer(String templatePath, String outputFile,List<TableInfo> tableInfos,Map<String,String> customParameter){
//主鍵
TableInfo prikey = new TableInfo();
//for循環(huán)標(biāo)識(shí)
boolean forFlag = false;
StringBuilder forContent = new StringBuilder();
//駝峰標(biāo)識(shí)映射后的表名
String replacement = StringUtil.captureName(StringUtil.camelCaseName(tableName));
//遍歷屬性
for (TableInfo tableInfo : tableInfos) {
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
prikey = tableInfo;
break;
}
}
try(FileReader fileReader = new FileReader(templatePath);
BufferedReader reader = new BufferedReader(fileReader)) {
//生成文件
File file = FileUtil.createFile(outputFile);
StringBuffer stringBuffer = new StringBuffer();
//讀取模板文件,拼接文件內(nèi)容
Object[] lines = reader.lines().toArray();
for (Object o : lines) {
String line = String.valueOf(o);
/* 設(shè)置值 */
//${tableName} 表名稱,例如:tb_user
if(line.contains("${tableName}")){
line = line.replaceAll("\\$\\{tableName}", tableName);
}
//${tableComment} 表注釋,例如:tb_user
if(line.contains("${tableComment}")){
line = line.replaceAll("\\$\\{tableComment}", tableComment);
}
//${entity} 實(shí)體類名稱,例如:TbUser
if(line.contains("${entity}")){
line = line.replaceAll("\\$\\{entity}", replacement);
}
//${entityFirstToLowerCase} 實(shí)體類名稱首字母小寫,例如:tbUser
if(line.contains("${entityFirstToLowerCase}")){
line = line.replaceAll("\\$\\{entityFirstToLowerCase}", StringUtil.camelCaseName(tableName));
}
//${entityToLowerCase} 實(shí)體類名稱全小寫,例如:tbuser
if(line.contains("${entityToLowerCase}")){
line = line.replaceAll("\\$\\{entityToLowerCase}", replacement.toLowerCase());
}
//${priDataType} 實(shí)體類主鍵類型,例如:String
if(line.contains("${priDataType}")){
line = line.replaceAll("\\$\\{priDataType}", StringUtil.typeMapping(prikey.getDataType()));
}
//處理自定義參數(shù)
line = customParameter(line,customParameter);
//先取得循環(huán)體的內(nèi)容
if(forFlag){
forContent.append(line).append("\n");
}
//是否為for循環(huán)遍歷表字段
if(line.contains("#for")){
forFlag = true;
}
if(line.contains("#end")){
forFlag = false;
line = line.replaceAll("#end", "");
}
//遍歷循環(huán)體的內(nèi)容,并設(shè)置值
if(!forFlag && forContent.length() > 0){
//遍歷表字段
for (TableInfo tableInfo : tableInfos) {
String tableColumns = forContent.toString()
//表字段信息:類型、名稱、注釋
.replaceAll("\\$\\{tableInfo.dataType}", StringUtil.typeMapping(tableInfo.getDataType()))
.replaceAll("\\$\\{tableInfo.columnName}", StringUtil.camelCaseName(tableInfo.getColumnName()))
.replaceAll("\\$\\{tableInfo.columnComment}", tableInfo.getColumnComment());
//清除多余#end,以及換行符
tableColumns = tableColumns.replaceAll("#end", "").replaceAll("\n", "");
//設(shè)置是否主鍵、是否自增
String pri = "",autoIncrement="";
//主鍵
if ("PRI".equals(tableInfo.getColumnKey())) {
pri = " @Id\n";
//自增id
if ("auto_increment".equals(tableInfo.getExtra())){
autoIncrement = "@GeneratedValue(strategy= GenerationType.IDENTITY)\n";
}
}
tableColumns = tableColumns
.replaceAll("#ifPri", pri)
.replaceAll("#ifAutoIncrement", autoIncrement);
//處理自定義參數(shù)
tableColumns = customParameter(tableColumns,customParameter);
//前補(bǔ)tab,后補(bǔ)換行符
stringBuffer.append(" ").append(tableColumns.trim()).append("\n\n");
}
//置空
forContent.setLength(0);
}
if(!forFlag){
stringBuffer.append(line).append("\n");
}
}
//寫入數(shù)據(jù)到到文件中
FileUtil.fileWriter(file, stringBuffer);
}catch (Exception e){
e.printStackTrace();
}
}
private void writer(String templatePath, String outputFile,List<TableInfo> tableInfos){
writer(templatePath,outputFile,tableInfos,new HashMap<>());
}
/**
* 處理自定義參數(shù)
*/
private String customParameter(String str,Map<String,String> customParameter){
for (String key : customParameter.keySet()) {
str = str.replaceAll("\\$\\{"+key+"}",customParameter.get(key));
}
return str;
}
/**
* file工具類
*/
private static class FileUtil {
/**
* 創(chuàng)建文件
*
* @param pathNameAndFileName 路徑跟文件名
* @return File對(duì)象
*/
private static File createFile(String pathNameAndFileName) {
File file = new File(pathNameAndFileName);
try {
//獲取父目錄
File fileParent = file.getParentFile();
if (!fileParent.exists()) {
fileParent.mkdirs();
}
//創(chuàng)建文件
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
file = null;
System.err.println("新建文件操作出錯(cuò)");
e.printStackTrace();
}
return file;
}
/**
* 字符流寫入文件
*
* @param file file對(duì)象
* @param stringBuffer 要寫入的數(shù)據(jù)
*/
private static void fileWriter(File file, StringBuffer stringBuffer) {
//字符流
try {
FileWriter resultFile = new FileWriter(file, false);//true,則追加寫入 false,則覆蓋寫入
PrintWriter myFile = new PrintWriter(resultFile);
//寫入
myFile.println(stringBuffer.toString());
myFile.close();
resultFile.close();
} catch (Exception e) {
System.err.println("寫入操作出錯(cuò)");
e.printStackTrace();
}
}
}
/**
* 字符串處理工具類
*/
private static class StringUtil {
/**
* 數(shù)據(jù)庫(kù)類型->JAVA類型
*
* @param dbType 數(shù)據(jù)庫(kù)類型
* @return JAVA類型
*/
private static String typeMapping(String dbType) {
String javaType;
if ("int|integer".contains(dbType)) {
javaType = "Integer";
} else if ("float|double|decimal|real".contains(dbType)) {
javaType = "Double";
} else if ("date|time|datetime|timestamp".contains(dbType)) {
javaType = "Date";
} else {
javaType = "String";
}
return javaType;
}
/**
* 駝峰轉(zhuǎn)換為下劃線
*/
private static String underscoreName(String camelCaseName) {
StringBuilder result = new StringBuilder();
if (camelCaseName != null && camelCaseName.length() > 0) {
result.append(camelCaseName.substring(0, 1).toLowerCase());
for (int i = 1; i < camelCaseName.length(); i++) {
char ch = camelCaseName.charAt(i);
if (Character.isUpperCase(ch)) {
result.append("_");
result.append(Character.toLowerCase(ch));
} else {
result.append(ch);
}
}
}
return result.toString();
}
/**
* 首字母大寫
*/
private static String captureName(String name) {
char[] cs = name.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
/**
* 下劃線轉(zhuǎn)換為駝峰
*/
private static String camelCaseName(String underscoreName) {
StringBuilder result = new StringBuilder();
if (underscoreName != null && underscoreName.length() > 0) {
boolean flag = false;
for (int i = 0; i < underscoreName.length(); i++) {
char ch = underscoreName.charAt(i);
if ("_".charAt(0) == ch) {
flag = true;
} else {
if (flag) {
result.append(Character.toUpperCase(ch));
flag = false;
} else {
result.append(ch);
}
}
}
}
return result.toString();
}
}
/**
* JDBC連接數(shù)據(jù)庫(kù)工具類
*/
private static class DBConnectionUtil {
static {
// 1、加載驅(qū)動(dòng)
try {
Class.forName(DRIVER_CLASSNAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 返回一個(gè)Connection連接
*/
static Connection getConnection() {
Connection conn = null;
// 2、連接數(shù)據(jù)庫(kù)
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 關(guān)閉Connection,Statement連接
*/
public static void close(Connection conn, Statement stmt) {
try {
conn.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 關(guān)閉Connection,Statement,ResultSet連接
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
try {
close(conn, stmt);
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 表結(jié)構(gòu)信息實(shí)體類
*/
private class TableInfo {
private String columnName;//字段名
private String dataType;//字段類型
private String columnComment;//字段注釋
private String columnKey;//主鍵
private String extra;//主鍵類型
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getColumnComment() {
return columnComment;
}
public void setColumnComment(String columnComment) {
this.columnComment = columnComment;
}
public String getColumnKey() {
return columnKey;
}
public void setColumnKey(String columnKey) {
this.columnKey = columnKey;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
/**
* 獲取表結(jié)構(gòu)信息
* 目前僅支持mysql
*/
private List<TableInfo> getTableInfo() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
ArrayList<TableInfo> list = new ArrayList<>();
try {
conn = DBConnectionUtil.getConnection();
//表字段信息
String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_schema = (select database()) and table_name=?";
ps = conn.prepareStatement(sql);
ps.setString(1, tableName);
rs = ps.executeQuery();
while (rs.next()) {
TableInfo tableInfo = new TableInfo();
//列名,全部轉(zhuǎn)為小寫
tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
//列類型
tableInfo.setDataType(rs.getString("data_type"));
//列注釋
tableInfo.setColumnComment(rs.getString("column_comment"));
//主鍵
tableInfo.setColumnKey(rs.getString("column_key"));
//主鍵類型
tableInfo.setExtra(rs.getString("extra"));
list.add(tableInfo);
}
//表注釋
sql = "select table_comment from information_schema.tables where table_schema = (select database()) and table_name=?";
ps = conn.prepareStatement(sql);
ps.setString(1, tableName);
rs = ps.executeQuery();
while (rs.next()) {
//表注釋
tableComment = rs.getString("table_comment");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(rs != null){
DBConnectionUtil.close(conn, ps, rs);
}
}
return list;
}
/**
* 快速創(chuàng)建,供外部調(diào)用,調(diào)用之前先設(shè)置一下項(xiàng)目的基礎(chǔ)路徑
*/
private String create() {
System.out.println("生成路徑位置:" + filePath);
//獲取表信息
List<TableInfo> tableInfo = getTableInfo();
//駝峰標(biāo)識(shí)映射后的表名
String captureName = StringUtil.captureName(StringUtil.camelCaseName(tableName));
//自定義參數(shù)
HashMap<String, String> customParameter = new HashMap<>();
customParameter.put("author","作者:Auto Generator By 'huanzi-qch'");
customParameter.put("date","生成日期:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//讀取模板、生成代碼
writer(tlfPath+"controller.tlf",
filePath + "controller\\" + captureName + "Controller.java",
tableInfo,customParameter);
writer(tlfPath+"entity.tlf",
filePath + "pojo\\" + captureName + ".java",
tableInfo,customParameter);
writer(tlfPath+"entityvo.tlf",
filePath + "vo\\" + captureName + "Vo.java",
tableInfo,customParameter);
writer(tlfPath+"repository.tlf",
filePath + "repository\\" + captureName + "Repository.java",
tableInfo,customParameter);
writer(tlfPath+"service.tlf",
filePath + "service\\" + captureName + "Service.java",
tableInfo,customParameter);
writer(tlfPath+"serviceimpl.tlf",
filePath + "service\\" + captureName + "ServiceImpl.java",
tableInfo,customParameter);
return tableName + " 后臺(tái)代碼生成完畢!";
}
public static void main(String[] args) {
// String[] tables = {"sys_user","sys_menu","sys_authority","sys_user_menu","sys_user_authority","sys_shortcut_menu","sys_setting"};
String[] tables = {"tb_user"};
for (String table : tables) {
String msg = new AutoGeneratorPlus(table).create();
System.out.println(msg);
}
}
}
同時(shí),所有代碼都在base admin項(xiàng)目里,代碼已經(jīng)開源、托管到我的GitHub、碼云:
GitHub:https://github.com/huanzi-qch/base-admin
碼云:https://gitee.com/huanzi-qch/base-admin
到此這篇關(guān)于教你用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的代碼生成器的文章就介紹到這了,更多相關(guān)Java代碼生成器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot開啟Bean數(shù)據(jù)校驗(yàn)功能
這篇文章主要介紹了springboot開啟Bean數(shù)據(jù)校驗(yàn)功能,通過啟用Bean屬性校驗(yàn)導(dǎo)入JSR303與Hibernate校驗(yàn)框架坐標(biāo),使用@Validated注解啟用校驗(yàn)功能,需要的朋友可以參考下2023-10-10
Spring?@Conditional注解示例詳細(xì)講解
@Conditional是Spring4新提供的注解,它的作用是按照一定的條件進(jìn)行判斷,滿足條件給容器注冊(cè)bean,這篇文章主要介紹了Spring?@Conditional注解示例詳細(xì)講解,需要的朋友可以參考下2022-11-11
基于java類路徑classpath和包的實(shí)例講解
下面小編就為大家分享一篇基于java類路徑classpath和包的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
java狀態(tài)機(jī)方案解決訂單狀態(tài)扭轉(zhuǎn)示例詳解
這篇文章主要為大家介紹了java狀態(tài)機(jī)方案解決訂單狀態(tài)扭轉(zhuǎn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
詳解Java使用super和this來重載構(gòu)造方法
這篇文章主要介紹了詳解Java使用super和this來重載構(gòu)造方法的相關(guān)資料,這里提供實(shí)例來幫助大家理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08
SpringBoot如何優(yōu)雅的處理重復(fù)請(qǐng)求
對(duì)于一些用戶請(qǐng)求,在某些情況下是可能重復(fù)發(fā)送的,如果是查詢類操作并無大礙,但其中有些是涉及寫入操作的,一旦重復(fù)了,可能會(huì)導(dǎo)致很嚴(yán)重的后果,所以本文給大家介紹了SpringBoot優(yōu)雅的處理重復(fù)請(qǐng)求的方法,需要的朋友可以參考下2023-12-12
SpringCloud之熔斷監(jiān)控Hystrix Dashboard的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud之熔斷監(jiān)控Hystrix Dashboard的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09

