java自动生成代码

合集下载

使用Java代码自动生成工具:Telosys

使用Java代码自动生成工具:Telosys

使⽤Java代码⾃动⽣成⼯具:Telosys在Java开发⼯具中Java代码⾃动⽣成⼯具是很常见的,代码⽣成是模型驱动开发中最简单和最常⽤的技术。

我们使⽤⼀个信息源,⼀种模型形式,并将其与⼀些模板结合起来以获得⽣成的⼯件,例如代码。

代码⽣成是进⼊更⾼级技术的有⽤的⼊门级步骤。

因此,认为创建简单的代码⽣成平台以降低新⽤户的进⼊门槛⾮常重要。

作为⼀个社区,我们希望让尽可能多的开发⼈员从编写重复代码转向寻找更智能的解决⽅案。

如果我们使代码⽣成器易于访问且有效,我们将“拯救”许多开发⼈员并将他们带到模型驱动开发和语⾔⼯程⽅⾯。

因此,像 Telosys 这样可⽤且全⾯的代码⽣成器对语⾔⼯程社区⾮常有价值。

代码⽣成对于为开发⼈员提供通⽤框架⾮常有⽤。

如果每个⼈都通过代码⽣成开始开发,您可以确保所有团队的基础是同质的,并且代码具有令⼈满意的质量(尊重标准、注释、单元测试等)。

当然,另⼀个重点是⽣产⼒。

您可以在组件创建的初始步骤中显着减少⼯作量。

您管理的实体越多,您可以在创建模板上投⼊的时间就越多。

代码⽣成还可⽤于快速⽣成应⽤程序的动态模型。

然后可以在迭代开发周期中重⽤代码。

基于现有数据库的“脚⼿架”⽅法也⾮常有效。

我已经多次使⽤它,⽤于新项⽬或从⼀种语⾔迁移到另⼀种语⾔。

Telosys 与其他代码⽣成器有何不同?⾸先,Telosys 是由开发⼈员为开发⼈员创建的。

它只是旨在务实和⾼效。

概念和发展遵循⼀些基本原则:它必须简单、易于使⽤并保持轻便它必须是 100% 开源的它必须能够为任何类型的语⾔或框架⽣成代码⽣成的代码必须对⼯具零依赖(可以随时停⽌使⽤⼯具⽽不影响项⽬)开发⼈员必须能够使⽤任何⽂本编辑器轻松调整模板开发⼈员必须能够使⽤“轻量级模型”(不需要 UML 模型)定义项⽬实体因此,Telosys 可以被视为⼀种战术⼯具。

这不是⼀个对项⽬组织有重⼤影响的战略选择。

您可以随时安装、使⽤和删除它。

当然,您也可以从项⽬开始到结束使⽤它,并利⽤模型和模板,这取决于您。

如何利用Java开发工具实现代码自动化

如何利用Java开发工具实现代码自动化

如何利用Java开发工具实现代码自动化在当今的软件开发领域,代码自动化已经成为提高开发效率、保证代码质量的关键手段之一。

Java 作为一种广泛应用的编程语言,拥有丰富的工具和库,可以帮助我们实现代码自动化。

接下来,让我们一起深入探讨如何利用 Java 开发工具来达成这一目标。

首先,我们要明确代码自动化的概念。

简单来说,代码自动化就是让计算机自动完成一些重复性、规律性的代码编写工作,从而节省开发者的时间和精力,减少人为错误。

要实现代码自动化,我们需要熟练掌握一些基本的 Java 技术和工具。

其中,反射机制是一个非常强大的特性。

通过反射,我们可以在运行时获取类的信息,包括属性、方法等,并进行动态的操作。

例如,我们可以利用反射来自动生成对象的初始化代码,或者根据配置文件动态地调用类的方法。

代码生成器也是实现代码自动化的重要工具。

我们可以使用模板引擎,如 FreeMarker 或 Velocity,来定义代码模板。

然后,根据特定的规则和数据,生成相应的 Java 代码。

比如,当我们设计一个数据库操作的框架时,可以根据数据库表的结构,自动生成对应的实体类、数据访问对象(DAO)以及相关的 SQL 语句。

除了上述方法,单元测试框架也是实现代码自动化的重要组成部分。

JUnit 是 Java 中广泛使用的单元测试框架。

通过编写单元测试用例,我们可以自动对代码的功能进行验证。

而且,在持续集成(CI)环境中,单元测试可以自动执行,一旦发现问题,及时反馈给开发者。

在实际开发中,构建工具也对代码自动化起着重要作用。

Maven 和Gradle 是两个常用的构建工具。

它们可以自动管理项目的依赖,执行编译、打包、部署等一系列操作。

我们只需要在配置文件中定义好项目的结构和依赖关系,构建工具就会按照我们的要求完成相应的工作。

另外,版本控制系统(如 Git)也能为代码自动化提供支持。

通过设置钩子(hooks),我们可以在代码提交、推送等操作时自动执行一些检查和处理,比如代码风格检查、单元测试执行等。

教你用Java实现一个简单的代码生成器

教你用Java实现一个简单的代码生成器

教你⽤Java实现⼀个简单的代码⽣成器前⾔逆向⼯程从数据库表直接⽣成代码,是⽇常开发中常⽤的敏捷开发⼿段,常见的例如:mybatis-plus的代码⽣成器等为什么要⾃⼰写代码⽣成器呢?MP的⽣成器不⾹吗?⾹!但是⾃⼰写的⼯具⽤起来最顺⼿,可以随意扩展,想怎么玩就怎么玩,只要⾃⼰有想法,玩出花来都没问题,当然了,能⼒有限,现在还只能实现简单版本,更多骚操作⾃⼰发挥!思路:1、建⽴jdbc连接,执⾏查询sql,获取表结构信息。

2、在指定的路径上创建⽂件。

3、按照我们的布局排版要求,根据表结构信息拼接⽂件的内容。

4、将字符输出到⽂件中。

以上即可完成⼀个⽂件的⾃动⽣成编码 通⽤部分⼏个内部⼯具类file⼯具类:创建、读取⽂件字符串⼯具类:驼峰标识、下划线互转,⾸字母⼤写,数据库字段类型转java类型等jdbc连接:连接数据库表注释、表结构信息实体类、执⾏sql获取表结构信息的⽅法表结构信息private String columnName;//字段名private String dataType;//字段类型private String columnComment;//字段注释private String columnKey;//主键private String extra;//主键类型mysql查询表注释、表字段信息使⽤的是表字段信息SELECTcolumn_name,data_type,column_comment,column_key,extraFROMinformation_schema.COLUMNSWHEREtable_schema = (SELECT DATABASE())AND table_name =?表注释SELECTtable_commentFROMinformation_schema.TABLESWHEREtable_schema = (SELECT DATABASE())AND table_name =?需要⽀持其他数据库类型的,⾃⼰调整就好了,例如oracle获取表注释、表结构sql如下:-- 表、表注释SELECTt.table_name,mentsFROMuser_tables tJOIN user_tab_comments t1 ON t.table_name = t1.table_name;-- 表字段、字段注释SELECTt.table_name,c.column_name,c.data_type,mentsFROMUSER_TAB_COLUMNS cJOIN user_tables t ON c.table_name = t.table_nameJOIN user_col_comments cc ON cc.table_name = t.table_nameWHEREcc.column_name = c.column_name;另外,数据连接、基础路径的配置也是⼀样/*** 数据连接相关,需要⼿动设置*/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";/*** 基础路径,需要⼿动设置*/private String basePackage = "cn\\huanzi\\qch\\baseadmin\\";//根包位置private String filePackage = basePackage + "sys\\";//⽂件所在包位置2.0版本多⼀个模板⽂件路径private String tlfPath = System.getProperty("user.dir") + "\\src\\main\\resources\\tlf\\";//模板⽂件位置main函数也⼀样,调⽤构造参数,传⼊表名,调⽤⼊⼝函数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版本采⽤原始的在代码拼接字符串,然后创建⽂件将字符串输出的⽅法,⽐较原始但个⼈觉得可玩性较⾼⼏个创建⽅法,就拿实体类来举例/*** 创建pojo实体类*/private void createPojo(List<TableInfo> tableInfos) {//创建⽂件File file = FileUtil.createFile(filePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");//拼接⽂件内容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");//遍历设置属性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("}");//写⼊⽂件内容FileUtil.fileWriter(file, stringBuffer);}其他的也⼀样,⽆⾮就:创建⽂件、拼接⽂件内容、输出⽂件内容⼊⼝函数,供main函数直接调⽤/*** 快速创建,供外部调⽤,调⽤之前先设置⼀下项⽬的基础路径*/private String create() {System.out.println("⽣成路径位置:" + filePath);//获取表信息List<TableInfo> tableInfo = getTableInfo();//开始⽣成代码createPojo(tableInfo);createVo(tableInfo);createRepository(tableInfo);createService(tableInfo);createController(tableInfo);return tableName + " 后台代码⽣成完毕!";}V2.0版本AutoGeneratorPlus,2.0版本升级了,设置了模板⽂件、⽂件内容的字符串从模板读取,再根据关键字替换参数,最后再输出到创建的⽂件中,这个版本就⽐较好理解,⼤部分的代码⽣成器也都这样⼲需要先定义模板⽂件(⽂件名后缀⽆所谓,⾃⼰随便定义),拿entity来举例package cn.huanzi.qch.baseadmin.sys.${entityToLowerCase}.pojo;import lombok.Data;import javax.persistence.*;import java.io.Serializable;import java.util.Date;/*** ${tableComment} 实体类** ${author}* ${date}*/@Entity@Table(name = "${tableName}")@Datapublic class ${entity} implements Serializable {#for#ifPri#ifAutoIncrementprivate ${tableInfo.dataType} ${tableInfo.columnName};//${tableInfo.columnComment}#end}${},⽤于取参数,替换成我们的值#for、#if,循环遍历表字段以及判断是否为主键、是否主键⾃增各种关键字随便定义,我们在读取模板⽂件处理时能对上就⾏⽂件内容处理/*** 读取模板,设置内容,⽣成⽂件* @param templatePath 模板⽂件路径* @param outputFile ⽂件⽣成路径* @param tableInfos 表字段信息* @param customParameter ⾃定义参数*/private void writer(String templatePath, String outputFile,List<TableInfo> tableInfos,Map<String,String> customParameter){//主键TableInfo prikey = new TableInfo();//for循环标识boolean forFlag = false;StringBuilder forContent = new StringBuilder();//驼峰标识映射后的表名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();//读取模板⽂件,拼接⽂件内容Object[] lines = reader.lines().toArray();for (Object o : lines) {String line = String.valueOf(o);/* 设置值 *///${tableName} 表名称,例如:tb_userif(line.contains("${tableName}")){line = line.replaceAll("\\$\\{tableName}", tableName);}//${tableComment} 表注释,例如:tb_userif(line.contains("${tableComment}")){line = line.replaceAll("\\$\\{tableComment}", tableComment);}//${entity} 实体类名称,例如:TbUserif(line.contains("${entity}")){line = line.replaceAll("\\$\\{entity}", replacement);}//${entityFirstToLowerCase} 实体类名称⾸字母⼩写,例如:tbUserif(line.contains("${entityFirstToLowerCase}")){line = line.replaceAll("\\$\\{entityFirstToLowerCase}", StringUtil.camelCaseName(tableName));}//${entityToLowerCase} 实体类名称全⼩写,例如:tbuserif(line.contains("${entityToLowerCase}")){line = line.replaceAll("\\$\\{entityToLowerCase}", replacement.toLowerCase());}//${priDataType} 实体类主键类型,例如:Stringif(line.contains("${priDataType}")){line = line.replaceAll("\\$\\{priDataType}", StringUtil.typeMapping(prikey.getDataType()));}//处理⾃定义参数line = customParameter(line,customParameter);//先取得循环体的内容if(forFlag){forContent.append(line).append("\n");}//是否为for循环遍历表字段if(line.contains("#for")){forFlag = true;}if(line.contains("#end")){forFlag = false;line = line.replaceAll("#end", "");}//遍历循环体的内容,并设置值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", "");//设置是否主键、是否⾃增String pri = "",autoIncrement="";//主键if ("PRI".equals(tableInfo.getColumnKey())) {pri = " @Id\n";//⾃增idif ("auto_increment".equals(tableInfo.getExtra())){autoIncrement = "@GeneratedValue(strategy= GenerationType.IDENTITY)\n";}}tableColumns = tableColumns.replaceAll("#ifPri", pri).replaceAll("#ifAutoIncrement", autoIncrement);//处理⾃定义参数tableColumns = customParameter(tableColumns,customParameter);//前补tab,后补换⾏符stringBuffer.append(" ").append(tableColumns.trim()).append("\n\n");}//置空forContent.setLength(0);}if(!forFlag){stringBuffer.append(line).append("\n");}}//写⼊数据到到⽂件中FileUtil.fileWriter(file, stringBuffer);}catch (Exception e){e.printStackTrace();}}内置了⼏个重要参数${tableName} 表名称,例如:tb_user${tableComment} 表注释,例如:tb_user${entity} 实体类名称,例如:TbUser${entityFirstToLowerCase} 实体类名称⾸字母⼩写,例如:tbUser${entityToLowerCase} 实体类名称全⼩写,例如:tbuser${priDataType} 实体类主键类型,例如:String还有三个表字段信息:类型、名称、注释${tableInfo.dataType}${tableInfo.columnName}${tableInfo.columnComment}⽀持⾃定义参数Map<String,String> customParameter,例如模板⽂件中的注释:/*** ${author}* ${date}*/⼊⼝函数/*** 快速创建,供外部调⽤,调⽤之前先设置⼀下项⽬的基础路径*/private String create() {System.out.println("⽣成路径位置:" + filePath);//获取表信息List<TableInfo> tableInfo = getTableInfo();//驼峰标识映射后的表名String captureName = StringUtil.captureName(StringUtil.camelCaseName(tableName));//⾃定义参数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 + " 后台代码⽣成完毕!";}⽐较复杂的就是#for、#if的处理,我这⾥只是简单实现,不过也完全够我们⽤了效果 V1.0版本V2.0版本后记⼤部分项⽬的代码都是可以复⽤的,特别是像我们这种封装了⼀套通⽤代码,单表直接继承实现CRUD、分页等功能,每个模块⾼度相似的代码,代码⽣成器就成了敏捷开发中重要的⼀步,直接根据数据库表⽣成我们想要的代码,省去了⼀步步创建⽂件、复制粘贴⽂件内容的繁琐步骤,实现快速开发!⾃⼰写的代码⽣成器,扩展性更强,满⾜每个业务模块的代码要求不成问题开源在这⾥贴出完整代码,全都在⼀个类⾥⾯,并且没有其他依赖包,很纯!v1.0AutoGeneratorView Codepackage 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 {/*** 程序⾃动设置*/private String tableName;//表名private String tableComment;//表注释private String filePath;//最终⽂件⽣成位置/*** 数据连接相关,需要⼿动设置*/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";/*** 基础路径,需要⼿动设置*/private String basePackage = "cn\\huanzi\\qch\\baseadmin\\";//根包位置private String filePackage = basePackage + "sys\\";//⽂件所在包位置/*** 构造参数,设置表名*/private AutoGenerator(String tableName) {//设置表名this.tableName = tableName;//⽂件所在包位置filePackage = filePackage + StringUtil.camelCaseName(tableName).toLowerCase() + "\\";//拼接完整最终位置 System.getProperty("user.dir") 获取的是项⽬所在路径,如果我们是⼦项⽬,则需要添加⼀层路径filePath = System.getProperty("user.dir") + "\\src\\main\\java\\" + filePackage;}/*** 创建pojo实体类*/private void createPojo(List<TableInfo> tableInfos) {//创建⽂件File file = FileUtil.createFile(filePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");//拼接⽂件内容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");//遍历设置属性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("}");//写⼊⽂件内容FileUtil.fileWriter(file, stringBuffer);}/*** 创建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");//遍历设置属性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);}/*** 创建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);}/*** 创建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.camelCa );stringBuffer.append("\n");stringBuffer.append("}");FileUtil.fileWriter(file, stringBuffer);//ImplFile 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.cam );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);}/*** 创建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.camelCa );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 {/*** 创建⽂件** @param pathNameAndFileName 路径跟⽂件名* @return File对象*/private static File createFile(String pathNameAndFileName) {File file = new File(pathNameAndFileName);try {//获取⽗⽬录File fileParent = file.getParentFile();if (!fileParent.exists()) {fileParent.mkdirs();}//创建⽂件if (!file.exists()) {file.createNewFile();}} catch (Exception e) {file = null;System.err.println("新建⽂件操作出错");e.printStackTrace();}return file;}/*** 字符流写⼊⽂件** @param file file对象* @param stringBuffer 要写⼊的数据*/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("写⼊操作出错");e.printStackTrace();}}}/*** 字符串处理⼯具类*/private static class StringUtil {/*** 数据库类型->JAVA类型** @param dbType 数据库类型* @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;}/*** 驼峰转换为下划线*/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);}/*** 下划线转换为驼峰*/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连接数据库⼯具类*/private static class DBConnectionUtil {static {// 1、加载驱动try {Class.forName(DRIVER_CLASSNAME);} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 返回⼀个Connection连接*/static Connection getConnection() {Connection conn = null;// 2、连接数据库try {conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (SQLException e) {e.printStackTrace();}return conn;}/*** 关闭Connection,Statement连接*/public static void close(Connection conn, Statement stmt) {try {conn.close();stmt.close();} catch (SQLException e) {e.printStackTrace();}}/*** 关闭Connection,Statement,ResultSet连接*/public static void close(Connection conn, Statement stmt, ResultSet rs) {try {close(conn, stmt);rs.close();} catch (SQLException e) {e.printStackTrace();}}}/*** 表结构信息实体类*/private class TableInfo {private String columnName;//字段名private String dataType;//字段类型。

Java代码的自动生成与重构

Java代码的自动生成与重构

Java代码的自动生成与重构引言在软件开发领域,代码的生成和重构是提高开发效率和代码质量的重要手段之一。

而对于Java代码来说,自动生成和重构工具更是不可或缺的。

本文将介绍Java 代码的自动生成与重构相关的概念、工具和技术,并探讨它们对于开发过程的影响。

一、自动生成代码的概念与工具1.1 自动生成代码的概念自动生成代码是指通过工具或技术,根据已有的模板或规则,自动创建代码的过程。

这些代码可以是重复性的、标准化的或者基于某种模式的。

自动生成代码可以减少开发者手动编写重复性代码的工作量,提高代码的可维护性和可读性。

1.2 自动生成代码的工具在Java开发中,有许多自动生成代码的工具可供选择。

其中比较知名的工具包括:Eclipse、NetBeans、IntelliJ IDEA等集成开发环境(IDE),以及一些独立的代码生成工具,如MyBatis、Spring Roo等。

Eclipse是一个功能强大的开发环境,提供了丰富的代码自动生成功能。

通过Eclipse,开发者可以根据需要自动生成类、方法、属性、构造函数等代码片段,大大减少了手写代码的工作量。

NetBeans也是一款流行的集成开发环境,提供了类似的代码生成功能。

开发者可以通过NetBeans快速生成Java类、界面、测试用例等。

IntelliJ IDEA是一款功能强大的Java开发工具,也提供了丰富的代码自动生成功能。

开发者可以利用IntelliJ IDEA生成代码片段、测试代码等。

除了集成开发环境,一些独立的代码生成工具也非常受欢迎。

比如MyBatis是一款基于Java的持久层框架,它可以根据数据库表结构自动生成Java代码,大大简化了数据库操作的开发工作。

Spring Roo是另一款流行的代码生成工具,它可以根据项目需求自动生成Spring框架相关的代码,包括实体类、控制器、服务等。

二、代码重构的概念与技术2.1 代码重构的概念代码重构是指通过改变代码的结构和设计,改进代码的质量、可读性和可维护性,而不改变代码的外部行为。

软件工程中的代码文档自动生成方法(三)

软件工程中的代码文档自动生成方法(三)

软件工程中的代码文档自动生成方法深入探讨如何在软件工程中实现代码文档的自动生成,对于提高开发效率和代码质量至关重要。

本文将从需求分析、代码注释和文档生成等方面,介绍几种常见的代码文档自动生成方法。

I. 需求分析的重要性在实现代码文档自动生成之前,我们必须明确需求。

需求分析是软件工程中的一项关键工作,它确保了我们对于代码文档的准确理解。

在这一阶段,我们与用户、开发团队和其他利益相关者进行交流,确保我们明确理解他们对于代码文档的期望。

需求分析包括但不限于以下几个方面:代码结构、函数或类的功能、输入输出等。

明确了需求后,我们就可以将其转化为相应的代码文档。

II. 代码注释的规范化良好的代码注释是生成高质量文档的关键。

注释应该清晰、简洁、并且包含足够的信息。

以下是一些代码注释的规范化建议:1. 为每个函数或类添加注释,解释它们的功能和作用。

这有助于开发人员和其他阅读代码的人员快速了解功能和使用方法。

2. 对于复杂逻辑或特殊处理的代码段,添加详细的注释。

这样可以帮助其他开发人员更好地理解代码的意图。

3. 使用标准的注释格式和语法。

例如,使用文档化注释工具支持的注释格式,如Javadoc、Doxygen等。

III. 自动生成工具的使用现代软件工程中,有很多自动生成代码文档的工具可供选择。

下面介绍两种常见的自动生成工具:1. Javadoc:Javadoc是Java开发中广泛使用的一种自动生成代码文档的工具。

通过使用特定的注释标签,可以自动提取注释内容,并生成HTML格式的代码文档。

只需运行Javadoc命令,就能为整个项目生成代码文档,从而大大减轻了文档编写的负担。

2. Doxygen:Doxygen是一种通用的文档生成工具,支持多种编程语言,如C++、Java和Python等。

它能够从源代码中提取注释,并生成HTML、PDF和LaTeX等多种格式的文档。

Doxygen的强大之处在于它支持复杂的代码结构和关系的可视化展示。

Java框架中的代码生成工具介绍

Java框架中的代码生成工具介绍

Java框架中的代码生成工具介绍代码生成工具在Java框架中扮演着重要的角色,它们可以自动创建模板代码和基础结构,大大提高了开发效率。

本文将介绍几种常用的Java框架中的代码生成工具。

一、MyBatis-GeneratorMyBatis-Generator是一款强大的代码生成工具,主要用于生成与数据库表对应的实体类、DAO类、Mapper映射文件等。

它基于MyBatis框架,可以根据数据库的结构自动生成相应的代码。

使用MyBatis-Generator非常简单,只需编写一个XML配置文件,指定数据库连接信息、表名、生成代码的目录等,就可以自动生成所需的代码。

可以通过自定义插件来扩展其功能,满足不同项目的需求。

二、Spring RooSpring Roo是一个开源的Rapid Application Development(快速应用开发)工具,它可以快速生成基于Spring框架的Java应用的骨架代码。

Spring Roo可以通过命令行或者图形界面进行操作,提供了丰富的命令和选项来生成代码、配置文件等。

使用Spring Roo可以轻松地创建实体类、控制器、服务层等,并自动处理相关的依赖注入、持久化等问题。

它还支持自定义代码模板和插件,方便定制化开发。

三、JHipsterJHipster是一款用于生成现代化Java应用程序的代码生成器。

它结合了Java、Spring Boot、Angular/React/Vue.js等技术,可以快速构建全栈应用。

借助JHipster,开发人员可以选择不同的选项,如数据库类型、身份验证模块、前端框架等,然后通过一条命令生成项目的基础结构和代码。

生成的代码包括实体类、RESTful API、前端页面等,大大减少了开发工作量。

四、Apache VelocityApache Velocity是一款基于Java的模板引擎,也可以用作代码生成工具。

它使用简单且功能强大,可以根据自定义的模板生成任意文本文件。

copilot java 代码生成

copilot java 代码生成

copilot java 代码生成Copilot是一项新颖的AI技术,可以为开发人员提供自动代码生成的支持。

Java是一种广泛使用的编程语言,与Copilot结合使用可以提高开发效率和代码质量。

下面就Java的Copilot代码生成进行简要介绍。

首先,将Copilot插件安装到开发环境中,目前支持的开发工具有VS Code、PyCharm等。

然后建立Java项目,Copilot会基于机器学习来分析开发者的输入代码以及上下文信息,从而推荐代码。

这种智能化生成代码的方式不仅大大提高了效率,还可以帮助开发者更好地理解代码逻辑。

Java的Copilot代码生成支持创建类、方法和属性,也能为不断变化的需求或用户反馈提供快速响应。

Copilot使用AI算法来生成代码,这意味着它可以在时间和空间上大量减少编码负担。

开发人员只需输入所需的代码范围并放心地等待开发工具为解决方案提供思路。

另一个好处是Copilot生成的代码质量通常很高。

其AI引擎能够处理常见问题、模式和最佳实践,并注意代码文件的工程结构和格式。

这样,生成的代码质量比手写的代码更好并且使得代码更容易维护。

但是,尽管智能化生成代码有很多优点,但开发人员也需要注意潜在的问题。

最明显的可能是安全问题。

手动编写代码使得开发人员能够较为容易地判断漏洞和风险,并根据需要执行各种安全措施。

但是,Copilot生成的代码可能存在安全隐患,所以代码质量检查和代码审查是必要的。

Copilot为Java开发人员提供了更快速高效的编程解决方案。

通过集成Copilot,开发人员可以快速生成高质量的代码,而不必写出冗长、重复或繁琐的结构。

虽然有一些问题需要开发人员注意,但与利大于弊。

这种智能化代码生成技术,是现代软件开发行业的一个重要趋势。

lombok高级用法 -回复

lombok高级用法 -回复

lombok高级用法-回复Lombok是一个在Java编程语言中可以使用的一种实用工具,它通过自动化代码生成,帮助开发人员减少冗余的模板代码,使开发过程更加高效。

除了常见的注解和代码生成功能外,Lombok还提供了一些高级用法,能够进一步简化代码,并提供更多的灵活性和可读性。

本文将一步一步介绍Lombok的高级用法,并提供相关示例来帮助读者理解这些概念。

简介Lombok的高级用法是指通过组合不同的注解和配置选项,以实现更加复杂的代码自动生成。

这些高级用法不仅可以减少手动编写的代码数量,还能够提高代码的可读性和可维护性。

1. ToStringToString注解用于自动生成类的toString方法。

通常情况下,Java类需要手动编写toString方法以实现对类的属性进行字符串表示。

使用ToString注解,Lombok将自动生成该方法的代码。

示例代码如下:javaimport lombok.ToString;ToStringpublic class Person {private String name;private int age;}使用ToString注解后,Lombok将自动生成如下代码:javapublic class Person {private String name;private int age;Overridepublic String toString() {return "Person(name=" + name + ", age=" + age + ")";}}通过该注解自动生成的toString方法会打印类的属性名称和相应的值,避免了手动编写toString方法的繁琐过程。

2. BuilderBuilder注解可以自动生成一个Builder类,该类用于构建复杂对象。

使用Builder可以方便地创建实例,而无需使用繁琐的构造函数或setter方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.与数据库建立连接
在DBUtil中设置数据库相关的参数
Class.forName(driverName);
conn = DriverManager.getConnection(url, user, password);
2.获得数据库中的所有表
Mapmaps = new HashMap();
PreparedStatement pstate = conn.prepareStatement("show table status"); ResultSet results = pstate.executeQuery();
while (results.next()) {
String tableName = results.getString("NAME");
String comment = results.getString("COMMENT");
maps.put(tableName, comment);
}
3.获得每个表中的信息
封装一个实体来存储表中的信息
PreparedStatement pstate = conn.prepareStatement("show full fields from " + tableName);
ResultSet results = pstate.executeQuery();
List lists = new ArrayList();
while (results.next()) {
Column column = new Column();
String field = results.getString("FIELD");
column.setFeildMapper(field);
String fieldName = processField(field);
column.setFeild(fieldName);
String type = processType(results.getString("TYPE"));
String comment = results.getString("COMMENT");
column.setType(type);
column.setComment(comment);
lists.add(column);
}
4.拼串输出
将固定代码中需要变动的字段从实体中取拼串写入文档中
例如给表生成po:
public class WritePo {
public static void createPo(String path,String packageName,String upTable, String lowTable, List columns) throws IOException {
File folder = new File(path + lowTable + "/po");
if (!folder.exists()) {
folder.mkdirs();
}
File beanFile = new File(folder + "/" + upTable + ".java");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(beanFile)));
bw.write("package "+packageName+lowTable+".po;");
bw.write("import java.io.Serializable;");
bw.newLine();
// bw.write("import lombok.Data;");
// bw.write("import javax.persistence.Entity;");
bw.newLine();
bw.write("@SuppressWarnings(\"serial\")");
bw.newLine();
// bw.write("@Entity");
// bw.write("@Data");
// bw.newLine();
bw.write("public class " + upTable + " implements Serializable {"); bw.newLine();
bw.newLine();
int size = columns.size();
for (Column vo : columns) {
// bw.write("\t/**" + comments.get(i) + "**/");
bw.write("\t/**");
bw.newLine();
bw.write("\t *" + vo.getComment());
bw.write("\t **/");
bw.newLine();
bw.write("\tprivate " + vo.getType() + " " + vo.getFeild() + ";"); bw.newLine();
bw.newLine();
}
bw.newLine();
// 生成get 和set方法
String tempField = null;
String _tempField = null;
String tempType = null;
for (Column vo : columns) {
tempType = vo.getType();
_tempField = vo.getFeild();
tempField = _tempField.substring(0, 1).toUpperCase()
+ _tempField.substring(1);
bw.newLine();
// bw.write("\tpublic void set" + tempField + "(" + tempType + " _" + // _tempField + "){");
bw.write("\tpublic void set" + tempField + "(" + tempType + " " + _tempField + "){");
bw.newLine();
// bw.write("\t\tthis." + _tempField + "=_" + _tempField + ";"); bw.write("\t\tthis." + _tempField + " = " + _tempField + ";"); bw.newLine();
bw.write("\t}");
bw.newLine();
bw.newLine();
bw.write("\tpublic " + tempType + " get" + tempField + "(){"); bw.newLine();
bw.write("\t\treturn this." + _tempField + ";");
bw.newLine();
bw.write("\t}");
bw.newLine();
}
bw.newLine();
bw.write("}");
bw.newLine();
bw.flush();
bw.close();
}
}
最终的效果
后台的增删改查功能都可以生成!希望对大家有帮助!。

相关文档
最新文档