Java >> Java-zelfstudie >  >> Java

Hack Speedment in uw eigen persoonlijke codegenerator

Speedment is een Open Source-toolkit die kan worden gebruikt om Java-entiteiten en -managers te genereren voor communicatie met een database. Dit is geweldig als je een Object Relational Mapping van het domeinmodel nodig hebt, maar in sommige gevallen wil je misschien iets heel anders genereren met je database als sjabloon. In dit artikel ga ik je een hack laten zien die je kunt gebruiken om die codegenerator in Speedment over te nemen en voor je eigen persoonlijke doeleinden te gebruiken. Aan het einde van het artikel hebben we een volledig blanco codegenerator die we kunnen programmeren om onze biedingen uit te voeren!

Achtergrond

Speedment is ontworpen om te werken als een plug-in voor Maven. Door verschillende nieuwe Maven-doelen aan te roepen, kunnen we Speedment opdracht geven om verbinding te maken met een database, broncode te genereren en ook alle gegenereerde bestanden uit ons project te verwijderen. Het bevat ook een grafische gebruikersinterface die het gemakkelijk maakt om de generatietaak te configureren op basis van metagegevens die uit onze database zijn verzameld. Stel je nu al deze informatie voor die we kunnen verzamelen door die metadata te analyseren. We weten welke tabellen er bestaan, we weten welke beperkingen ze hebben en welke typen de afzonderlijke kolommen hebben. Er zijn waarschijnlijk miljoenen use-cases waar we kunnen profiteren van het automatisch genereren van dingen uit die metadata. Door de stappen in dit artikel te volgen, kunnen we al die dingen doen.

Stap 1:Zet een regulier Speedment-project op

Maak een nieuw Maven-project en voeg het volgende toe aan het pom.xml-bestand:

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>

We hebben Speedment toegevoegd als runtime-afhankelijkheid en de Maven-plug-in geconfigureerd om de standaard MySQL JDBC-driver te gebruiken om verbinding te maken met onze database. Super goed! Je hebt nu toegang tot een aantal nieuwe Maven-doelen. Als we bijvoorbeeld de Speedment-gebruikersinterface willen starten, kunnen we dat doen door het volgende uit te voeren:

mvn speedment:tool

Als we dat nu zouden doen, zou Speedment in de normale modus worden gestart, waardoor we verbinding kunnen maken met een database en daaruit entiteiten en managers kunnen genereren voor communicatie met die database met behulp van Java 8-streams. Dat is niet wat we deze keer willen doen. We willen het hacken zodat het precies doet wat we nodig hebben. We blijven daarom de pom aanpassen.

Stap 2:wijzig de plug-inverklaring

Speedment is modulair opgebouwd met verschillende artefacten die verantwoordelijk zijn voor verschillende taken. Alle reeds bestaande generatortaken bevinden zich in een artefact genaamd "com.speedment.generator:generator-standaard". Dat is waar we gaan toeslaan! Door dat artefact uit het klassenpad te verwijderen, kunnen we voorkomen dat Speedment iets genereert wat we niet willen.

We passen de pom als volgt aan:

...
<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>
...

Wat is dat? We sluiten een afhankelijkheid uit door er een toe te voegen? Hoe kan dat zelfs werken? Welnu, Speedment is ontworpen om zo min mogelijk code op te nemen, tenzij de toepassing dit expliciet nodig heeft. De "com.speedment:tool-artifact" is al een afhankelijkheid van de maven-plug-in, en door het te vermelden in de -sectie van de maven-plug-in, kunnen we instellingen aan de configuratie toevoegen. In dit geval zeggen we dat we willen dat de plug-in toegang heeft tot de tool, behalve dat we de standaardgenerator niet willen.

Er is hier wel een probleem. Als we het doel speedment:tool proberen te lanceren, krijgen we een uitzondering. De reden hiervoor is dat Speedment verwacht de standaardvertalers op het klassenpad.

Hier komt de tweede lelijke hack om de hoek kijken. In ons project maken we een nieuw pakket met de naam com.speedment.generator.standard en definiëren daarin een nieuw java-bestand met de naam StandardTranslatorBundle.java. Het blijkt dat dit het enige bestand is dat Speedment echt nodig heeft om te werken. We geven het de volgende inhoud:

StandardTranslatorBundle.java

package com.speedment.generator.standard;


import com.speedment.common.injector.InjectBundle;
import java.util.stream.Stream;


public final class StandardTranslatorBundle implements InjectBundle {
    @Override
    public Stream<Class<?>> injectables() {
        return Stream.empty();
    }
}

Vervolgens moeten we het uitgesloten artefact vervangen door ons eigen project, zodat de plug-in zich nooit realiseert dat de bestanden ontbreken. We keren terug naar het pom.xml-bestand en voegen ons eigen project toe aan de -sectie van de speedment-maven-plugin. Het volledige pom-bestand ziet er als volgt uit:

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>

Als we nu ons project bouwen en vervolgens de goal speedment:tool uitvoeren, zouden we de grafische gebruikersinterface probleemloos moeten kunnen starten. Als we verbinding maken met de database en vervolgens op "Genereren" drukken, gebeurt er helemaal niets! We hebben Speedment met succes gehackt om helemaal niets te doen!

Stap 3:verander snelheid in wat je wilt

Als we nu een frisse, schone Speedment hebben, kunnen we er de applicatie van maken die we willen dat het is. We hebben nog steeds een krachtige gebruikersinterface waar we de codegeneratie kunnen configureren op basis van een databasemodel. We hebben een expressieve bibliotheek met hulpprogramma's en hulpklassen om met gegenereerde code te werken. En bovenal hebben we een structuur om de metadata van de database op een objectgeoriënteerde manier te analyseren.

Lees dit artikel voor meer informatie over het schrijven van uw eigen sjablonen voor het genereren van codes en het aansluiten ervan op het platform. Je moet ook de Speedment GitHub-pagina bekijken om te leren hoe de bestaande generatoren werken (degene die we zojuist hebben uitgeschakeld) en misschien wat inspiratie opdoen over hoe je je eigen generatoren kunt bouwen.

Tot de volgende keer, blijf hacken!

Java-tag