逆向生成原理

逆向工程原理

    • 前言
    • 逆向工程的原理
      • 1.Freemarker模板引擎
      • 2.逆向工程的原理

前言

在我们实际开发过程中,开发流程大体可以分为需求分析、数据库字段设计、然后再开始编码,然后就开始创建我们实体类、controller、service、serviceImpl、mapper,进行CRUD的编写。虽然看起来这些操作都十分简单,但是会占据我们大量的开发时间,我们简单的CRUD编写已经有MyBatis和MyBatis-plus框架替我们完成。但是我们还能不能再减轻我们无关的工作量呢?类似于Springboot那样,将我们复杂的依赖交给容器管理。答案是可以的,我们研究不同的实体类、controller层不难发现,就拿实体类来举例,每个实体类不同的地方就是实体类属性的字段类型跟字段名不一样,而这些字段不就是我们从数据库映射过来的吗?那么我们只要能够从数据库那拿到字段信息再加以转换不就可以吗。这也就是我们MyBatis的逆向工程或者MyBatis-plus的逆向工程的原理,也是很多逆向工程的原理,如renrenfast、若依框架等等。但是哪些框架更多的在乎通用性,做了很多对我们没有用的封装。假如我们有一些定制的请求就很难进行业务逻辑的定制,那么就还是需要我们自己手动添加。所以我们需要理解逆向工程的原理。我们才能够知道在哪里修改才能出现我们自己想要的结果。接下来我就来讲解下逆向工程的原理。

逆向工程的原理

1.Freemarker模板引擎

在此之前,我们先来了解一下什么是Freemarker模板引擎?说通俗易懂一点就是我们制造一个模板,然后将数据往模板里面填入数据。类似于动态SQL和前端vue的做法。Freemarker的语法也比较简单。举几个简单的例子,更多不在这里展开,有需要的在网上搜索其他资料了解。

首先引入依赖

<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version>
</dependency>

例如我们在D盘ftl目录下有一个模板文件test.ftl,内容如下:

<h1>
public class ${pojoName} implements Serializable {
}
</h1>

然后我们后端向就需要往这个模板里面填入数据并输出为一个新文件,具体使用如下:

public class FreemarkerTest {public static void main(String[] args) throws Exception {// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。Configuration configuration = new Configuration(Configuration.getVersion());// 第二步:设置模板文件所在的路径。configuration.setDirectoryForTemplateLoading(new File("D:\\ftl"));// 第三步:设置模板文件使用的字符集。一般就是utf‐8. 注意版本。新版本不需要configuration.setDefaultEncoding("UTF‐8");// 第四步:加载一个模板,创建一个模板对象。Template template = configuration.getTemplate("test.ftl");// 第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。Map dataModel = new HashMap<>();//向数据集中添加数据dataModel.put("pojoName", "user");// 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。Writer out = new FileWriter(new File("D:\\ftl\\out\\test.html"));// 第七步:调用模板对象的process方法输出文件。template.process(dataModel, out);// 第八步:关闭流。out.close();}
}

然后打开test.html文件就可以看到下图内容
在这里插入图片描述

可以看到模板引擎自动将我们传入的数据填充到模板中,并成功展现。
到此,恭喜你,你已经会一些简单的Freemarker操作了。

一个ftl模版文件,是由少数几个动态标签加上其他静态的内容组成。动态标签包含以下几种:

  • 普通参数
${demo}
  • list标签
<#list studentList as student>
`student.id/{student.id}/student.id/`{[studnet.name](http://studnet.name/)}
</#list>
  • if条件标签
<#if student_index % 2 == 0>1
<#else>0
</#if>
  • 在if标签中,还可以进行简单的null值判断
<#if a??>a不为空时。。
<#else>a为空时###
</#if>
  • 日期标签
当前日期: `date?date
当前时间:{date?date} 
当前时间:date?date
当前时间:`{date?time}
当前日期和时间:`date?datetime
自定义日期格式:{date?datetime} 
自定义日期格式:date?datetime
自定义日期格式:`{date?string("yyyyMM/dd HH:mm: ss")}
  • 包含标签
<#include "test.ftl"/>

以上只是为了后面讲解时,不至于看不懂,略微讲解一下,如果感兴趣,可以去网上搜索相关教程进行学习。

2.逆向工程的原理

接下来我们来看一看MyBatis-plus的逆向工程是怎么实现的。

(1)引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.5</version>
</dependency>

查看文件,我们不难发现里面就是一堆ftl文件,结果显而易见,最终都是查出相关数据,然后将数据添加到相关的模板代码之中,然后得到最终的文件,最后我们只需要了解我们所需要的数据是怎么得到的。我们就能够清楚逆向工程的原理。

在这里插入图片描述

通常,我们使用jdbc只是用来查询数据,但是我们也可以用来查询表的结构以及注释信息,下面示例代码就是获取我们用来逆向生成的数据。得到数据填入模板中就能得到最终的文件。

public static void main(String[] args) throws Exception {//mysqlClass.forName("com.mysql.cj.jdbc.Driver");Properties props = new Properties();  props.put("useInformationSchema", "true"); //mysql获取表注释需要加上这个属性 props.put("user", "root");  props.put("password", "root");  Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/genserver?serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true",props);//oracle
//		Class.forName("oracle.jdbc.driver.OracleDriver");
//		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@172.16.49.65:1521/motion","swordrisk","risk#230");//		 Properties props = new Properties();  
//         props.put("remarksReporting", "true");  //要获取注释,需要增加这个属性。
//         props.put("user", "swordrisk");  
//         props.put("password", "risk#230");  
//         Connection con = DriverManager.getConnection("jdbc:oracle:thin:@172.16.49.65:1521/motion",props);//上面建立连接System.out.println("========映射表信息==============");DatabaseMetaData meta = con.getMetaData(); ResultSet tables = meta.getTables("genserver", "%", "black_info", new String[] {"TABLE"});while(tables.next()) {ResultSetMetaData metaData = tables.getMetaData();System.out.println(metaData.getColumnCount());for(int i = 1 ; i <= metaData.getColumnCount(); i ++) {System.out.println(metaData.getColumnName(i)+" ==> "+tables.getString(metaData.getColumnName(i)));}System.out.println(tables.getString("TABLE_NAME")+" --->>> "+tables.getString("REMARKS"));}System.out.println("========映射列信息==============");ResultSet columns = meta.getColumns("genserver", "%", "black_info", "%");System.out.println("columnName|columnType|datasize|digits|nullable|remarks");while(columns.next()) {String columnName = columns.getString("COLUMN_NAME"); String columnType = columns.getString("TYPE_NAME"); int datasize = columns.getInt("COLUMN_SIZE"); int digits = columns.getInt("DECIMAL_DIGITS"); int nullable = columns.getInt("NULLABLE"); String remarks = columns.getString("REMARKS");System.out.println(columnName+"|"+columnType+"|"+datasize+"|"+digits+"|"+ nullable+"|"+remarks);}System.out.println("========映射主键信息==============");ResultSet primaryKeys = meta.getPrimaryKeys("genserver", "%", "black_info");while(primaryKeys.next()) {ResultSetMetaData metaData = primaryKeys.getMetaData();System.out.println("主键个数:"+metaData.getColumnCount());for(int i = 1 ; i <= metaData.getColumnCount(); i ++) {System.out.println(metaData.getColumnName(i)+" ==> "+primaryKeys.getString(metaData.getColumnName(i)));}}}

输出结果

在这里插入图片描述

下面就是实体类的模板文件代码,感兴趣可以阅读一下。

package pojo;import java.io.Serializable;
import java.util.Date;
import java.sql.Timestamp;import com.alibaba.fastjson.annotation.JSONField;import annotation.Table;
import annotation.TableColumn;/**
* @desc:the module of table ${table_name}
* @desc for the condition of one page mamage the CRUD function of one table, 
*	you dan use the @Table and the @TableColumn annotation for rapidly coding
<#if table_remark !="">* @desc found table comment  ${table_remark},default used as the fileName of the excel file Exported</#if> 
* @author kklmars
* @date ${gen_time}
*/
@Table(tableName = "${table_name_small}"<#if table_remark !="">,expFileName="${table_remark}"<#else>,expFileName="导出数据文件"</#if> <#if table_order_by?exists>,orderBy="${table_order_by}"</#if><#if table_order?exists>,order="${table_order}"</#if>)
public class ${pojo_name} implements Serializable{<#if COLUMNS?exists><#list COLUMNS as model>/*** this method is generated by GenUI.CodeGen.enjoy coding.* ${model.javaName} the value of ${table_name}.${model.columnName}* Found comment on this column is ${model.remarks} default used as the header of this column in excel exported and the query table on page*/<#if model.javaType=="Date">@JSONField(format="yyyy-MM-dd")<#elseif model.javaType=="Timestamp">@JSONField(format="yyyy-MM-dd hh:mm:ss")</#if>@TableColumn(dbColumn = "${model.columnName}",dbColumnType = "${model.columnType}"<#if model.remarks != "">,excelHeader = "${model.remarks}"</#if><#if model.isPK == "true">,isPK="true"</#if>)private ${model.javaType} ${model.javaName};</#list></#if>private static final long serialVersionUID = 1L;<#if COLUMNS?exists><#list COLUMNS as model>public ${model.javaType} ${model.getterName}() {return ${model.javaName};}public void ${model.setterName}(${model.javaType} ${model.javaName}) {<#if model.javaType == "String">this.${model.javaName} = ${model.javaName} == null ? null : ${model.javaName}.trim();<#else>this.${model.javaName} = ${model.javaName};</#if>}</#list></#if>public String toString(){StringBuilder sb = new StringBuilder();sb.append("pojo.${pojo_name} ").append("[");<#if COLUMNS?exists><#list COLUMNS as model>sb.append(", ${model.javaName} = ").append(${model.javaName});</#list></#if>sb.append("]");return sb.toString();}}

综上,我们就理清了逆向工程的原理,就是将实体类、controller、service、serviceImpl、mapper等里面不会发生变化的作为静态模板,然后我们通过jdbc建立连接,在连接中获取表信息。然后填充到模板中,最终就能得到最终的实体类或我们想要的文件。当然,这种方法不仅仅只能用在这个地方,在我们热点商品详情页、首页等等不会发生太大变化、但是访问非常高的地方,我们就可以利用模板生成静态页面,然后放入nginx中,提高我们的系统性能。
最后希望能够点赞关注收藏,让我创作更多有意义的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/499191.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体

更新日期&#xff1a;2024年12月30日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 问题再现通过Tag搜索物体&#xff08;SearchByTag&#xff09;打开SearchByTag窗口搜索标记指定Tag的所有物体批量修改Tag搜索Undefined状态的所有物体 …

JWT包中的源码分析【Golang】

前言 最近在学web编程的途中&#xff0c;经过学长提醒&#xff0c;在进行登陆&#xff08;Login&#xff09;操作之后&#xff0c;识别是否登陆的标识应该要放入authorization中&#xff0c;正好最近也在学鉴权&#xff0c;就顺便来看看源码了。 正文 1. 代码示例 在进行分…

鸿蒙应用开发(1)

可能以为通过 鸿蒙应用开发启航计划&#xff08;点我去看上一节&#xff09; 的内容&#xff0c;就足够了&#xff0c;其实还没有。 可是我还是要告诉你&#xff0c;你还需要学习新的语言 -- ArkTS。 &#xff0c;ArkTS是HUAWEI开发的程序语言。你需要学习这门语言。这会花费你…

python爬虫--小白篇【selenium自动爬取文件】

一、问题描述 在学习或工作中需要爬取文件资源时&#xff0c;由于文件数量太多&#xff0c;手动单个下载文件效率低&#xff0c;操作麻烦&#xff0c;采用selenium框架自动爬取文件数据是不二选择。如需要爬取下面网站中包含的全部pdf文件&#xff0c;并将其转为Markdown格式。…

超大规模分类(一):噪声对比估计(Noise Contrastive Estimation, NCE)

NCE损失对应的论文为《A fast and simple algorithm for training neural probabilistic language models》&#xff0c;发表于2012年的ICML会议。 背景 在2012年&#xff0c;语言模型一般采用n-gram的方法&#xff0c;统计单词/上下文间的共现关系&#xff0c;比神经概率语言…

latex 尖括号怎么写 编译出来是问号

首先引入\usepackage{amsmath}使用\langle \range&#xff0c; 如下&#xff1a; These knowledge graphs represent real-world facts in the form of triples of \(\langle entity, relationship, entity \rangle \)编译展示出来如下&#xff1a;

永磁同步电机控制算法--最大转矩电流比控制(牛顿迭代法)

一、原理介绍 搭建了基于牛顿迭代法的MTPA双闭环矢量控制系统 二、仿真验证 在MATLAB/simulink里面验证所提算法&#xff0c;采用和实验中一致的控制周期1e-4&#xff0c;电机部分计算周期为1e-6。仿真模型如下所示&#xff1a; 对直接公式计算法和牛顿迭代法进行仿真对比验…

[Win32/ATL]_[初级]_[处理WM_PAINT消息注意事项]

场景 在开发Win32/WTL程序时&#xff0c;遇到了使用CFolderDialog(atldlgs.h)打不开目录选择对话框的情况。具体表现是执行了窗口的DoModal&#xff0c;却没有窗口弹出来。 可以确定执行操作是在主线程,并不是工作线程。调试时暂停看堆栈&#xff0c;知道到DoModal方法里的SHB…

华为配置 之 RIP

简介&#xff1a; RIP&#xff08;路由信息协议&#xff09;是一种广泛使用的内部网关协议&#xff0c;基于距离向量算法来决定路径。它通过向全网广播路由控制信息来动态交换网络拓扑信息&#xff0c;从而计算出最佳路由路径。RIP易于配置和理解&#xff0c;非常适用于小型网络…

RCE-PLUS (学习记录)

源码 <?php error_reporting(0); highlight_file(__FILE__); function strCheck($cmd) {if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){return($cmd);}else{die("i hate this"…

Unity Mesh生成Cube

1. 配置一个Cube的每个面的数据 一共是6个面&#xff0c;每个面包含的数据包括4个顶点的相对顶点坐标&#xff08;Cube的中心为原点&#xff09;&#xff0c;法线方向&#xff0c;UV坐标&#xff0c;顶点渲染顺序&#xff0c;以及这个面用到的材质&#xff0c;因为这里是Top&am…

【YOLO算法改进】ALSS-YOLO:无人机热红外图像|野生动物小目标检测

目录 论文信息 论文创新点 1.自适应轻量通道分割和洗牌&#xff08;ALSS&#xff09;模块 2.轻量坐标注意力&#xff08;LCA&#xff09;模块 3.单通道聚焦模块 4.FineSIOU损失函数 摘要 架构设计 轻量高效网络架构 - ALSS模块 LCA模块 单通道聚焦模块 损失函数优…

【亚马逊云】基于Amazon EC2实例部署 NextCloud 云网盘并使用 Docker-compose 搭建 ONLYOFFICE 企业在线办公应用软件

文章目录 1. 部署EC2实例2. 安装 Docker 服务3. 安装docker-compose4. 创建Docker-compose文件5. 创建nginx.conf文件6. 运行docker-compose命令开始部署7. 访问ONLYOFFICE插件8. 访问NextCloud云盘9. 下载并启用ONLYOFFICE插件10. 上传文件测试11. 所遇问题12. 参考链接 1. 部…

使用爬虫技术获取网页中的半结构化数据

目录 前言1. 半结构化数据与爬虫技术简介1.1 半结构化数据的定义与特性1.2 爬虫技术的基本原理 2. 爬取半结构化数据的实现过程2.1 明确目标与准备2.2 发送HTTP请求2.3 解析网页内容2.4 动态内容的处理2.5 数据存储与清洗 3. 技术挑战与应对策略3.1 处理反爬机制3.2 提高爬取效…

win10、win11-鼠标右键还原、暂停更新

系统优化 win 10jihuo win 11jihuo鼠标右键还原暂停更新 update 2024.12.28win 10 jihuo winx&#xff0c;打开powershell管理员&#xff0c;输入以下命令,选择1并等待 irm https://get.activated.win | iex参考&#xff1a;https://www.bilibili.com/video/BV1TN411M72J/?sp…

【蓝桥杯选拔赛真题87】python输出字符串 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python输出字符串 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python输出字符串 第十五届蓝桥杯青少年组python比赛选拔赛真题详细解析…

有什么AI辅助阅读文献工具推荐?

AI的发展速度非常快&#xff0c;在很多方面都已经可以提供货真价实的辅助能力。 比如AI辅助阅读方面&#xff0c;可以获取、分析和理解大量文献资料。这可以帮助我们快速浏览和理解PDF文件和其他文档&#xff0c;提高我们的工作效率和学习效率&#xff0c;达到降本增效。 作为…

各个Spring Cloud版本有何主要差异

Spring Cloud 的各个版本之间确实存在一些关键差异&#xff0c;这些差异主要体现在功能更新、性能优化、对新技术的支持以及对旧有技术的替代等方面。 1. Spring Cloud Dalston 这是 Spring Cloud 的一个早期版本&#xff0c;它提供了微服务架构所需的基本组件&#xff0c;如服…

【翻译】审慎对齐:推理使更安全的语言模型成为可能

原文&#xff1a;https://arxiv.org/abs/2412.16339 出自OpenAI 摘要 随着大规模语言模型对安全关键领域的影响越来越大&#xff0c;确保它们可靠地遵守定义良好的原则仍然是一个基本挑战。本文提出慎思校准&#xff0c;一种新的范式&#xff0c;直接教模型安全规范&#xff…