900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > java实现代码自动生成工具 基于spring boot

java实现代码自动生成工具 基于spring boot

时间:2021-09-20 04:56:21

相关推荐

java实现代码自动生成工具 基于spring boot

前言

此项目主要解决在项目搭建初期,创建项目时很多代码手动创建太过繁琐,耗费不必要的开发时间。通过此代码生成工具可以自动生成相关代码,当然不局限于controller层、service层、entity层、mapper层的代码生成!因为本项目中自定义代码生成规则的配置比较简单,只需自定义模板并创建工厂实例即可。同时可自定义代码的生成路径,未设置则默认生成在本项目下(可更直观查看生成的结构效果,文末有效果图)。

本项目基于SpringBoot,通过beetl模板引擎自动渲染生成代码。

项目源码地址:bhy702-generator

项目结构
一: 导入pom文件相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- mybatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><dependency><groupId>com.ibeetl</groupId><artifactId>beetl-framework-starter</artifactId><version>1.1.68.RELEASE</version></dependency><!-- 升级beetl的依赖,保证在1.8上不出现警告 --><dependency><groupId>org.antlr</groupId><artifactId>antlr4-runtime</artifactId><version>4.7.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

二: 编写beetl配置类

/*** @author: brbai* @create: -10-16 17:12:45* @description:*/@Configuration@Slf4j@Datapublic class BeetlConfiguration {@Value("${beetl.template-path}")private String templatePath;@Value("${beetl.delimiter-statement-start}")private String delimiterStatementStart;@Value("${beetl.delimiter-statement-end}")private String delimiterStatementEnd;@Bean(name = "beetlConfig")public BeetlGroupUtilConfiguration beetlGroupUtilConfiguration() {BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();// Beetl的配置Properties properties = new Properties();properties.setProperty("statementStart",delimiterStatementStart);properties.setProperty("statementEnd",delimiterStatementEnd);properties.setProperty("DELIMITER_STATEMENT_START", delimiterStatementStart);properties.setProperty("DELIMITER_STATEMENT_END", delimiterStatementEnd);beetlGroupUtilConfiguration.setConfigProperties(properties);ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(templatePath);beetlGroupUtilConfiguration.setResourceLoader(resourceLoader);// 调用Beetl的初始化方法beetlGroupUtilConfiguration.init();return beetlGroupUtilConfiguration;}}

三: 配置properties文件

application.properties文件:

server.port=8090server.servlet.context-path=/spring.datasource.url=jdbc:mysql://localhost:3306/building_materials?useUnicode=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true&tinyInt1isBit=falsespring.datasource.username=rootspring.datasource.password=bhy702# beetl模板引擎的加载路径。以resources为根路径,此时表示加载resources/template文件夹中的模板文件beetl.template-path = template# beetl模板引擎语法开始标记beetl.delimiter-statement-start = @# beetl模板引擎语法结束标记。为空时在有开始标记@的行末结束beetl.delimiter-statement-end =# 代码文件的保存路径,注释后默认保存在本项目中#project.base-path = F:\\360MoveData\\Users\\n551\\Desktop

为了便于查看代码生成效果,默认代码生成在此项目内,同时提供自定义代码生成位置。自定义代码生成位置只需配置application.properties中的project.base-path

四: 设计代码模板(代码模板没限制,想怎么设计都行)
下面以Entity.tpl代码模板文件为例:

package ${props.params.packageName};import lombok.Data;@for(column in props.columnList){@if(column.type=='Date'){import java.util.Date;@break;@}}\@Datapublic class ${props.className}{@for(column in props.columnList){private ${column.type} ${column.lowerPropertyName};@}}

五: 根据代码模板确定所需参数数据,添加代码模板的工厂实例。

为了便于开发,我封装了一个模板所需的参数类TplProperties

TplProperties参数类:

/*** @author: brbai* @create: -12-26 11:13:42* @description: 模板参数*/@Datapublic class TplProperties {private String basePath;private String rootPackage;private String tableName;private List<Column> columnList;private Map<String,Object> params = new HashMap();;/*** 表名格式转换* xxx_yyy->XxxYyy*/private String className;/*** 表名格式转换* xxx_yyy->xxxYyy*/private String propertyName;public TplProperties(String basePath, String rootPackage, String tableName, List<Column> columnList) {this.basePath = basePath;this.rootPackage = rootPackage;this.tableName = tableName;this.columnList = columnList;}public TplProperties(String rootPackage, String tableName, List<Column> columnList) {this.rootPackage = rootPackage;this.tableName = tableName;this.columnList = columnList;}public String getClassName() {return StringUtil.mapTableNameToClassName(tableName);}public String getPropertyName() {return StringUtil.mapTableNameToPropertyName(tableName);}public void setParam(String key,Object value) {this.params.put(key,value);}public String getBasePath() {if(basePath == null){//未在properties文件中设置代码生成路径时,代码默认生成在此项目下return System.getProperty("user.dir") + "/src";}return basePath;}}

工厂实例:

/*** @author: brbai* @create: -12-14 19:12:59* @description:*/public class Entity implements Code {@Overridepublic void create(GroupTemplate gt, TplProperties properties, String tplPath) throws IOException {String packageName = properties.getRootPackage()+ ".entity";properties.setParam("packageName",packageName);Template t = gt.getTemplate(tplPath);t.binding("props", properties);GenerateUtil.createFile(t,properties.getBasePath()+"/main/java/"+ packageName.replace(".", "/") + "/" + properties.getClassName() + ".java");}}

六: 识别数据库类型,读取数据库表结构

/*** @Description: 获取数据库表结构* @Param: [sqlSessionFactory]* @return: java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>>*/public static Map<String, Map<String, String>> getDatabaseAttribute(SqlSession sqlSession) throws SQLException {Map<String, Map<String, String>> databaseAttribute = new HashMap<>();Connection connection = sqlSession.getConnection();//获得数据库信息DatabaseMetaData metaData = connection.getMetaData();String databaseName = metaData.getDatabaseProductName();if ("MySQL".equals(databaseName)) {//获得数据库表ResultSet resultSet = metaData.getTables(null, null, null, new String[]{"TABLE"});while (resultSet.next()) {String tableName = resultSet.getString(3);String sql = "SELECT * FROM " + tableName;PreparedStatement preparedStatement = connection.prepareStatement(sql);ResultSet set = preparedStatement.executeQuery();//获得表信息ResultSetMetaData md = set.getMetaData();//获得表字段数int columnCount = md.getColumnCount();Map<String, String> attributes = new LinkedHashMap<>();for (int i = 1; i <= columnCount; i++) {//字段名String columnName = md.getColumnName(i);//字段属性String columnType = md.getColumnTypeName(i);attributes.put(columnName, columnType);}databaseAttribute.put(tableName,attributes);}}else if("Oracle".equals(databaseName)){//DEVTEST是oracle的用户名。此Oracle代码还没怎么测试。ResultSet rs = metaData.getTables("null", "DEVTEST", "%", new String[]{"TABLE"});while (rs.next()) {String tableName = rs.getString("TABLE_NAME");ResultSet columns = metaData.getColumns(null, "DEVTEST", tableName, "%");Map<String, String> attributes = new LinkedHashMap<>();while (columns.next()) {attributes.put(columns.getString("COLUMN_NAME"), columns.getString("TYPE_NAME"));}databaseAttribute.put(tableName, attributes);}}return databaseAttribute;}

七: 数据清洗,设置生成代码的包名,获取工厂实例生成代码文件

/*** @author: brbai* @create: -11-20 14:12:12* @description: test*/@RunWith(SpringRunner.class)@SpringBootTestpublic class CodeTest {@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Autowiredprivate BeetlGroupUtilConfiguration beetlConfig;@Autowiredprivate CodeFactory codeFactory;@Value("${project.base-path:#{null}}")private String basePath;@Testpublic void codeGeneratorTest() throws SQLException{//生成代码的项目包名String rootPackage = "c";GroupTemplate gt = beetlConfig.getGroupTemplate();//获取数据库表结构SqlSession sqlSession = sqlSessionFactory.openSession();Map<String, Map<String, String>> databaseAttribute = DBUtil.getDatabaseAttribute(sqlSession);String databaseName = sqlSession.getConnection().getMetaData().getDatabaseProductName();databaseAttribute.forEach((tableName,columnMap)->{List<Column> columnList = new ArrayList<>();columnMap.forEach((name,type)->{String javaType = null;//数据库行字段类型以及字段名格式转换,并存入模板参数集合if("MySQL".equals(databaseName)){javaType = DBUtil.sqlTypeToJavaType(type);}else if("Oracle".equals(databaseName)){javaType = DBUtil.oracleSqlTypeToJavaType(type);}columnList.add(new Column(name, javaType, StringUtil.mapUnderscoreToCamelCase(name), StringUtil.mapTableNameToClassName(name)));});//构建参数TplProperties properties = null;if(basePath != null){properties = new TplProperties(basePath,rootPackage,tableName,columnList);}else{properties = new TplProperties(rootPackage,tableName,columnList);}try {//代码生成codeFactory.getCodeInstance("CONTROLLER").create(gt,properties,"/Controller.tpl");codeFactory.getCodeInstance("SERVICE").create(gt,properties,"/Service.tpl");codeFactory.getCodeInstance("ENTITY").create(gt,properties,"/Entity.tpl");codeFactory.getCodeInstance("MAPPER").create(gt,properties,"/Mapper.tpl");codeFactory.getCodeInstance("MAPPER_XML").create(gt,properties,"/MapperXml.tpl");} catch (IOException e) {e.printStackTrace();}});}}

运行codeGeneratorTest()方法

效果图如下:

未配置代码生成路径时:

配置了代码生成路径时:

由于项目代码比较多,没能全部贴出来,源码我已经上传码云了,想看源码的小伙伴可以点这里。bhy702-generator

欢迎访问本文的个人博客链接: https://br-bai.github.io//12/26/Java实现代码自动生成工具,基于Spring Boot/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。