SlideShare a Scribd company logo
Tutorial: How to Generate Customized Java 8
Code from Your Database
Per Minborg
CTO, Speedment, Inc
Emil Forslund
Developer, Speedment, Inc.
Every Decision a Developer Makes is a
Trade-off
The best code is
no code at all
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?
About Us
Per 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
• 1.5 years of mascot experience
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
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...
}
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
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
Speedment Workflow
customers.stream()
.filter(…)
.filter(…)
.map(…)
.collect(toList());
Step 1: Generate
Code
Step 2: Write Logic Step 3: Run
Application
Step 4: Iterate
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
Tool
Artifacts
• com.speedment:
• runtime
• generator
• tool
• speedment-maven-plugin
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
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
Querying the Database using Streams
• Queries are expressed
using Java 8 streams
• Streams are analyzed to
produce high-performance
queries
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’;
Querying the Database using Streams
SELECT * FROM 'customer'
REGION.equal(NORTH_AMERICA)
REGISTERED.greaterOrEqual(2016-01-01)
count()
Sourc
e
Filter
Filter
Term.
Pipeline
Querying the Database using Streams
SELECT * FROM 'customer'
WHERE 'customer'.'region' = ‘North America’
REGION.equal(NORTH_AMERICA)
REGISTERED.greaterOrEqual(2016-01-01)
count()
Sourc
e
Filter
Filter
Term.
Pipeline
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()
Sourc
e
Filter
Term.
Pipeline
Querying the Database using Streams
SELECT COUNT('id') FROM 'customer'
WHERE 'customer'.'region' = ‘North America’
AND 'customer'.'registered' >= ‘2016-01-01’;
count()
Sourc
e
Term.
Pipeline
Querying the Database using Streams
SELECT COUNT('id') FROM 'customer'
WHERE 'customer'.'region' = ‘North America’
AND 'customer'.'registered' >= ‘2016-01-01’;
Sourc
e
Pipeline
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…
.map(JsonEncoder.allOf(customers)::apply)
.collect(joining(“, ”))
+”]”;
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());
Application Example
• Total Count of Customers
• Located in North America
• Registered This Year
Step 1: Getting Speedment using Maven
<plugin>
<groupId>com.speedment</groupId>
<artifactId>speedment-maven-plugin</artifactId>
<version>3.0.0-EA</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</plugin>
Generate source files based on database
The JDBC connector to use
Step 2: Initializing Speedment
SalesApplication app = new SalesApplicationBuilder()
.withPassword("qwerty")
.build();
CustomerManager customers = app.getOrThrow(CustomerManager.class);
These classes are generated
automatically
Instance is configured using Builder-
pattern
A manager class is generated for every database table
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();
Step 4: Output
System.out.println(
"A total of %d customers from %s " +
"have registered this year.",
count, fromWhere.name()
);
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()
);
}
Output
Pers-MacBook-Pro:~ pemi$ java –jar salesapplication.jar
A total of 354 customers from NORTH_AMERICA have registered this year.
Live Demo: Speedment
• Generate Domain Model
• Write Java Stream that:
• Determine the ID of a certain city
• Alphabetical list of last names of
salespersons in that city
• Execute
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
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?
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
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
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
Modular Design
Database Domain Model
• Project
• Dbms
• Schema
• Table
• Column
• PrimaryKey
• ForeignKey
• Index
List<Table> tables = project.dbmses()
.flatMap(Dbms::schemas)
.flatMap(Schema::tables)
.collect(toList());
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" }
]
}]
}]
}
}
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
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
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
Type Mappers
• Controls how columns are implemented
• Runtime conversion between Database and Java types
java.sql.Timestamp long
Generation vs. Templates
• Separation of concerns
• Easily change code style
• Minimize maintenance
• Maximize reusability
Generate a New Custom Class
1. Create a new Translator
2. Model how the new class
should look
3. Define a Plugin Class
4. Include it in project pom.xml
Example: Generate a Point class
Step 1: Create a New Translator Class
public 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 invoked
forEvery(Project|Dbms|Schema|Table|Column|
…)
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<>());
Step 3: Define a Plugin Class
public class PointPlugin {
@ExecuteBefore(RESOLVED)
protected 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
Step 4: Include it in Project pom.xml
<plugin>
<groupId>com.speedment</groupId>
<artifactId>speedment-maven-plugin</artifactId>
<version>3.0.0-EA</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<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
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(“}”);
}
}
A More Concrete Example
1. Create a new Translator
2. Model how the new class
should look
3. Define a Plugin Class
4. Include it in project pom.xml
Example: Generate an Enum of
tables in the database
Step 1: Create a New Translator Class
public 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 invoked
forEvery(Project|Dbms|Schema|Table|Column|
…)
Step 2: The makeCodeGenModel -
method
DocumentDbUtil.traverseOver(project, Table.class)
.map(Table::getJavaName)
.map(getSupport().namer()::javaStaticFieldName)
.sorted()
.map(EnumConstant::of)
.forEachOrdered(clazz::add);
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
);
}
}
Step 4: Include it in Project pom.xml
<plugin>
<groupId>com.speedment</groupId>
<artifactId>speedment-maven-plugin</artifactId>
<version>3.0.0-EA</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<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
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:
Generate all the Things
• Gson Adapters
• Spring Configuration Files
• REST Controllers
• and much more…
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
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?
Add New Method to Existing Classes
• Fit Into Existing Class Hierarchy
• Change Naming Conventions
• Optimize Internal Implementations
• Add Custom Methods
Add New Method to Existing Classes
Example: Add a getColumnCount
method to generated managers
1. Create a new
TranslatorDecorator class
2. Write code generation logic
3. Add it to Speedment
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
});
});
}
}
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 + ";")
);
Step 3: Add it to Speedment
public 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
Execute
When the project is
regenerated, a new method is
added to each manager
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
Demo: Advanced Plugin
• Use the Speedment Spring
Plugin to generate a working
REST API
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
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
Additional Features
• Plugin a custom namer
• Generate classes that are related to other domain models
• Generate classes for other languages
• Style the GUI Tool
Database Connectors
Open Source
• MySQL
• PostgreSQL
• MariaDB
Enterprise
• Oracle
• Microsoft SQL server
• dB2
Agenda
• Problem Description
• Code Generation in Database Applications
• How Does it Work?
• Hands on Demo
• Controlling the Code Generation
• Generate Custom Classes
• Add new Method to Existing Classes
• Hands on Demo
• Additional Features
• Real World Examples
• Questions & Answers
In-JVM-Memory Data Store
• Alternative stream source
• Uses code generation
• Optimized serializers for
offheap storage
• No changes to user-written
code
• 10-100x faster queries
Ext Speeder
In-JVM-Memory !
Q&A
www.speedment.org
github.com/speedment
@speedment
www.speedment.com
Linkedin:
Per Minborg
Emil Forslund

More Related Content

What's hot (20)

PDF
[2015/2016] Require JS and Handlebars JS
Ivano Malavolta
 
PDF
Getting Started with the OpenNTF Domino API
Teamstudio
 
PDF
Connect 2014 JMP101: Java for XPages Development
panagenda
 
PPTX
2/15/2012 - Wrapping Your Head Around the SharePoint Beast
Mark Rackley
 
PDF
Spring Framework 4.0 to 4.1
Sam Brannen
 
PDF
Building search app with ElasticSearch
Lukas Vlcek
 
PDF
JMP401: Masterclass: XPages Scalability
Tony McGuckin
 
PPTX
Basic Selenium Training
Dipesh Bhatewara
 
PPTX
SPTechCon - Share point and jquery essentials
Mark Rackley
 
PDF
[2015/2016] Backbone JS
Ivano Malavolta
 
PPTX
Batching and Java EE (jdk.io)
Ryan Cuprak
 
PDF
Spring framework
Aircon Chen
 
PDF
How to grow your own Microservice?
Dmitry Buzdin
 
PPTX
Advance java Online Training in Hyderabad
Ugs8008
 
PPT
MVC Demystified: Essence of Ruby on Rails
codeinmotion
 
PDF
HTML5: the new frontier of the web
Ivano Malavolta
 
PDF
Tips for Building your First XPages Java Application
Teamstudio
 
PPTX
Advance Java Topics (J2EE)
slire
 
PPT
XPages Workshop: Concepts And Exercises
ddrschiw
 
PPT
01 java intro
Deepal Shah
 
[2015/2016] Require JS and Handlebars JS
Ivano Malavolta
 
Getting Started with the OpenNTF Domino API
Teamstudio
 
Connect 2014 JMP101: Java for XPages Development
panagenda
 
2/15/2012 - Wrapping Your Head Around the SharePoint Beast
Mark Rackley
 
Spring Framework 4.0 to 4.1
Sam Brannen
 
Building search app with ElasticSearch
Lukas Vlcek
 
JMP401: Masterclass: XPages Scalability
Tony McGuckin
 
Basic Selenium Training
Dipesh Bhatewara
 
SPTechCon - Share point and jquery essentials
Mark Rackley
 
[2015/2016] Backbone JS
Ivano Malavolta
 
Batching and Java EE (jdk.io)
Ryan Cuprak
 
Spring framework
Aircon Chen
 
How to grow your own Microservice?
Dmitry Buzdin
 
Advance java Online Training in Hyderabad
Ugs8008
 
MVC Demystified: Essence of Ruby on Rails
codeinmotion
 
HTML5: the new frontier of the web
Ivano Malavolta
 
Tips for Building your First XPages Java Application
Teamstudio
 
Advance Java Topics (J2EE)
slire
 
XPages Workshop: Concepts And Exercises
ddrschiw
 
01 java intro
Deepal Shah
 

Similar to How to JavaOne 2016 - Generate Customized Java 8 Code from Your Database [TUT4489] (20)

PPTX
How to generate customized java 8 code from your database
Speedment, Inc.
 
PDF
Play Framework and Activator
Kevin Webber
 
PPTX
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
PPTX
SenchaCon 2016 - How to Auto Generate a Back-end in Minutes
Speedment, Inc.
 
PPTX
SenchaCon 2016 - How to Auto Generate a Back-end in Minutes
Malin Weiss
 
PPTX
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
Sencha
 
PDF
Web Development using Ruby on Rails
Avi Kedar
 
PPTX
05 entity framework
Bat Programmer
 
PDF
JDD2015: Java Everywhere Again—with DukeScript - Jaroslav Tulach
PROIDEA
 
PDF
Masterin Large Scale Java Script Applications
Fabian Jakobs
 
PDF
How to Contribute to Apache Usergrid
David M. Johnson
 
PDF
Quick start with AngularJS
Iuliia Baranova
 
PPTX
Java script nirvana in netbeans [con5679]
Ryan Cuprak
 
PPTX
Bringing DevOps to the Database
Michaela Murray
 
PDF
Escaping the yellow bubble - rewriting Domino using MongoDb and Angular
Mark Leusink
 
PPTX
concept of server-side JavaScript / JS Framework: NODEJS
Kongu Engineering College, Perundurai, Erode
 
PDF
MEAN Stack Warm-up
Troy Miles
 
PPTX
Internship softwaretraining@ijse
Jinadi Rashmika
 
PPTX
SharePoint 2013 Performance Analysis - Robi Vončina
SPC Adriatics
 
PPTX
AngularJS 1.x - your first application (problems and solutions)
Igor Talevski
 
How to generate customized java 8 code from your database
Speedment, Inc.
 
Play Framework and Activator
Kevin Webber
 
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
SenchaCon 2016 - How to Auto Generate a Back-end in Minutes
Speedment, Inc.
 
SenchaCon 2016 - How to Auto Generate a Back-end in Minutes
Malin Weiss
 
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
Sencha
 
Web Development using Ruby on Rails
Avi Kedar
 
05 entity framework
Bat Programmer
 
JDD2015: Java Everywhere Again—with DukeScript - Jaroslav Tulach
PROIDEA
 
Masterin Large Scale Java Script Applications
Fabian Jakobs
 
How to Contribute to Apache Usergrid
David M. Johnson
 
Quick start with AngularJS
Iuliia Baranova
 
Java script nirvana in netbeans [con5679]
Ryan Cuprak
 
Bringing DevOps to the Database
Michaela Murray
 
Escaping the yellow bubble - rewriting Domino using MongoDb and Angular
Mark Leusink
 
concept of server-side JavaScript / JS Framework: NODEJS
Kongu Engineering College, Perundurai, Erode
 
MEAN Stack Warm-up
Troy Miles
 
Internship softwaretraining@ijse
Jinadi Rashmika
 
SharePoint 2013 Performance Analysis - Robi Vončina
SPC Adriatics
 
AngularJS 1.x - your first application (problems and solutions)
Igor Talevski
 
Ad

Recently uploaded (20)

PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Ad

How to JavaOne 2016 - Generate Customized Java 8 Code from Your Database [TUT4489]

  • 1. Tutorial: How to Generate Customized Java 8 Code from Your Database Per Minborg CTO, Speedment, Inc Emil Forslund Developer, Speedment, Inc.
  • 2. Every Decision a Developer Makes is a Trade-off The best code is no code at all
  • 3. 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?
  • 4. About Us Per 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 • 1.5 years of mascot experience
  • 5. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 6. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 7. 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... }
  • 8. 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
  • 9. 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
  • 10. Speedment Workflow customers.stream() .filter(…) .filter(…) .map(…) .collect(toList()); Step 1: Generate Code Step 2: Write Logic Step 3: Run Application Step 4: Iterate
  • 11. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 12. Tool
  • 13. Artifacts • com.speedment: • runtime • generator • tool • speedment-maven-plugin
  • 14. 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
  • 15. 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
  • 16. Querying the Database using Streams • Queries are expressed using Java 8 streams • Streams are analyzed to produce high-performance queries
  • 17. 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’;
  • 18. Querying the Database using Streams SELECT * FROM 'customer' REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Sourc e Filter Filter Term. Pipeline
  • 19. Querying the Database using Streams SELECT * FROM 'customer' WHERE 'customer'.'region' = ‘North America’ REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Sourc e Filter Filter Term. Pipeline
  • 20. 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() Sourc e Filter Term. Pipeline
  • 21. Querying the Database using Streams SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; count() Sourc e Term. Pipeline
  • 22. Querying the Database using Streams SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; Sourc e Pipeline
  • 23. 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… .map(JsonEncoder.allOf(customers)::apply) .collect(joining(“, ”)) +”]”;
  • 24. 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());
  • 25. Application Example • Total Count of Customers • Located in North America • Registered This Year
  • 26. Step 1: Getting Speedment using Maven <plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.0-EA</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> </dependencies> </plugin> Generate source files based on database The JDBC connector to use
  • 27. Step 2: Initializing Speedment SalesApplication app = new SalesApplicationBuilder() .withPassword("qwerty") .build(); CustomerManager customers = app.getOrThrow(CustomerManager.class); These classes are generated automatically Instance is configured using Builder- pattern A manager class is generated for every database table
  • 28. 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();
  • 29. Step 4: Output System.out.println( "A total of %d customers from %s " + "have registered this year.", count, fromWhere.name() );
  • 30. 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() ); }
  • 31. Output Pers-MacBook-Pro:~ pemi$ java –jar salesapplication.jar A total of 354 customers from NORTH_AMERICA have registered this year.
  • 32. Live Demo: Speedment • Generate Domain Model • Write Java Stream that: • Determine the ID of a certain city • Alphabetical list of last names of salespersons in that city • Execute
  • 33. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 34. 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?
  • 35. 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
  • 36. 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
  • 37. 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
  • 39. Database Domain Model • Project • Dbms • Schema • Table • Column • PrimaryKey • ForeignKey • Index List<Table> tables = project.dbmses() .flatMap(Dbms::schemas) .flatMap(Schema::tables) .collect(toList());
  • 40. 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" } ] }] }] } }
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. Type Mappers • Controls how columns are implemented • Runtime conversion between Database and Java types java.sql.Timestamp long
  • 45. Generation vs. Templates • Separation of concerns • Easily change code style • Minimize maintenance • Maximize reusability
  • 46. Generate a New Custom Class 1. Create a new Translator 2. Model how the new class should look 3. Define a Plugin Class 4. Include it in project pom.xml Example: Generate a Point class
  • 47. Step 1: Create a New Translator Class public 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 invoked forEvery(Project|Dbms|Schema|Table|Column| …)
  • 48. 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<>());
  • 49. Step 3: Define a Plugin Class public class PointPlugin { @ExecuteBefore(RESOLVED) protected 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
  • 50. Step 4: Include it in Project pom.xml <plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.0-EA</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <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
  • 51. 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(“}”); } }
  • 52. A More Concrete Example 1. Create a new Translator 2. Model how the new class should look 3. Define a Plugin Class 4. Include it in project pom.xml Example: Generate an Enum of tables in the database
  • 53. Step 1: Create a New Translator Class public 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 invoked forEvery(Project|Dbms|Schema|Table|Column| …)
  • 54. Step 2: The makeCodeGenModel - method DocumentDbUtil.traverseOver(project, Table.class) .map(Table::getJavaName) .map(getSupport().namer()::javaStaticFieldName) .sorted() .map(EnumConstant::of) .forEachOrdered(clazz::add);
  • 55. 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 ); } }
  • 56. Step 4: Include it in Project pom.xml <plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>3.0.0-EA</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <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
  • 57. 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:
  • 58. Generate all the Things • Gson Adapters • Spring Configuration Files • REST Controllers • and much more…
  • 59. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 60. 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?
  • 61. Add New Method to Existing Classes • Fit Into Existing Class Hierarchy • Change Naming Conventions • Optimize Internal Implementations • Add Custom Methods
  • 62. Add New Method to Existing Classes Example: Add a getColumnCount method to generated managers 1. Create a new TranslatorDecorator class 2. Write code generation logic 3. Add it to Speedment
  • 63. 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 }); }); } }
  • 64. 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 + ";") );
  • 65. Step 3: Add it to Speedment public 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
  • 66. Execute When the project is regenerated, a new method is added to each manager
  • 67. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 68. Demo: Advanced Plugin • Use the Speedment Spring Plugin to generate a working REST API
  • 69. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 70. 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
  • 71. Additional Features • Plugin a custom namer • Generate classes that are related to other domain models • Generate classes for other languages • Style the GUI Tool
  • 72. Database Connectors Open Source • MySQL • PostgreSQL • MariaDB Enterprise • Oracle • Microsoft SQL server • dB2
  • 73. Agenda • Problem Description • Code Generation in Database Applications • How Does it Work? • Hands on Demo • Controlling the Code Generation • Generate Custom Classes • Add new Method to Existing Classes • Hands on Demo • Additional Features • Real World Examples • Questions & Answers
  • 74. In-JVM-Memory Data Store • Alternative stream source • Uses code generation • Optimized serializers for offheap storage • No changes to user-written code • 10-100x faster queries

Editor's Notes

  • #6: What we are going to talk about today
  • #7: What we are going to talk about today
  • #8: Ice-breaker
  • #9: Negatives
  • #10: Positives
  • #11: Agile Workflow
  • #12: What we are going to talk about today
  • #13: Positives
  • #14: Positives
  • #15: Code Structure Let the database be the center of the iterative process
  • #16: What we are going to talk about today
  • #18: Pause before the fourth arrow ”Do you know what the coolest aspect of this paragraph is?”
  • #24: Positives
  • #25: Positives
  • #29: Output on next slide
  • #30: Output on next slide
  • #31: Output on next slide
  • #32: Next: Emil Live Demo #1
  • #34: What we are going to talk about today
  • #35: Stop here
  • #42: Mention problem before showing the solutions
  • #50: @ExecuteBefore says this class must be configured before use Dependency injection is used to get access to the code generation component
  • #56: @ExecuteBefore says this class must be configured before use Dependency injection is used to get access to the code generation component
  • #59: Now that you have seen all this, how do you think code generation can solve your challenges? Do you have ideas what you can generate?
  • #60: What we are going to talk about today
  • #61: Entities, Managers, Application
  • #62: Why add methods? You know your own domain model best!
  • #67: For every table! Like 100 tables!
  • #68: What we are going to talk about today
  • #69: Live Demo, then Q&A
  • #70: What we are going to talk about today
  • #71: Live Demo, then Q&A
  • #72: Live Demo, then Q&A
  • #74: What we are going to talk about today
  • #76: Live Demo, then Q&A