Java實現(xiàn)一鍵生成表controller,service,mapper文件
controller、service、Mapper文件的作用
Controller:控制器
業(yè)務(wù)模塊流程的控制,不同的業(yè)務(wù)流程有不同的控制器
負(fù)責(zé)請求轉(zhuǎn)發(fā),接收頁面過來的參數(shù),傳給service處理,接到返回值,并再次傳給頁面
- 控制處理前端請求和響應(yīng),與前端進(jìn)行交互,給前端提供接口
- 調(diào)用Service層(定義的接口)
- 如果只是簡單增刪可以調(diào)用Mapper(不推薦)
Service:服務(wù)
相對獨立,負(fù)責(zé)業(yè)務(wù)邏輯(功能)的設(shè)計,是一個接口類
Mapper:(DAO)
訪問數(shù)據(jù)庫,對數(shù)據(jù)庫進(jìn)行操作,提供接口給Service層
- 當(dāng)sql語句發(fā)生變化更改時,我們可以只修改對應(yīng)的XML文件,而無需再修改Mapper,這樣每次更改sql語句時,代碼就可以不用再次重新編譯!
- 直接與數(shù)據(jù)庫打交道(執(zhí)行SQL語句),接口提供給service層
下圖為java約定俗成的幾個文件的作用
實現(xiàn)代碼
package com.unisoc.isupport.utils; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.*; /** * @author Yuanqiang.Zhang * @since 2023/5/15 */ public class GeneratorTool { /** * 數(shù)據(jù)庫連接信息 */ private static String IP = "172.0.0.1"; private static int PORT = 3306; private static String DATABASE_NAME = "zyq_test"; private static String USERNAME = "root"; private static String PASSWORD = "root"; /** * 創(chuàng)建者 */ private static String AUTHOR = "YuanQiang.Zhang"; /** * 基礎(chǔ)包路徑 */ private static String BASE_PACKAGE = "com.zdb"; /** * 需要生成的表 */ private static String[] TABLE_NAMES = {"z_word"}; /** * 忽略的前綴 */ private static String[] IGNORE_PREFIX = {"z_"}; /** * 主方法運行 * * @param args args */ public static void main(String[] args) { Connection conn = getConnection(); for (String tableName : TABLE_NAMES) { createTableFiles(conn, tableName); } } private static String getWithoutPrefixTableName(String tableName) { if (IGNORE_PREFIX.length == 0) { return tableName; } for (String s : IGNORE_PREFIX) { if (tableName.startsWith(s)) { return tableName.substring(s.length()); } } return tableName; } public static void createTableFiles(Connection conn, String tableName) { List<String[]> fields = getTableFields(conn, tableName); String withoutPrefixTableName = getWithoutPrefixTableName(tableName); String className = getClassName(withoutPrefixTableName); createEntity(fields, tableName, className, withoutPrefixTableName); // createMapper(withoutPrefixTableName, className); // createMapperXml(withoutPrefixTableName, className); // createService(withoutPrefixTableName, className); // createServiceImpl(withoutPrefixTableName, className); // createController(withoutPrefixTableName, className); } public static void createController(String tableName, String className) { StringBuilder sb = new StringBuilder(); sb.append(String.format("package %s.controller;\n\n", BASE_PACKAGE)); sb.append(String.format("import %s.service.%sService;\n", BASE_PACKAGE, className)); sb.append("import lombok.extern.slf4j.Slf4j;\n"); sb.append("import org.springframework.web.bind.annotation.RequestMapping;\n"); sb.append("import org.springframework.web.bind.annotation.RestController;\n"); sb.append("import org.springframework.beans.factory.annotation.Autowired;\n\n"); sb.append("/**\n"); sb.append(String.format(" * @author %s\n", AUTHOR)); sb.append(String.format(" * @since %s\n", formatDateTime(new Date()))); sb.append(" */\n"); sb.append("@RestController\n"); sb.append("@Slf4j\n"); String path = String.valueOf(className.toCharArray()[0]).toLowerCase() + className.substring(1); sb.append(String.format("@RequestMapping(\"/%s\")\n", path)); sb.append(String.format("public class %sController {\n\n", className)); sb.append(" @Autowired\n"); sb.append(String.format(" private %sService service;\n\n", className)); sb.append("}\n"); String fileName = className + "Controller.java"; String filePath = getBasePath() + "/controller/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(tableName + " 的 Controller 類已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(tableName + " 的 Controller 類生成完畢。"); } } public static void createServiceImpl(String tableName, String className) { StringBuilder sb = new StringBuilder(); sb.append(String.format("package %s.service.impl;\n\n", BASE_PACKAGE)); sb.append("import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\n"); sb.append(String.format("import %s.entity.%s;\n", BASE_PACKAGE, className)); sb.append(String.format("import %s.mapper.%sMapper;\n", BASE_PACKAGE, className)); sb.append(String.format("import %s.service.%sService;\n", BASE_PACKAGE, className)); sb.append("import lombok.extern.slf4j.Slf4j;\n"); sb.append("import org.springframework.beans.factory.annotation.Autowired;\n"); sb.append("import org.springframework.stereotype.Service;\n\n"); sb.append("/**\n"); sb.append(String.format(" * @author %s\n", AUTHOR)); sb.append(String.format(" * @since %s\n", formatDateTime(new Date()))); sb.append(" */\n"); sb.append("@Slf4j\n"); sb.append("@Service\n"); sb.append(String.format("public class %sServiceImpl extends ServiceImpl<%sMapper, %s> implements %sService { \n\n", className, className, className, className)); sb.append(" @Autowired\n"); sb.append(String.format(" private %sMapper mapper;\n\n", className)); sb.append("}\n"); String fileName = className + "ServiceImpl.java"; String filePath = getBasePath() + "/service/impl/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(tableName + " 的 ServiceImpl 已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(tableName + " 的 ServiceImpl 生成完畢。"); } } public static void createService(String tableName, String className) { StringBuilder sb = new StringBuilder(); sb.append(String.format("package %s.service;\n\n", BASE_PACKAGE)); sb.append("import com.baomidou.mybatisplus.extension.service.IService;\n"); sb.append(String.format("import %s.entity.%s;\n\n", BASE_PACKAGE, className)); sb.append("/**\n"); sb.append(String.format(" * @author %s\n", AUTHOR)); sb.append(String.format(" * @since %s\n", formatDateTime(new Date()))); sb.append(" */\n"); sb.append(String.format("public interface %sService extends IService<%s> {\n\n", className, className)); sb.append("}\n"); String fileName = className + "Service.java"; String filePath = getBasePath() + "/service/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(tableName + " 的 Service 類已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(tableName + " 的 Service 類生成完畢。"); } } public static void createMapperXml(String tableName, String className) { StringBuilder sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n"); sb.append(String.format("<mapper namespace=\"%s.mapper.%sMapper\">\n\n", BASE_PACKAGE, className)); sb.append("</mapper>\n"); String fileName = className + "Mapper.xml"; String filePath = "src/main/resources/mapper/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(tableName + " 的 Mapper.xml 已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(tableName + " 的 Mapper.xml 生成完畢。"); } } public static void createMapper(String tableName, String className) { StringBuilder sb = new StringBuilder(); sb.append(String.format("package %s.mapper;\n\n", BASE_PACKAGE)); sb.append(String.format("import %s.entity.%s;\n", BASE_PACKAGE, className)); sb.append("import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n\n"); sb.append("/**\n"); sb.append(String.format(" * @author %s\n", AUTHOR)); sb.append(String.format(" * @since %s\n", formatDateTime(new Date()))); sb.append(" */\n"); sb.append(String.format("public interface %sMapper extends BaseMapper<%s> {\n\n", className, className)); sb.append("}\n"); String fileName = className + "Mapper.java"; String filePath = getBasePath() + "/mapper/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(tableName + " 的 Mapper 類已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(tableName + " 的 Mapper 類生成完畢。"); } } public static void createEntity(List<String[]> fields, String tableName, String className, String withoutPrefixTableName) { StringBuilder sb = new StringBuilder(); sb.append(String.format("package %s.entity;\n\n", BASE_PACKAGE)); sb.append("import com.baomidou.mybatisplus.annotation.*;\n"); sb.append("import lombok.Data;\n\n"); // 判斷是否有 timestamp 類型 if (hasDate(fields)) { sb.append("import java.util.Date;\n\n"); } sb.append("/**\n"); sb.append(" * @author " + AUTHOR + "\n"); sb.append(" * @since " + formatDateTime(new Date()) + "\n"); sb.append(" */\n"); sb.append("@Data\n"); sb.append(String.format("@TableName(\"%s\")\n", tableName)); sb.append(String.format("public class %s {\n\n", className)); for (String[] attrs : fields) { String columnName = attrs[0]; String dataType = attrs[1]; String columnComment = attrs[2]; String columnKey = attrs[3]; if ("PRI".equals(columnKey)) { sb.append(" /** 主鍵 */\n"); sb.append(String.format(" @TableId(value = \"%s\", type = IdType.AUTO)\n", columnName)); } else { if (Objects.nonNull(columnComment) && !columnComment.isEmpty()) { sb.append(String.format(" /** %s */\n", columnComment)); } sb.append(String.format(" @TableField(value = \"%s\")\n", columnName)); } String fieldName = getFieldName(columnName); if (dataType.endsWith("int")) { if ("bigint".equals(dataType)) { sb.append(String.format(" private Long %s;\n", fieldName)); } else { sb.append(String.format(" private Integer %s;\n", fieldName)); } } else if (dataType.endsWith("char") || dataType.endsWith("text")) { sb.append(String.format(" private String %s;\n", fieldName)); } else if ("timestamp".equals(dataType) || "datetime".equals(dataType)) { sb.append(String.format(" private Date %s;\n", fieldName)); } else if ("double".equals(dataType)) { sb.append(String.format(" private Double %s;\n", fieldName)); } else { System.err.println("發(fā)現(xiàn)沒有判斷到的數(shù)據(jù)類型:" + dataType); } sb.append("\n"); } sb.append("\n}"); String fileName = className + ".java"; String filePath = getBasePath() + "/entity/" + fileName; File file = new File(filePath); if (file.exists()) { System.out.println(withoutPrefixTableName + " 的 Entity 類已經(jīng)存在,不再生成。"); } else { writeFileContent(file, sb.toString()); System.out.println(withoutPrefixTableName + " 的 Entity 類生成完畢。"); } } private static String getBasePath() { return "src/main/java/" + BASE_PACKAGE.replace(".", "/"); } private static String getFieldName(String columnName) { if (!columnName.contains("_")) { StringBuilder sb = new StringBuilder(); char[] chars = columnName.toCharArray(); sb.append(String.valueOf(chars[0]).toLowerCase()); if (chars.length <= 1) { return sb.toString(); } else { for (int i = 1; i < chars.length; i++) { sb.append(chars[i]); } } return sb.toString(); } String s = getClassName(columnName); return String.valueOf(s.toCharArray()[0]).toLowerCase() + s.substring(1); } private static boolean hasDate(List<String[]> fields) { if (Objects.isNull(fields) || fields.isEmpty()) { return false; } for (String[] attrs : fields) { String dataType = attrs[1]; if ("timestamp".equals(dataType) || "datetime".equals(dataType)) { return true; } } return false; } private static List<String[]> getTableFields(Connection conn, String tableName) { String sql = "SELECT * FROM information_schema.columns WHERE table_schema = '" + DATABASE_NAME + "' AND table_name = '" + tableName + "'"; List<String[]> fields = new ArrayList<>(); try { Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery(sql); while (rs.next()) { String columnName = rs.getString("COLUMN_NAME"); String dataType = rs.getString("DATA_TYPE"); String columnComment = rs.getString("COLUMN_COMMENT"); String columnKey = rs.getString("COLUMN_KEY"); String[] attrs = new String[4]; attrs[0] = columnName; attrs[1] = dataType; attrs[2] = columnComment; attrs[3] = columnKey; fields.add(attrs); } } catch (Exception e) { e.printStackTrace(); } return fields; } /** * 獲取類名 * * @param tableName 表名 * @return 類名 */ private static String getClassName(String tableName) { char[] chars = tableName.toCharArray(); boolean flag = true; StringBuilder sb = new StringBuilder(); for (char c : chars) { if (c == '_') { flag = true; continue; } if (flag) { sb.append(String.valueOf(c).toUpperCase()); } else { sb.append(String.valueOf(c).toLowerCase()); } flag = false; } return sb.toString(); } /** * 獲取數(shù)據(jù)庫鏈接 * * @return Connection */ private static Connection getConnection() { try { Class.forName("com.mysql.cj.jdbc.Driver"); String url = String.format("jdbc:mysql://%s:%s/%s", IP, PORT, DATABASE_NAME); return DriverManager.getConnection(url, USERNAME, PASSWORD); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 將內(nèi)容寫入到文件中 * * @param file 文件 * @param content 內(nèi)容 */ public static void writeFileContent(File file, String content) { String parentPath = file.getParent(); if (Objects.nonNull(parentPath) && !parentPath.isEmpty()) { File parent = new File(parentPath); if (!parent.exists()) { parent.mkdirs(); } } if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try (FileWriter writer = new FileWriter(file)) { writer.write(content); writer.flush(); } catch (IOException e) { e.printStackTrace(); } } private static String formatDateTime(Date date) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(date); } }
到此這篇關(guān)于Java實現(xiàn)一鍵生成表controller,service,mapper文件的文章就介紹到這了,更多相關(guān)Java生成文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 中的 getDeclaredMethods() 方法(使用與原理)
文章介紹了Java反射機(jī)制中的`getDeclaredMethods()`方法,詳細(xì)講解了其使用方法、原理、注意事項以及實際應(yīng)用場景,幫助讀者更好地理解和應(yīng)用這一強(qiáng)大的工具,感興趣的朋友一起看看吧2024-12-12Java?webservice的POST和GET請求調(diào)用方式
這篇文章主要介紹了Java?webservice的POST和GET請求調(diào)用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解決方案
這篇文章主要介紹了SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08???????Spring多租戶數(shù)據(jù)源管理 AbstractRoutingDataSource
本文技術(shù)了???????Spring多租戶數(shù)據(jù)源管理 AbstractRoutingDataSource,下文詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下2022-05-05Spring Cloud Gateway 記錄請求應(yīng)答數(shù)據(jù)日志操作
這篇文章主要介紹了Spring Cloud Gateway 記錄請求應(yīng)答數(shù)據(jù)日志操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12