动态代码生成 静态代码生成
Speedment是一个开源工具包 ,可用于生成Java实体和管理器以与数据库进行通信。 如果您需要域模型的对象关系映射,那么这很好,但是在某些情况下,您可能希望使用数据库作为模板来生成完全不同的东西。 在本文中,我将向您展示一个hack,您可以使用该hack接管Speedment中的该代码生成器并将其用于个人目的。 在本文的结尾,我们将提供一个完全空白的代码生成器,我们可以对其进行编程以进行竞标!
背景
Speedment旨在用作Maven的插件。 通过调用各种新的Maven目标,我们可以指示Speedment连接到数据库,生成源代码,并从我们的项目中删除所有生成的文件。 它还包含一个图形用户界面,使您可以轻松地基于从数据库中收集的元数据配置生成作业。 现在,想象一下我们可以通过分析该元数据收集的所有信息。 我们知道存在哪些表,知道它们具有的所有约束以及各个列具有什么类型。 可能有数百万个用例,我们可以从该元数据自动生成内容中受益。 按照本文中的步骤,我们可以做所有这些事情。
步骤1:建立定期加速项目
创建一个新的Maven项目并将以下内容添加到pom.xml文件中:
pom.xml
<properties><speedment.version>3.0.1</speedment.version><mysql.version>5.1.39</mysql.version>
</properties><dependencies><dependency><groupId>com.speedment</groupId><artifactId>runtime</artifactId><version>${speedment.version}</version><type>pom</type></dependency>
</dependencies><build><plugins><plugin><groupId>com.speedment</groupId><artifactId>speedment-maven-plugin</artifactId><version>${speedment.version}</version><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency></dependencies></plugin></plugins>
</build>
我们添加了Speedment作为运行时依赖项,并配置了Maven插件以使用标准MySQL JDBC驱动程序连接到我们的数据库。 大! 现在,您可以访问许多新的Maven目标。 例如,如果我们要启动Speedment UI,可以通过运行以下命令来实现:
mvn speedment:tool
如果我们现在这样做,Speedment将以正常模式启动,使我们能够连接到数据库,并从数据库中生成实体和管理器,以使用Java 8流与该数据库进行通信。 这不是我们这次想要做的。 我们希望对其进行修改,以使其完全满足我们的要求。 因此,我们继续修改pom。
步骤2:修改插件声明
速度以模块化的方式构建,由不同的工件负责不同的任务。 所有预先存在的生成器任务都位于一个名为“ com.speedment.generator:generator-standard”的工件中。 那就是我们要罢工的地方! 通过从类路径中删除该工件,我们可以防止Speedment生成我们不希望生成的任何东西。
我们将pom修改如下:
...
<plugin><groupId>com.speedment</groupId><artifactId>speedment-maven-plugin</artifactId><version>${speedment.version}</version><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Add this: --><dependency><groupId>com.speedment</groupId><artifactId>tool</artifactId><version>${speedment.version}</version><type>pom</type><exclusions><exclusion><groupId>com.speedment.generator</groupId><artifactId>generator-standard</artifactId></exclusion></exclusions></dependency></dependencies>
</plugin>
...
那是什么? 我们通过添加一个来排除依赖项? 那怎么能工作呢? 好吧,Speedment旨在包含尽可能少的代码,除非应用程序明确需要。 “ com.speedment:tool-artifact”已经是maven插件的依赖项,通过在maven插件的<dependencies>部分中提及它,我们可以将设置附加到其配置中。 在这种情况下,我们说我们希望插件可以访问该工具,但我们不希望标准生成器。
但是这里有一个问题。 如果我们尝试启动speedment:tool目标,我们将获得一个例外。 原因是Speedment 希望标准翻译器位于类路径中。
这是第二个丑陋的入侵发生的地方。在我们的项目中,我们创建一个名为com.speedment.generator.standard的新程序包,并在其中定义一个名为StandardTranslatorBundle.java的新Java文件。 事实证明,这是Speedment真正需要工作的唯一文件。 我们为其提供以下内容:
StandardTranslatorBundle.java
package com.speedment.generator.standard;import com.speedment.common.injector.InjectBundle;
import java.util.stream.Stream;public final class StandardTranslatorBundle implements InjectBundle {@Overridepublic Stream<Class<?>> injectables() {return Stream.empty();}
}
接下来,我们需要用我们自己的项目替换排除的工件,以使插件永远不会意识到文件丢失。 我们返回到pom.xml文件,并将我们自己的项目添加到speedment-maven-plugin的<dependencies>部分。 完整的pom文件如下所示:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.github.pyknic</groupId><artifactId>speedment-general-purpose</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><speedment.version>3.0.1</speedment.version></properties><dependencies><dependency><groupId>com.speedment</groupId><artifactId>runtime</artifactId><version>${speedment.version}</version><type>pom</type></dependency></dependencies><build><plugins><plugin><groupId>com.speedment</groupId><artifactId>speedment-maven-plugin</artifactId><version>${speedment.version}</version><dependencies><dependency><groupId>com.speedment</groupId><artifactId>tool</artifactId><version>${speedment.version}</version><type>pom</type><exclusions><exclusion><groupId>com.speedment.generator</groupId><artifactId>generator-standard</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.github.pyknic</groupId><artifactId>speedment-general-purpose</artifactId><version>1.0.0-SNAPSHOT</version></dependency> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.39</version></dependency></dependencies></plugin></plugins></build>
</project>
如果现在我们构建项目,然后运行target speedment:tool,我们应该能够毫无问题地启动图形用户界面。 如果我们连接到数据库,然后按“ Generate”,则什么也不会发生! 我们已经成功地破解了Speedment,使其无所作为!
第3步:将速度变成您想要的东西
现在,当我们有了全新的,干净的Speedment时,就可以开始将其转变为我们想要的应用程序了。 我们仍然具有强大的用户界面,可以在其中基于数据库模型配置代码生成。 我们有一个富有表现力的实用程序和帮助程序类库,用于处理生成的代码。 最重要的是,我们拥有一种用于以面向对象的方式分析数据库元数据的结构。
要了解有关如何编写自己的代码生成模板并将其挂钩到平台的更多信息, 请参阅本文 。 您还应该查看Speedment GitHub页面,以了解现有生成器(我们刚刚禁用的生成器)如何工作,并可能会启发您如何构建自己的生成器。
直到下次,继续入侵!
翻译自: https://www.javacodegeeks.com/2016/11/hack-speedment-personal-code-generator.html
动态代码生成 静态代码生成