若依源码解析:代码生成ruoyi

您所在的位置:网站首页 mybaties源码解析 若依源码解析:代码生成ruoyi

若依源码解析:代码生成ruoyi

2023-06-05 09:41| 来源: 网络整理| 查看: 265

文章目录摘要代码生成器的使用数据库连接配置数据库表设计代码生成器配置修改mybatis别名配置,增加对com.cyl包名的识别修改mybatis的mapper扫描包路径代码生成代码输出模板配置代码生成器原理模板引擎:Velocity使用Velocity模板引擎的一般流程模板语法上下文数据information_schema源码解析导入表结构(com.ruoyi.generator.controller.GenController#importTableSave接口)生成代码(com.ruoyi.generator.controller.GenController#batchGenCode接口)generatorCoded方法

摘要

若依的代码生成器模块(ruoyi-generator)可以根据数据库表的设计信息和配置的模板,自动生成相应的Java代码文件。代码生成器使用Velocity作为模板引擎,根据模板文件中的占位符和变量替换规则,将元数据信息嵌入到生成的代码中,生成具体的代码文件。通过导入表结构和生成代码两个后端接口,实现了快速导入数据库表结构和生成代码的功能。导入表结构会从information_schema数据库的tables和columns表中查询表和列的信息,并插入到ruoyi数据库的gen_table和gen_table_column表中。生成代码时,会根据查询到的表和列信息,初始化Velocity模板引擎,并准备上下文信息,包括变量值信息。然后,读取模板文件,渲染模板,并将渲染后的内容添加到压缩流中生成zip压缩文件,供前端下载使用。ruoyi-vue代码生成器大大提高了开发效率,使得开发人员能够快速生成符合规范的代码文件。

代码生成器的使用

通过以下步骤,若依可以根据数据库表的设计信息自动生成相应的代码文件,极大地提高了开发效率。开发人员可以根据生成的代码文件进行进一步的开发和定制。

以下是若依实现代码自动生成的一般流程:

数据库连接配置

首先,若依需要配置数据库连接信息,包括数据库类型、地址、用户名和密码等。

若依源码解析:代码生成ruoyi-generator_数据库

数据库表设计

在数据库中设计和定义表结构,包括表名、字段名、数据类型、约束等。 若依建表有个要求:表字段 和 表,都需要加注释,注释就是生成页面的显示内容

CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `GOODS_NAME` varchar(255) DEFAULT NULL COMMENT '商品名字', `put_way_flag` tinyint(1) DEFAULT NULL COMMENT '商品是否上架,0:下架,1:上架', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `create_by` varchar(64) DEFAULT NULL COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `update_by` varchar(64) DEFAULT NULL COMMENT '更新人', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表'代码生成器配置

若依提供了一个代码生成器,通过application.yml配置文件可以设置生成器的参数,如生成路径、包名、作者等。

# 代码生成 gen: # 作者 author: zcc # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool packageName: com.cyl.pms # 自动去除表前缀,默认是false autoRemovePre: false # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) tablePrefix: pms_

另外,这里要使用自定义包名com.cyl.pms,所以若依系统中mybatis也要做相应的修改

修改mybatis别名配置,增加对com.cyl包名的识别# MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.cyl.**.domain修改mybatis的mapper扫描包路径

修改com.ruoyi.framework.config.ApplicationConfig类的MapperScan注解,增加对com.cyl包的扫描

@MapperScan({"com.ruoyi.**.mapper","com.cyl.**.mapper"}) public class ApplicationConfig{ ... }代码生成

若依根据配置和模板,通过解析数据库表的元数据信息,自动生成对应的Java类、Mapper接口、Service类、Controller类等代码文件。

进入系统工具-代码生成页面,点击导入按钮,找到goods表并导入,如下图所示

若依源码解析:代码生成ruoyi-generator_ci_02

点击编辑按钮之后,跳转修改生成配置页面。

若依源码解析:代码生成ruoyi-generator_代码生成器_03

若依源码解析:代码生成ruoyi-generator_数据库_04

点击生成代码按钮

若依源码解析:代码生成ruoyi-generator_数据库_05

代码输出

生成的代码文件可以输出到指定的目录中,可以选择直接写入磁盘文件或者打包成压缩文件。 生成的代码目录结构如下所示

├── goodsMenu.sql ├── main │ ├── java │ │ └── com │ │ └── kdyzm │ │ └── business │ │ ├── controller │ │ │ └── GoodsController.java │ │ ├── domain │ │ │ └── Goods.java │ │ ├── mapper │ │ │ └── GoodsMapper.java │ │ └── service │ │ ├── IGoodsService.java │ │ └── impl │ │ └── GoodsServiceImpl.java │ └── resources │ └── mapper │ └── business │ └── GoodsMapper.xml └── vue ├── api │ └── business │ └── goods.js └── views └── business └── goods └── index.vue模板配置

若依代码生成器支持三种数据格式模板的代码生成:单表、树表、主子表,一般默认使用的是单表模板,也是最常使用的模板。

若依源码解析:代码生成ruoyi-generator_数据库_06

代码生成器原理模板引擎:Velocity

在若依(Ruoyi)项目的代码生成中,使用了Apache Velocity作为模板引擎来生成具体的代码。

使用Velocity模板引擎的一般流程

Velocity是一个Java模板引擎,它使用简单的模板语法和变量替换规则来生成文本输出。以下是若依项目中使用Velocity模板引擎的一般流程:

引入Velocity依赖: 首先,在项目的构建文件中(如pom.xml)添加Velocity的依赖项,以便在代码中使用Velocity的相关类和方法。获取模板: 在代码生成过程中,若依会根据配置的模板文件路径,使用Velocity模板引擎获取指定的模板。通常,模板文件以.vm为后缀,如xxx.java.vm表示Java类的模板。创建Velocity模板引擎对象: 若依通过Velocity.getTemplate(template, charset)方法创建Velocity模板引擎对象。template参数是模板文件的路径,charset参数是模板文件的字符编码。准备上下文数据: 在代码生成过程中,若依会准备一些上下文数据,以便在模板中使用。这些数据通常包括表信息、字段信息和其他生成参数等。上下文数据被封装在一个context对象中,可以通过context.put(key, value)方法添加到上下文中。渲染模板: 使用Template.merge(context, writer)方法,将上下文数据应用于模板,并将渲染后的结果写入指定的输出writer中。在若依中,通常使用StringWriter作为输出的writer,以便将渲染后的代码保存为字符串。获取渲染结果: 通过StringWriter.toString()方法获取渲染后的代码字符串,即生成的具体代码。输出代码: 生成的代码可以输出到指定的路径或文件中。若依中使用FileUtils.writeStringToFile(file, content, charset)方法将代码字符串写入文件中。模板语法

Velocity模板引擎使用简洁而强大的模板语法。在若依项目中,模板文件通常采用.java.vm的后缀,表示Java类的模板。在模板文件中,可以使用Velocity的标签、变量和指令来定义动态内容和控制流程。

一些常用的Velocity模板语法包括:

变量替换:使用${variable}来引用变量。条件语句:使用#if、#elseif、#else来控制条件判断。循环语句:使用#foreach来进行循环迭代。宏定义:使用#macro来定义可重用的宏。注释:使用##进行单行注释。上下文数据

在代码生成过程中,若依会准备上下文数据,用于传递给Velocity模板引擎。上下文数据通常包括表信息、字段信息和其他生成参数等。这些数据被封装在一个context对象中,可以使用context.put(key, value)方法将数据添加到上下文中。

在模板中,可以通过${key}的形式引用上下文中的数据。例如,${table.name}表示引用上下文中表名的值。

information_schema

MySQL数据库中的information_schema数据库是MySQL的系统数据库之一,它包含了关于数据库、表、列等元数据信息的表。在代码生成器中,正是利用了information_schema数据库中的TABLES表和COLUMNS表来获取数据库表的信息,从而实现代码的生成。

TABLES表:TABLES表存储了数据库中所有表的信息,包括表名、表所属的数据库、表的引擎类型、创建时间、更新时间等。通过查询TABLES表,代码生成器可以获取到需要生成代码的表的相关信息,如表名、表所在的数据库等。COLUMNS表:COLUMNS表存储了数据库中所有表的列信息,包括列名、数据类型、列的默认值、是否允许为空、字符集等。通过查询COLUMNS表,代码生成器可以获取到需要生成代码的表的列信息,如列名、数据类型等。

通过查询TABLES表和COLUMNS表,代码生成器可以获得数据库表的设计信息,包括表名、列名、数据类型等。这些信息可以用于生成代码文件,例如生成实体类的属性、Mapper接口的方法等。通过结合模板引擎,将这些数据库表的设计信息嵌入到模板中,就可以自动生成具体的Java代码文件。

代码生成器利用information_schema数据库中的TABLES表和COLUMNS表,提供了一种便捷的方式来获取数据库表的结构信息,使得生成的代码与数据库表的设计保持一致,减少了手动编写代码的工作量,并提高了代码的一致性和可维护性。

源码解析

在ruoyi-vue项目的ruoyi-generator模块中,代码生成器相关的代码实现了以下步骤。 通过以下步骤,ruoyi-vue代码生成器可以根据数据库表的结构信息和模板文件,生成具体的代码文件。导入表结构步骤将表和列信息存储到数据库中,生成代码步骤则利用这些信息和模板进行代码的生成和打包。这样可以实现代码的快速生成和下载,提高开发效率。

导入表结构(com.ruoyi.generator.controller.GenController#importTableSave接口)@PreAuthorize("@ss.hasPermi('tool:gen:import')") @Log(title = "代码生成", businessType = BusinessType.IMPORT) @PostMapping("/importTable") public AjaxResult importTableSave(String tables) { String[] tableNames = Convert.toStrArray(tables); // 查询表信息 List tableList = genTableService.selectDbTableListByNames(tableNames); genTableService.importGenTable(tableList, SecurityUtils.getUserId()); return AjaxResult.success(); }通过查询information_schema数据库的tables表,获取目标表的表名、表注释、创建时间和更新时间。这里忽略了定时任务的表和已经生成过的表。初始化表数据,并将数据插入ruoyi数据库的gen_table表中。通过查询information_schema数据库的columns表,获取目标表的列信息,包括字段名、字段注释、字段类型、是否允许为null等详细信息。初始化列信息,并将数据插入ruoyi数据库的gen_table_column表中。生成代码(com.ruoyi.generator.controller.GenController#batchGenCode接口)@PreAuthorize("@ss.hasPermi('tool:gen:code')") @Log(title = "代码生成", businessType = BusinessType.GENCODE) @GetMapping("/batchGenCode") public void batchGenCode(HttpServletResponse response, String tables) throws IOException { String[] tableNames = Convert.toStrArray(tables); byte[] data = genTableService.downloadCode(tableNames); genCode(response, data); }从ruoyi数据库的gen_table表和gen_table_column表中查询出生成代码所需的表和列信息。初始化Velocity模板引擎。准备Velocity上下文信息,包括变量值信息。上下文中存储了从数据库查询到的表和列信息,以及其他生成参数。读取模板文件,渲染模板,并将渲染后的模板内容添加到压缩流中,最后生成zip压缩文件供前端下载。generatorCoded方法/** * 生成代码(自定义路径) * * @param tableName 表名称 */ @Override public void generatorCode(String tableName) { // 查询表信息 GenTable table = genTableMapper.selectGenTableByName(tableName); Result result = getResult(table); for (String template : result.templates) { if (template.endsWith(".java.vm")) { result.context.put("fullPackage", getFullPackage(template)); } // 渲染模板 StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, Constants.UTF8); tpl.merge(result.context, sw); String path = null; try { path = generatePath(template, table); File file = new File(path); FileUtils.writeStringToFile(file, sw.toString(), CharsetKit.UTF_8); log.info("{}", file.getAbsoluteFile()); } catch (IOException e) { throw new ServiceException("渲染模板失败,表名:" + table.getTableName() + ", path: " + path); } } }

这段代码是在若依(Ruoyi)项目的代码生成器中的一个方法,用于生成代码并写入文件。

具体解释如下:

方法签名:public void generatorCode(String tableName)该方法接受一个参数 tableName,表示要生成代码的表名。查询表信息:GenTable table = genTableMapper.selectGenTableByName(tableName);通过 genTableMapper(数据访问层)根据表名查询数据库中的表信息,并将结果保存在 GenTable 对象 table 中。获取模板结果:Result result = getResult(table);通过调用 getResult 方法,根据查询到的表信息 table,获取生成代码所需的模板文件和上下文数据,结果保存在 Result 对象 result 中。遍历模板文件:for (String template : result.templates)遍历 result 中的模板文件列表。处理 Java 模板:if (template.endsWith(".java.vm")) { result.context.put("fullPackage", getFullPackage(template)); }

如果模板文件以 .java.vm 结尾,表示为 Java 类的模板文件。将生成的代码所属的包名(通过 getFullPackage 方法获取)放入上下文数据 result.context 中。

渲染模板:StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, Constants.UTF8); tpl.merge(result.context, sw);

使用 Velocity 模板引擎,根据模板文件和上下文数据,将模板渲染为具体的代码,结果保存在 StringWriter 对象 sw 中。

生成文件:String path = generatePath(template, table); File file = new File(path); FileUtils.writeStringToFile(file, sw.toString(), CharsetKit.UTF_8);

根据模板文件和表信息,生成代码文件的路径。然后创建文件对象 file,将渲染后的代码内容写入文件中。

日志输出:log.info("{}", file.getAbsoluteFile());输出生成的代码文件的绝对路径。异常处理:} catch (IOException e) { throw new ServiceException("渲染模板失败,表名:" + table.getTableName() + ", path: " + path); }

如果在渲染模板和生成文件的过程中发生了异常,抛出自定义的 ServiceException 异常,并提供失败的表名和路径信息。

通过以上步骤,这段代码会根据表名查询表信息,获取模板文件和上下文数据,然后遍历模板文件,将模板渲染为具体的代码,最后生成代码文件并写入磁盘。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3