how to generate customized java 8 code from your database
TRANSCRIPT
![Page 1: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/1.jpg)
How to Generate Customized Java 8 Code From Your DatabasePer MinborgCTO, Speedment, Inc
Emil ForslundDeveloper, Speedment, Inc.
![Page 2: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/2.jpg)
Every Decision a Developer Makes is a Trade-off
The best code is no code at all
![Page 3: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/3.jpg)
Using Code Generation• Makes the code efficient and
short• Modifications are done once
and applied everywhere• Minimizes errors• “DRY” (Don’t Repeat
Yourself) vs. ”WET” (We Enjoy Typing)
• “Code your code”
But how can we control the generated code?
![Page 4: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/4.jpg)
About UsPer Minborg• Founder of several IT companies• Lives in Palo Alto • 20 years of Java experience• 15+ US patents • Speaker at Java events• Blog: Minborg’s Java Pot
Emil Forslund• Java Developer• Lives in Palo Alto• 8 years of Java
experience• Speaker at Java events • Blog: Age of Java
Spire• Speedment Open Source mascot• Lives on GitHub • 2 years of mascot experience
![Page 5: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/5.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 6: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/6.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 7: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/7.jpg)
Do You Recognize This Code?Class.forName("org.postgresql.Driver");try (final Connection conn = DriverManager.getConnection( "jdbc:postgresql://hostname:port/dbname", "username", "password")) { // Database Logic Here... }
![Page 8: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/8.jpg)
Why Creating DB-Apps is So Time Consuming• Even trivial database operations require a lot of
boilerplate code • Mixing SQL and Java is error-prone • ORMs require you to write annotated POJOs for
every table• Creating even a simple DB app can take hours
![Page 9: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/9.jpg)
Open-Source Project Speedment• Stream ORM Java toolkit and runtime • Generate domain-model from the
database • No need for complicated
configurations or setup• All operations are type-safe• Data is accessed using Java 8 Streams• Business friendly Apache 2-license
![Page 10: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/10.jpg)
Speedment on GitHub
![Page 11: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/11.jpg)
Speedment Workflow
customers.stream() .filter(…) .filter(…) .map(…) .collect(toList());
Step 1: Generate Code
Step 2: Write Logic Step 3: Run Application
Step 4: Iterate
![Page 12: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/12.jpg)
Tool
![Page 13: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/13.jpg)
Artifacts• com.speedment:
• runtime• generator• tool• speedment-maven-plugin
![Page 14: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/14.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 15: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/15.jpg)
So How Do the Generated Code Work?• Code is organized based on database structure• Hash-sums make sure user changes are not overwritten
If the DB structure changes, the code is
updated with the press of a button
![Page 16: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/16.jpg)
Entities, Managers and Applications• An Entity represents a row in a table
• Is a POJO• Customer• CustomerImpl
• A Manager represents a table• Responsible for the CRUD operations• CustomerManager• CustomerManagerImpl
• An Application represents the entire project• Responsible for configuration and settings• SalesApplication • SalesApplicationBuilder
![Page 17: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/17.jpg)
Querying the Database using Streams• Queries are expressed using the
standard Java 8 Stream API• Streams are analyzed to
produce high-performance queries
![Page 18: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/18.jpg)
Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count();
Standard Stream API Generated Enum Constants
Only 1 value is loaded from DB
Full Type-Safety
SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’;
![Page 19: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/19.jpg)
Querying the Database using Streams
SELECT * FROM 'customer'
REGION.equal(NORTH_AMERICA)
REGISTERED.greaterOrEqual(2016-01-01)
count()
Source
Filter
Filter
Term.
Pipeline
![Page 20: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/20.jpg)
Querying the Database using Streams
SELECT * FROM 'customer'WHERE 'customer'.'region' = ‘North America’
REGION.equal(NORTH_AMERICA)
REGISTERED.greaterOrEqual(2016-01-01)
count()
Source
Filter
Filter
Term.
Pipeline
![Page 21: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/21.jpg)
Querying the Database using Streams
SELECT * FROM 'customer'WHERE 'customer'.'region' = ‘North America’
AND 'customer'.'registered' >= ‘2016-01-01’;
REGISTERED.greaterOrEqual(2016-01-01)
count()
Source
Filter
Term.
Pipeline
![Page 22: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/22.jpg)
Querying the Database using Streams
SELECT COUNT('id') FROM 'customer'WHERE 'customer'.'region' = ‘North America’
AND 'customer'.'registered' >= ‘2016-01-01’;
count()
Source
Term.
Pipeline
![Page 23: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/23.jpg)
Querying the Database using Streams
SELECT COUNT('id') FROM 'customer'WHERE 'customer'.'region' = ‘North America’
AND 'customer'.'registered' >= ‘2016-01-01’;Source
Pipeline
![Page 24: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/24.jpg)
Expressing Queries as Streams// Gets the second page of customers in North America// sorted by name in the form of a JSON array
customers.stream() .filter(REGION.equal(Region.NORTH_AMERICA)) .sorted(NAME.comparator()) .skip(10) .limit(10) // JVM from here… .collect(toJson(encode.allOf(customers)))
[ {”id”:11, ”name”: …}, {…}, …]
![Page 25: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/25.jpg)
Expressing Queries as Streams// Supports parallelism on custom executors// with full control of thread work item layout
customers.stream() .parallel() .filter(REGION.equal(Region.NORTH_AMERICA)) .forEach(expensiveOperatation());
![Page 26: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/26.jpg)
Application Example• Total Count of Customers
• Located in North America• Registered This Year
![Page 27: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/27.jpg)
Step 1: Getting Speedment using Maven
<plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.3</version></plugin>
Generate source files based on database
![Page 28: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/28.jpg)
Step 2: Initializing Speedment
SalesApplication app = new SalesApplicationBuilder() .withPassword("qwerty") .build();
CustomerManager customers = app.getOrThrow(CustomerManager.class);
These classes are generated automaticallyInstance is configured using Builder-pattern
A manager class is generated for every database table
![Page 29: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/29.jpg)
Step 3: Querying Region fromWhere = Region.NORTH_AMERICA; Instant fromWhen = Instant.parse("2016-01-01");
long count = customers.stream() .filter(Customer.REGION.equal(fromWhere)) .filter(Customer.REGISTERED.greaterOrEqual(fromWhen)) .count();
![Page 30: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/30.jpg)
Step 4: Output System.out.println( "A total of %d customers from %s " + "have registered this year.", count, fromWhere.name() );
![Page 31: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/31.jpg)
Full Application public static void main(String… args) { SalesApplication app = new SalesApplicationBuilder() .withPassword("qwerty") .build();
CustomerManager customers = app.getOrThrow(CustomerManager.class);
Region fromWhere = Region.NORTH_AMERICA; Instant fromWhen = Instant.parse("2016-01-01");
long count = customers.stream() .filter(Customer.REGION.equal(fromWhere)) .filter(Customer.REGISTERED.greaterOrEqual(fromWhen)) .count();
System.out.println( "A total of %d customers from %s " + "have registered this year.", count, fromWhere.name() ); }
![Page 32: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/32.jpg)
OutputPers-MacBook-Pro:~ pemi$ java –jar salesapplication.jar
A total of 354 customers from NORTH_AMERICA have registered this year.
![Page 33: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/33.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 34: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/34.jpg)
Controlling the Code Generation• So far we have queried a database
with streams• We have used code generation to
create entities and managers• Can it be used for more?
![Page 35: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/35.jpg)
What is Available out of the Box?• MVC oriented code generation• Modular design• Database domain model• JSON configuration (DSL)• Java language namer• Translator and TranslatorDecorator• Maven goals• Type mappers
![Page 36: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/36.jpg)
MVC Oriented Code Generation• Model
• File, Class, Interface, Enum, Field, Method, Constructor,Type, Generic, Annotation, …
• View• Renders a model to Java (or another language)• Set code style using custom views
• Control• AutoImport, AutoEquals, AutoJavadoc, SetGetAdd, FinalParameters• Write custom controllers to automate recurring tasks
![Page 37: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/37.jpg)
MVC Oriented Code Generation• Separation of concerns• Code generation is type safe
• Catch errors compile time• Discover methods directly in the IDE
• Reuse code segments and controllers
![Page 38: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/38.jpg)
Modular Design
![Page 39: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/39.jpg)
Database Domain Model• Project• Dbms• Schema• Table
• Column• PrimaryKey• ForeignKey• Index
List<Table> tables = project.dbmses() .flatMap(Dbms::schemas) .flatMap(Schema::tables) .collect(toList());
![Page 40: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/40.jpg)
JSON Configuration (DSL){ "config" : { "name" : "sales",
"dbmses" : [{ "name" : "db0", "typeName" : "MySQL", "ipAddress" : "127.0.0.1", "username" : "root",
"schemas" : [{ "name" : "sales", "tables" : [ { "name" : "city" }, { "name" : "salesperson" } ] }] }] }}
![Page 41: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/41.jpg)
Java Language Namer• Camel caser: converts from “some_db_name” to “someDbName”• Java naming conventions: user, User and USER• Detects keywords like “final”,”static” and escapes them• Detects collisions• Pluralizer: bag → bags, entity → entities, fish → fish
![Page 42: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/42.jpg)
Translator and TranslatorDecorator• Translator
• Renders a DB entity like a Table to a new Class or an Interface
• TranslatorDecorator• Modifies an existing Class or Interface
![Page 43: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/43.jpg)
Maven Goals• speedment:tool
• Launches the graphical tool• Allows customization of configuration model• Code generation
• speedment:generate• Code generation without launching the tool
• speedment:reload• Reloads database metadata without launching the tool
• speedment:clear• Removes all the generated classes (except manual changes) without launching the tool
![Page 44: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/44.jpg)
Type Mappers• Controls how columns are implemented• Runtime conversion between Database and Java types
java.sql.Timestamp long
![Page 45: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/45.jpg)
Generation vs. Templates• Separation of concerns• Easily change code style• Minimize maintenance• Maximize reusability
![Page 46: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/46.jpg)
Generate a New Custom Class
1. Create a new Translator2. Model how the new class should
look3. Define a Plugin Class4. Include it in project pom.xml
Example: Generate a Point class
![Page 47: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/47.jpg)
Step 1: Create a New Translator Classpublic class PointTranslator extends AbstractJavaClassTranslator<Project, Class> {
public final static TranslatorKey<Project, Class> POINT_KEY = new TranslatorKey.of(“generated_point", Class.class); public PointTranslator(Project document) { super(document, Class::of); }
@Override protected Class makeCodeGenModel(File file) { return newBuilder(file, getClassOrInterfaceName()) .forEveryProject((clazz, project) -> { // Generate Content Here }).build(); }
@Override protected String getClassOrInterfaceName() { return ”Point"; } @Override protected String getJavadocRepresentText() { return "A 2-dimensional coordinate."; }
}
Every translator is identified by a TranslatorKey
Name of generated class
Javadoc
Called every time the translator is invokedforEvery(Project|Dbms|Schema|Table|Column|…)
![Page 48: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/48.jpg)
Step 2: The makeCodeGenModel - methodclazz.public_() .add(Field.of(“x”, int.class) .private_().final_() ) .add(Field.of(“y”, int.class) .private_().final_() ) .add(Constructor.of().public_() .add(Field.of(“x”, int.class)) .add(Field.of(“y”, int.class)) .add(“this.x = x;”, “this.y = y;” ) ) .add(Method.of(“getX”, int.class).public_() .add(“return x;”) ) .add(Method.of(“getY”, int.class).public_() .add(“return y;”) ) .call(new AutoEquals<>()) .call(new AutoToString<>());
![Page 49: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/49.jpg)
Step 3: Define a Plugin Class
public class PointPlugin {
@ExecuteBefore(RESOLVED) void install(CodeGenerationComponent codeGen) { codeGen.put( Project.class, PointTranslator.POINT_KEY, PointTranslator::new ); }}
The key defined earlier
Will execute when Speedment is being initialized
How the translator is constructed
![Page 50: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/50.jpg)
Step 4: Include it in Project pom.xml<plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.3</version>
<dependencies> <dependency> <groupId>com.example</groupId> <artifactId>point-plugin</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies>
<configuration> <components> <component>com.example.pointplugin.PointPlugin</component> </components> </configuration></plugin> This tells Speedment to load the plugin
Make sure our plugin project is on the classpath
![Page 51: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/51.jpg)
Execute
/** * A 2-dimensional coordinate. * <p> * This file is safe to edit. It will not be overwritten by the code generator. * * @author company */public class Point { private final int x; private final int y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
The following file is generated: public int hashCode() { int hashCode = 31; hashCode += 41 * x; hashCode += 41 * y; return hashCode; }
public Boolean equals(Object other) { if (this == other) return true; else if (other == null) return false; else if (!(other instanceof Point)) { return false; }
final Point point = (Point) other; return x == point.x && y == point.y; }
public String toString() { return new StringBuilder(“Point{”) .append(“x: “).append(x).append(“, “) .append(“y: “).append(y).append(“}”); }}
![Page 52: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/52.jpg)
A More Concrete Example
1. Create a new Translator2. Model how the new class
should look3. Define a Plugin Class4. Include it in project pom.xml
Example: Generate an Enum of tables in the database
![Page 53: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/53.jpg)
Step 1: Create a New Translator Classpublic class TableEnumTranslator extends AbstractJavaClassTranslator<Project, Enum> {
public final static TranslatorKey<Project, Enum> TABLES_ENUM_KEY = new TranslatorKey.of(“tables_enum", Enum.class); public TableEnumTranslator(Project document) { super(document, Enum::of); }
@Override protected Enum makeCodeGenModel(File file) { return newBuilder(file, getClassOrInterfaceName()) .forEveryProject((clazz, project) -> { // Generate Content Here }).build(); }
@Override protected String getClassOrInterfaceName() { return ”Tables"; } @Override protected String getJavadocRepresentText() { return "An enumeration of tables in the database."; }
}
Every translator is identified by a TranslatorKey
Name of generated class
Javadoc
Called every time the translator is invokedforEvery(Project|Dbms|Schema|Table|Column|…)
![Page 54: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/54.jpg)
Step 2: The makeCodeGenModel - methodDocumentDbUtil.traverseOver(project, Table.class) .map(Table::getJavaName) .map(getSupport().namer()::javaStaticFieldName) .sorted() .map(EnumConstant::of) .forEachOrdered(clazz::add);
![Page 55: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/55.jpg)
Step 3: Define a Plugin Class
public class TableEnumPlugin {
@ExecuteBefore(RESOLVED) protected void install(CodeGenerationComponent codeGen) { codeGen.put( Project.class, TableEnumTranslator.TABLES_ENUM_KEY, TableEnumTranslator::new ); }}
![Page 56: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/56.jpg)
Step 4: Include it in Project pom.xml<plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.3</version>
<dependencies> <dependency> <groupId>com.example</groupId> <artifactId>table-enum-plugin</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies>
<configuration> <components> <component>com.example.tableenumplugin.TableEnumPlugin</component> </components> </configuration></plugin> This tells Speedment to load the plugin
Make sure our plugin project is on the classpath
![Page 57: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/57.jpg)
Execute
/** * An enumeration of tables in the database. * <p> * This file is safe to edit. It will not be overwritten by the code generator. * * @author company */enum Tables { CITY, SALESPERSON;}
The following file is generated:
![Page 58: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/58.jpg)
Generate all the Things• Gson Adapters• Spring Configuration Files• REST Controllers• and much more…
![Page 59: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/59.jpg)
Ext Speeder
![Page 60: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/60.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 61: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/61.jpg)
Add New Method to Existing Classes• So far we have
• Queried a database with generated classes
• Generated a custom class
• How do we modify the existing generation of classes?
![Page 62: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/62.jpg)
Add New Method to Existing Classes• Fit Into Existing Class Hierarchy• Change Naming Conventions• Optimize Internal Implementations• Add Custom Methods
![Page 63: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/63.jpg)
Add New Method to Existing ClassesExample: Add a getColumnCount method to generated managers
1. Create a new TranslatorDecorator class
2. Write code generation logic3. Add it to Speedment
![Page 64: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/64.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 65: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/65.jpg)
Step 1: Creating a New Decorator Class
public class ColumnCountDecorator implements TranslatorDecorator<Table, Interface> {
@Override public void apply(JavaClassTranslator<Table, Interface> translator) { translator.onMake(builder -> { builder.forEveryTable((intrf, table) -> { // Code generation logic goes here }); }); }}
![Page 66: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/66.jpg)
Step 2: Write Code Generation Logic
int columnCount = table.columns().count();
intrf.add(Method.of("getColumnCount", int.class) .default_() .set(Javadoc.of("Returns the number of columns in this table.") .add(RETURN.setValue("the column count")) ) .add("return " + columnCount + ";"));
![Page 67: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/67.jpg)
Step 3: Add it to Speedmentpublic final class TableEnumPlugin { @ExecuteBefore(RESOLVED) protected void install(CodeGenerationComponent codeGen) { codeGen.put( Project.class, TableEnumTranslator.TABLES_ENUM_KEY, TableEnumTranslator::new ); codeGen.add( Table.class, StandardTranslatorKey.GENERATED_MANAGER, new ColumnCountDecorator() ); }}
Modify an existing translator key
Our new decorator
The same plugin class as we created earlier
![Page 68: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/68.jpg)
ExecuteWhen the project is regenerated, a new method is added to each manager
![Page 69: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/69.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 70: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/70.jpg)
Additional Features• Add GUI Tool components for
custom configuration• Extend the JSON DSL
dynamically with plugins• Automate your build
environment with Maven• Add custom data type mappers
![Page 71: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/71.jpg)
Additional Features• Plugin a custom namer• Generate classes that are related to other domain models• Generate classes for other languages• Style the GUI Tool
![Page 72: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/72.jpg)
Database Connectors
Open Source• MySQL• PostgreSQL• MariaDB
Enterprise• Oracle• Microsoft SQL server• DB2• AS400
![Page 73: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/73.jpg)
Agenda• Problem Description• Code Generation in Database Applications
• How Does it Work?• Code Example
• Controlling the Code Generation• Generate Custom Classes• Add new Method to Existing Classes• Code Example
• Additional Features• Beyond Open Source• Questions & Answers
![Page 74: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/74.jpg)
Beyond Open-Source• Speedment Enterprise• Run your database queries orders of magnitude faster!
• 10x, 100x, 1 000x, 10 000x, …
• Use the same Stream API
![Page 75: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/75.jpg)
How is This Possible?• No changes to user-written code• Alternative stream source• Data is stored in-memory• Generates optimized serializers
for offheap storage
![Page 76: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/76.jpg)
In-JVM-Memory, JMH Benchmarks(*)Benchmark Mode Cnt Score Error UnitsSpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/opSpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op
SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/opSpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op
SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/opSpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op
SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/opSpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op
SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/opSpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op
(*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns.
10x
>10x
100x
2,000,000x
500,000,000x
![Page 77: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/77.jpg)
Speedment Enterprise Example
Courtesy of Extremely Heavy Industries
![Page 78: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/78.jpg)
Free Enterprise TrialToday we have released version 1.1.1
Get a free trial! Leave your contact information.
![Page 79: How to generate customized java 8 code from your database](https://reader035.vdocument.in/reader035/viewer/2022062306/58e4a2881a28abf5428b65f7/html5/thumbnails/79.jpg)
Q&Awww.speedment.org
github.com/speedment/speedment
@speedment
www.speedment.com
Linkedin: Per MinborgEmil Forslund