Browse Source

Add play2-java-jooq-hikaricp (#3062)

Matthias Kurz 7 years ago
parent
commit
9493d325cd
24 changed files with 1389 additions and 0 deletions
  1. 22 0
      frameworks/Java/play2-java/benchmark_config.json
  2. 29 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/.gitignore
  3. 23 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/README.md
  4. 121 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/controllers/Application.java
  5. 60 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/DefaultCatalog.java
  6. 79 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/HelloWorld.java
  7. 45 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Indexes.java
  8. 66 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Keys.java
  9. 35 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Tables.java
  10. 168 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/Fortune.java
  11. 168 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/World.java
  12. 190 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/records/FortuneRecord.java
  13. 190 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/records/WorldRecord.java
  14. 15 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/utils/DatabaseExecutionContext.java
  15. 16 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/views/fortunes.scala.html
  16. 12 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/views/main.scala.html
  17. 16 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/build.sbt
  18. 69 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/application.conf
  19. 28 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/logback.xml
  20. 8 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/routes
  21. 1 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/project/build.properties
  22. 1 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/project/plugins.sbt
  23. 17 0
      frameworks/Java/play2-java/play2-java-jooq-hikaricp/source_code
  24. 10 0
      frameworks/Java/play2-java/setup_java_jooq_hikaricp.sh

+ 22 - 0
frameworks/Java/play2-java/benchmark_config.json

@@ -65,6 +65,28 @@
         "query_url": "/queries?queries=", 
         "query_url": "/queries?queries=", 
         "fortune_url": "/fortunes", 
         "fortune_url": "/fortunes", 
         "update_url": "/update?queries="
         "update_url": "/update?queries="
+      },
+      "java-jooq-hikaricp": {
+        "display_name": "play2-java-jooq-hikaricp", 
+        "setup_file": "setup_java_jooq_hikaricp", 
+        "framework": "play2", 
+        "language": "Java", 
+        "flavor": "None",
+        "orm": "Full", 
+        "os": "Linux", 
+        "database": "MySQL", 
+        "approach": "Realistic", 
+        "classification": "Fullstack", 
+        "platform": "Akka", 
+        "webserver": "None", 
+        "database_os": "Linux", 
+        "notes": "", 
+        "versus": "akka-http", 
+        "port": "9000", 
+        "db_url": "/db", 
+        "query_url": "/queries?queries=", 
+        "fortune_url": "/fortunes", 
+        "update_url": "/update?queries="
       }
       }
     }
     }
   ]
   ]

+ 29 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/.gitignore

@@ -0,0 +1,29 @@
+logs
+project/project
+project/target
+target
+tmp
+.history
+dist
+
+# Ignore all dotfiles...
+.*
+# except for .gitignore
+!.gitignore
+
+# Ignore Play! working directory #
+db
+eclipse
+lib
+log
+logs
+modules
+precompiled
+project/project
+project/target
+target
+tmp
+test-result
+server.pid
+*.iml
+*.eml

+ 23 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/README.md

@@ -0,0 +1,23 @@
+# Play Benchmarking Test
+
+This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### Data-Store/Database Mapping Test
+
+* [Database test controller](app/controllers/Application.java)
+* [Database World test model](app/models/World.java)
+* [Database Fortune test model](app/models/Fortune.java)
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* Java 8
+* [Play 2.6.7](https://www.playframework.com/)
+
+## Test URLs
+### Data-Store/Database Mapping Test
+
+* http://localhost/db
+* http://localhost/queries?queries=10
+* http://localhost/fortunes
+* http://localhost/update?queries=10

+ 121 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/controllers/Application.java

@@ -0,0 +1,121 @@
+package controllers;
+
+import static models.tables.Fortune.FORTUNE;
+import static models.tables.World.WORLD;
+import static play.mvc.Http.MimeTypes.JSON;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+
+import org.jooq.DSLContext;
+import org.jooq.JSONFormat;
+import org.jooq.JSONFormat.RecordFormat;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
+import org.jooq.types.UInteger;
+
+import models.tables.records.FortuneRecord;
+import models.tables.records.WorldRecord;
+import play.db.Database;
+import play.mvc.Controller;
+import play.mvc.Result;
+import utils.DatabaseExecutionContext;
+
+public class Application extends Controller {
+
+    private static final SQLDialect DIALECT = SQLDialect.MYSQL_5_7;
+    private static final JSONFormat JSON_FORMAT = JSONFormat.DEFAULT_FOR_RECORDS.recordFormat(RecordFormat.OBJECT);
+
+    private final Database db;
+    private final DatabaseExecutionContext dbEc;
+
+    @Inject
+    public Application(final Database db, final DatabaseExecutionContext dbEc) {
+        this.db = db;
+        this.dbEc = dbEc;
+    }
+
+    public CompletionStage<Result> db() {
+        return getRandomWorlds(1).thenApply(worlds -> ok(worlds.get(0).formatJSON(JSON_FORMAT)).as(JSON));
+    }
+
+    public CompletionStage<Result> queries(final String queries) {
+        return getRandomWorlds(queryCount(queries)).thenApply(worlds -> ok(worlds.formatJSON(JSON_FORMAT)).as(JSON));
+    }
+
+    public CompletionStage<Result> fortunes() {
+        return CompletableFuture.supplyAsync(() -> {
+            final List<FortuneRecord> fortunes = this.db.withConnection(connection -> {
+                return DSL.using(connection, DIALECT).selectFrom(FORTUNE).fetch();
+            });
+            fortunes.add(new FortuneRecord(UInteger.valueOf(0), "Additional fortune added at request time."));
+            Collections.sort(fortunes, (f1, f2) -> f1.getMessage().compareTo(f2.getMessage()));
+
+            return ok(views.html.fortunes.render(fortunes));
+        }, dbEc);
+    }
+
+    public CompletionStage<Result> update(final String queries) {
+        return getRandomWorlds(queryCount(queries)).thenApplyAsync(worlds -> {
+            final Random random = ThreadLocalRandom.current();
+            for (final WorldRecord world : worlds) {
+                world.setRandomnumber((random.nextInt(10000) + 1));
+            }
+
+            final int batchSize = 25;
+            final int batches = ((worlds.size() / batchSize) + 1);
+            this.db.withConnection(connection -> {
+                final DSLContext sql = DSL.using(connection, DIALECT);
+                for ( int i = 0 ; i < batches ; ++i ) {
+                    sql.batchUpdate(worlds.subList(i * batchSize, Math.min((i + 1) * batchSize, worlds.size()))).execute();
+                }
+                return null;
+            });
+
+            return ok(worlds.formatJSON(JSON_FORMAT)).as(JSON);
+        }, dbEc);
+    }
+
+    private int queryCount(final String queryCountString) {
+        int queryCount;
+        try {
+            queryCount = Integer.parseInt(queryCountString, 10);
+        } catch (final NumberFormatException e) {
+            queryCount = 1;
+        }
+        if (queryCount < 1) {
+            queryCount = 1;
+        } else if (queryCount > 500) {
+            queryCount = 500;
+        }
+
+        return queryCount;
+    }
+
+    private CompletionStage<org.jooq.Result<WorldRecord>> getRandomWorlds(final int n) {
+        return CompletableFuture.supplyAsync(() -> {
+            final Random random = ThreadLocalRandom.current();
+            org.jooq.Result<WorldRecord> worlds = null;
+            for (int i = 0; i < n; ++i) {
+                long randomId = random.nextInt(10000) + 1;
+                final org.jooq.Result<WorldRecord> world = this.db.withConnection(connection -> {
+                    return DSL.using(connection, DIALECT).selectFrom(WORLD).where(WORLD.ID.eq(UInteger.valueOf(randomId))).fetch();
+                });
+
+                if(worlds == null) {
+                    worlds = world;
+                } else {
+                    worlds.add(world.get(0));
+                }
+            }
+            return worlds;
+        }, dbEc);
+    }
+
+}

+ 60 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/DefaultCatalog.java

@@ -0,0 +1,60 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Schema;
+import org.jooq.impl.CatalogImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class DefaultCatalog extends CatalogImpl {
+
+    private static final long serialVersionUID = 1833355075;
+
+    /**
+     * The reference instance of <code></code>
+     */
+    public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog();
+
+    /**
+     * The schema <code>hello_world</code>.
+     */
+    public final HelloWorld HELLO_WORLD = models.HelloWorld.HELLO_WORLD;
+
+    /**
+     * No further instances allowed
+     */
+    private DefaultCatalog() {
+        super("");
+    }
+
+    @Override
+    public final List<Schema> getSchemas() {
+        List result = new ArrayList();
+        result.addAll(getSchemas0());
+        return result;
+    }
+
+    private final List<Schema> getSchemas0() {
+        return Arrays.<Schema>asList(
+            HelloWorld.HELLO_WORLD);
+    }
+}

+ 79 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/HelloWorld.java

@@ -0,0 +1,79 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import models.tables.Fortune;
+import models.tables.World;
+
+import org.jooq.Catalog;
+import org.jooq.Table;
+import org.jooq.impl.SchemaImpl;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class HelloWorld extends SchemaImpl {
+
+    private static final long serialVersionUID = -1521404055;
+
+    /**
+     * The reference instance of <code>hello_world</code>
+     */
+    public static final HelloWorld HELLO_WORLD = new HelloWorld();
+
+    /**
+     * The table <code>hello_world.fortune</code>.
+     */
+    public final Fortune FORTUNE = models.tables.Fortune.FORTUNE;
+
+    /**
+     * The table <code>hello_world.world</code>.
+     */
+    public final World WORLD = models.tables.World.WORLD;
+
+    /**
+     * No further instances allowed
+     */
+    private HelloWorld() {
+        super("hello_world", null);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Catalog getCatalog() {
+        return DefaultCatalog.DEFAULT_CATALOG;
+    }
+
+    @Override
+    public final List<Table<?>> getTables() {
+        List result = new ArrayList();
+        result.addAll(getTables0());
+        return result;
+    }
+
+    private final List<Table<?>> getTables0() {
+        return Arrays.<Table<?>>asList(
+            Fortune.FORTUNE,
+            World.WORLD);
+    }
+}

+ 45 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Indexes.java

@@ -0,0 +1,45 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models;
+
+
+import javax.annotation.Generated;
+
+import models.tables.Fortune;
+import models.tables.World;
+
+import org.jooq.Index;
+import org.jooq.OrderField;
+import org.jooq.impl.AbstractKeys;
+
+
+/**
+ * A class modelling indexes of tables of the <code>hello_world</code> schema.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Indexes {
+
+    // -------------------------------------------------------------------------
+    // INDEX definitions
+    // -------------------------------------------------------------------------
+
+    public static final Index FORTUNE_PRIMARY = Indexes0.FORTUNE_PRIMARY;
+    public static final Index WORLD_PRIMARY = Indexes0.WORLD_PRIMARY;
+
+    // -------------------------------------------------------------------------
+    // [#1459] distribute members to avoid static initialisers > 64kb
+    // -------------------------------------------------------------------------
+
+    private static class Indexes0 extends AbstractKeys {
+        public static Index FORTUNE_PRIMARY = createIndex("PRIMARY", Fortune.FORTUNE, new OrderField[] { Fortune.FORTUNE.ID }, true);
+        public static Index WORLD_PRIMARY = createIndex("PRIMARY", World.WORLD, new OrderField[] { World.WORLD.ID }, true);
+    }
+}

+ 66 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Keys.java

@@ -0,0 +1,66 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models;
+
+
+import javax.annotation.Generated;
+
+import models.tables.Fortune;
+import models.tables.World;
+import models.tables.records.FortuneRecord;
+import models.tables.records.WorldRecord;
+
+import org.jooq.Identity;
+import org.jooq.UniqueKey;
+import org.jooq.impl.AbstractKeys;
+import org.jooq.types.UInteger;
+
+
+/**
+ * A class modelling foreign key relationships and constraints of tables of 
+ * the <code>hello_world</code> schema.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Keys {
+
+    // -------------------------------------------------------------------------
+    // IDENTITY definitions
+    // -------------------------------------------------------------------------
+
+    public static final Identity<FortuneRecord, UInteger> IDENTITY_FORTUNE = Identities0.IDENTITY_FORTUNE;
+    public static final Identity<WorldRecord, UInteger> IDENTITY_WORLD = Identities0.IDENTITY_WORLD;
+
+    // -------------------------------------------------------------------------
+    // UNIQUE and PRIMARY KEY definitions
+    // -------------------------------------------------------------------------
+
+    public static final UniqueKey<FortuneRecord> KEY_FORTUNE_PRIMARY = UniqueKeys0.KEY_FORTUNE_PRIMARY;
+    public static final UniqueKey<WorldRecord> KEY_WORLD_PRIMARY = UniqueKeys0.KEY_WORLD_PRIMARY;
+
+    // -------------------------------------------------------------------------
+    // FOREIGN KEY definitions
+    // -------------------------------------------------------------------------
+
+
+    // -------------------------------------------------------------------------
+    // [#1459] distribute members to avoid static initialisers > 64kb
+    // -------------------------------------------------------------------------
+
+    private static class Identities0 extends AbstractKeys {
+        public static Identity<FortuneRecord, UInteger> IDENTITY_FORTUNE = createIdentity(Fortune.FORTUNE, Fortune.FORTUNE.ID);
+        public static Identity<WorldRecord, UInteger> IDENTITY_WORLD = createIdentity(World.WORLD, World.WORLD.ID);
+    }
+
+    private static class UniqueKeys0 extends AbstractKeys {
+        public static final UniqueKey<FortuneRecord> KEY_FORTUNE_PRIMARY = createUniqueKey(Fortune.FORTUNE, "KEY_fortune_PRIMARY", Fortune.FORTUNE.ID);
+        public static final UniqueKey<WorldRecord> KEY_WORLD_PRIMARY = createUniqueKey(World.WORLD, "KEY_world_PRIMARY", World.WORLD.ID);
+    }
+}

+ 35 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/Tables.java

@@ -0,0 +1,35 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models;
+
+
+import javax.annotation.Generated;
+
+import models.tables.Fortune;
+import models.tables.World;
+
+
+/**
+ * Convenience access to all tables in hello_world
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Tables {
+
+    /**
+     * The table <code>hello_world.fortune</code>.
+     */
+    public static final Fortune FORTUNE = models.tables.Fortune.FORTUNE;
+
+    /**
+     * The table <code>hello_world.world</code>.
+     */
+    public static final World WORLD = models.tables.World.WORLD;
+}

+ 168 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/Fortune.java

@@ -0,0 +1,168 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import models.HelloWorld;
+import models.Indexes;
+import models.Keys;
+import models.tables.records.FortuneRecord;
+
+import org.jooq.Field;
+import org.jooq.Identity;
+import org.jooq.Index;
+import org.jooq.Name;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.TableImpl;
+import org.jooq.types.UInteger;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Fortune extends TableImpl<FortuneRecord> {
+
+    private static final long serialVersionUID = 943840722;
+
+    /**
+     * The reference instance of <code>hello_world.fortune</code>
+     */
+    public static final Fortune FORTUNE = new Fortune();
+
+    /**
+     * The class holding records for this type
+     */
+    @Override
+    public Class<FortuneRecord> getRecordType() {
+        return FortuneRecord.class;
+    }
+
+    /**
+     * The column <code>hello_world.fortune.id</code>.
+     */
+    public final TableField<FortuneRecord, UInteger> ID = createField("id", org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false).identity(true), this, "");
+
+    /**
+     * The column <code>hello_world.fortune.message</code>.
+     */
+    public final TableField<FortuneRecord, String> MESSAGE = createField("message", org.jooq.impl.SQLDataType.VARCHAR(2048).nullable(false), this, "");
+
+    /**
+     * Create a <code>hello_world.fortune</code> table reference
+     */
+    public Fortune() {
+        this(DSL.name("fortune"), null);
+    }
+
+    /**
+     * Create an aliased <code>hello_world.fortune</code> table reference
+     */
+    public Fortune(String alias) {
+        this(DSL.name(alias), FORTUNE);
+    }
+
+    /**
+     * Create an aliased <code>hello_world.fortune</code> table reference
+     */
+    public Fortune(Name alias) {
+        this(alias, FORTUNE);
+    }
+
+    private Fortune(Name alias, Table<FortuneRecord> aliased) {
+        this(alias, aliased, null);
+    }
+
+    private Fortune(Name alias, Table<FortuneRecord> aliased, Field<?>[] parameters) {
+        super(alias, null, aliased, parameters, "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Schema getSchema() {
+        return HelloWorld.HELLO_WORLD;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<Index> getIndexes() {
+        return Arrays.<Index>asList(Indexes.FORTUNE_PRIMARY);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Identity<FortuneRecord, UInteger> getIdentity() {
+        return Keys.IDENTITY_FORTUNE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UniqueKey<FortuneRecord> getPrimaryKey() {
+        return Keys.KEY_FORTUNE_PRIMARY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<UniqueKey<FortuneRecord>> getKeys() {
+        return Arrays.<UniqueKey<FortuneRecord>>asList(Keys.KEY_FORTUNE_PRIMARY);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Fortune as(String alias) {
+        return new Fortune(DSL.name(alias), this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Fortune as(Name alias) {
+        return new Fortune(alias, this);
+    }
+
+    /**
+     * Rename this table
+     */
+    @Override
+    public Fortune rename(String name) {
+        return new Fortune(DSL.name(name), null);
+    }
+
+    /**
+     * Rename this table
+     */
+    @Override
+    public Fortune rename(Name name) {
+        return new Fortune(name, null);
+    }
+}

+ 168 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/World.java

@@ -0,0 +1,168 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import models.HelloWorld;
+import models.Indexes;
+import models.Keys;
+import models.tables.records.WorldRecord;
+
+import org.jooq.Field;
+import org.jooq.Identity;
+import org.jooq.Index;
+import org.jooq.Name;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.DSL;
+import org.jooq.impl.TableImpl;
+import org.jooq.types.UInteger;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class World extends TableImpl<WorldRecord> {
+
+    private static final long serialVersionUID = 894226680;
+
+    /**
+     * The reference instance of <code>hello_world.world</code>
+     */
+    public static final World WORLD = new World();
+
+    /**
+     * The class holding records for this type
+     */
+    @Override
+    public Class<WorldRecord> getRecordType() {
+        return WorldRecord.class;
+    }
+
+    /**
+     * The column <code>hello_world.world.id</code>.
+     */
+    public final TableField<WorldRecord, UInteger> ID = createField("id", org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false).identity(true), this, "");
+
+    /**
+     * The column <code>hello_world.world.randomNumber</code>.
+     */
+    public final TableField<WorldRecord, Integer> RANDOMNUMBER = createField("randomNumber", org.jooq.impl.SQLDataType.INTEGER.nullable(false).defaultValue(org.jooq.impl.DSL.inline("0", org.jooq.impl.SQLDataType.INTEGER)), this, "");
+
+    /**
+     * Create a <code>hello_world.world</code> table reference
+     */
+    public World() {
+        this(DSL.name("world"), null);
+    }
+
+    /**
+     * Create an aliased <code>hello_world.world</code> table reference
+     */
+    public World(String alias) {
+        this(DSL.name(alias), WORLD);
+    }
+
+    /**
+     * Create an aliased <code>hello_world.world</code> table reference
+     */
+    public World(Name alias) {
+        this(alias, WORLD);
+    }
+
+    private World(Name alias, Table<WorldRecord> aliased) {
+        this(alias, aliased, null);
+    }
+
+    private World(Name alias, Table<WorldRecord> aliased, Field<?>[] parameters) {
+        super(alias, null, aliased, parameters, "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Schema getSchema() {
+        return HelloWorld.HELLO_WORLD;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<Index> getIndexes() {
+        return Arrays.<Index>asList(Indexes.WORLD_PRIMARY);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Identity<WorldRecord, UInteger> getIdentity() {
+        return Keys.IDENTITY_WORLD;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UniqueKey<WorldRecord> getPrimaryKey() {
+        return Keys.KEY_WORLD_PRIMARY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<UniqueKey<WorldRecord>> getKeys() {
+        return Arrays.<UniqueKey<WorldRecord>>asList(Keys.KEY_WORLD_PRIMARY);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public World as(String alias) {
+        return new World(DSL.name(alias), this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public World as(Name alias) {
+        return new World(alias, this);
+    }
+
+    /**
+     * Rename this table
+     */
+    @Override
+    public World rename(String name) {
+        return new World(DSL.name(name), null);
+    }
+
+    /**
+     * Rename this table
+     */
+    @Override
+    public World rename(Name name) {
+        return new World(name, null);
+    }
+}

+ 190 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/records/FortuneRecord.java

@@ -0,0 +1,190 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models.tables.records;
+
+
+import javax.annotation.Generated;
+
+import models.tables.Fortune;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Record2;
+import org.jooq.Row2;
+import org.jooq.impl.UpdatableRecordImpl;
+import org.jooq.types.UInteger;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class FortuneRecord extends UpdatableRecordImpl<FortuneRecord> implements Record2<UInteger, String> {
+
+    private static final long serialVersionUID = -1978128230;
+
+    /**
+     * Setter for <code>hello_world.fortune.id</code>.
+     */
+    public void setId(UInteger value) {
+        set(0, value);
+    }
+
+    /**
+     * Getter for <code>hello_world.fortune.id</code>.
+     */
+    public UInteger getId() {
+        return (UInteger) get(0);
+    }
+
+    /**
+     * Setter for <code>hello_world.fortune.message</code>.
+     */
+    public void setMessage(String value) {
+        set(1, value);
+    }
+
+    /**
+     * Getter for <code>hello_world.fortune.message</code>.
+     */
+    public String getMessage() {
+        return (String) get(1);
+    }
+
+    // -------------------------------------------------------------------------
+    // Primary key information
+    // -------------------------------------------------------------------------
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Record1<UInteger> key() {
+        return (Record1) super.key();
+    }
+
+    // -------------------------------------------------------------------------
+    // Record2 type implementation
+    // -------------------------------------------------------------------------
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Row2<UInteger, String> fieldsRow() {
+        return (Row2) super.fieldsRow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Row2<UInteger, String> valuesRow() {
+        return (Row2) super.valuesRow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Field<UInteger> field1() {
+        return Fortune.FORTUNE.ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Field<String> field2() {
+        return Fortune.FORTUNE.MESSAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UInteger component1() {
+        return getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String component2() {
+        return getMessage();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UInteger value1() {
+        return getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String value2() {
+        return getMessage();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FortuneRecord value1(UInteger value) {
+        setId(value);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FortuneRecord value2(String value) {
+        setMessage(value);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FortuneRecord values(UInteger value1, String value2) {
+        value1(value1);
+        value2(value2);
+        return this;
+    }
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    /**
+     * Create a detached FortuneRecord
+     */
+    public FortuneRecord() {
+        super(Fortune.FORTUNE);
+    }
+
+    /**
+     * Create a detached, initialised FortuneRecord
+     */
+    public FortuneRecord(UInteger id, String message) {
+        super(Fortune.FORTUNE);
+
+        set(0, id);
+        set(1, message);
+    }
+}

+ 190 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/models/tables/records/WorldRecord.java

@@ -0,0 +1,190 @@
+/*
+ * This file is generated by jOOQ.
+*/
+package models.tables.records;
+
+
+import javax.annotation.Generated;
+
+import models.tables.World;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Record2;
+import org.jooq.Row2;
+import org.jooq.impl.UpdatableRecordImpl;
+import org.jooq.types.UInteger;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+    value = {
+        "http://www.jooq.org",
+        "jOOQ version:3.10.1"
+    },
+    comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class WorldRecord extends UpdatableRecordImpl<WorldRecord> implements Record2<UInteger, Integer> {
+
+    private static final long serialVersionUID = -323588540;
+
+    /**
+     * Setter for <code>hello_world.world.id</code>.
+     */
+    public void setId(UInteger value) {
+        set(0, value);
+    }
+
+    /**
+     * Getter for <code>hello_world.world.id</code>.
+     */
+    public UInteger getId() {
+        return (UInteger) get(0);
+    }
+
+    /**
+     * Setter for <code>hello_world.world.randomNumber</code>.
+     */
+    public void setRandomnumber(Integer value) {
+        set(1, value);
+    }
+
+    /**
+     * Getter for <code>hello_world.world.randomNumber</code>.
+     */
+    public Integer getRandomnumber() {
+        return (Integer) get(1);
+    }
+
+    // -------------------------------------------------------------------------
+    // Primary key information
+    // -------------------------------------------------------------------------
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Record1<UInteger> key() {
+        return (Record1) super.key();
+    }
+
+    // -------------------------------------------------------------------------
+    // Record2 type implementation
+    // -------------------------------------------------------------------------
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Row2<UInteger, Integer> fieldsRow() {
+        return (Row2) super.fieldsRow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Row2<UInteger, Integer> valuesRow() {
+        return (Row2) super.valuesRow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Field<UInteger> field1() {
+        return World.WORLD.ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Field<Integer> field2() {
+        return World.WORLD.RANDOMNUMBER;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UInteger component1() {
+        return getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Integer component2() {
+        return getRandomnumber();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UInteger value1() {
+        return getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Integer value2() {
+        return getRandomnumber();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WorldRecord value1(UInteger value) {
+        setId(value);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WorldRecord value2(Integer value) {
+        setRandomnumber(value);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WorldRecord values(UInteger value1, Integer value2) {
+        value1(value1);
+        value2(value2);
+        return this;
+    }
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    /**
+     * Create a detached WorldRecord
+     */
+    public WorldRecord() {
+        super(World.WORLD);
+    }
+
+    /**
+     * Create a detached, initialised WorldRecord
+     */
+    public WorldRecord(UInteger id, Integer randomnumber) {
+        super(World.WORLD);
+
+        set(0, id);
+        set(1, randomnumber);
+    }
+}

+ 15 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/utils/DatabaseExecutionContext.java

@@ -0,0 +1,15 @@
+package utils;
+
+import javax.inject.Inject;
+
+import akka.actor.ActorSystem;
+import play.libs.concurrent.CustomExecutionContext;
+
+public class DatabaseExecutionContext extends CustomExecutionContext {
+
+    @Inject
+    public DatabaseExecutionContext(final ActorSystem actorSystem) {
+        super(actorSystem, "database.dispatcher");
+    }
+
+}

+ 16 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/views/fortunes.scala.html

@@ -0,0 +1,16 @@
+@(fortunes: List[models.tables.records.FortuneRecord])
+
+@main() {
+    <table>
+        <tr>
+            <th>id</th>
+            <th>message</th>
+        </tr>
+        @for(fortune <- fortunes) {
+        <tr>
+            <td>@fortune.getId()</td>
+            <td>@fortune.getMessage()</td>
+        </tr>
+        }
+    </table>
+}

+ 12 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/app/views/main.scala.html

@@ -0,0 +1,12 @@
+@()(content: Html)
+
+<!DOCTYPE html>
+
+<html>
+    <head>
+        <title>Fortunes</title>
+    </head>
+    <body>
+    @content
+    </body>
+</html>

+ 16 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/build.sbt

@@ -0,0 +1,16 @@
+name := "play2-java-jooq-hikaricp"
+
+version := "1.0-SNAPSHOT"
+
+lazy val root = (project in file(".")).enablePlugins(PlayJava)
+
+scalaVersion := "2.12.4"
+
+val jOOQVersion = "3.10.1"
+
+libraryDependencies ++= Seq(
+  guice,
+  javaJdbc,
+  "mysql" % "mysql-connector-java" % "5.1.44",
+  "org.jooq" % "jooq" % jOOQVersion,
+)

+ 69 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/application.conf

@@ -0,0 +1,69 @@
+# This is the main configuration file for the application.
+# ~~~~~
+
+# Secret key
+# ~~~~~
+# The secret key is used to secure cryptographics functions.
+play.http.secret.key = "wMULsT5mMPX4z62A8mUnR4d8P2vSyg8nktC43yooggD84GtFNQKrVjDu3chUrpUa"
+
+# The application languages
+# ~~~~~
+play.i18n.langs = [ "en" ]
+
+# Disable default filters
+play.filters.enabled = [ ]
+
+play.server.akka.server-header = "Play2"
+
+# Number of database connections
+# https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
+# db connections = ((physical_core_count * 2) + effective_spindle_count)
+# The TechEmpower benchmark environment uses 2 x 4-Core E5520 CPUs in the database server
+# That is 8 physical cores
+# https://www.techempower.com/benchmarks/#section=environment
+fixedConnectionPool = 17
+
+database.dispatcher {
+    executor = "thread-pool-executor"
+    throughput = 1
+    thread-pool-executor {
+        fixed-pool-size = ${fixedConnectionPool}
+    }
+}
+
+# Database configuration
+# ~~~~~
+# You can declare as many datasources as you want.
+# By convention, the default datasource is named `default`
+db {
+    default {
+        # https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
+        url = "jdbc:mysql://TFB-database:3306/hello_world"
+        username = "benchmarkdbuser"
+        password = "benchmarkdbpass"
+        hikaricp {
+            dataSource {
+                cachePrepStmts=true
+                prepStmtCacheSize=250
+                prepStmtCacheSqlLimit=2048
+                useServerPrepStmts=true
+                useLocalSessionState=true
+                useLocalTransactionState=true
+                rewriteBatchedStatements=true
+                cacheResultSetMetadata=true
+                cacheServerConfiguration=true
+                cacheCallableStmts=true
+                callableStmtCacheSize=250
+                elideSetAutoCommits=true
+                maintainTimeStats=false
+                alwaysSendSetIsolation=false
+                zeroDateTimeBehavior="convertToNull"
+                traceProtocol=false
+                jdbcCompliantTruncation=false
+                useUnbufferedInput=false
+                #useReadAheadInput=false
+            }
+            maximumPoolSize = ${fixedConnectionPool}
+        }
+    }
+}

+ 28 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/logback.xml

@@ -0,0 +1,28 @@
+<configuration>
+    
+  <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>500</queueSize>
+    <discardingThreshold>0</discardingThreshold>
+    <appender-ref ref="STDOUT" />
+  </appender>
+
+  <!--
+    The logger name is typically the Java/Scala package name.
+    This configures the log level to log at for a package and its children packages.
+  -->
+  <logger name="play" level="INFO" />
+  <logger name="application" level="INFO" />
+
+  <root level="ERROR">
+    <appender-ref ref="ASYNCSTDOUT" />
+  </root>
+
+</configuration>

+ 8 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/conf/routes

@@ -0,0 +1,8 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+
+GET        /db                  controllers.Application.db()
+GET        /queries             controllers.Application.queries(queries:String ?= "1")
+GET        /fortunes            controllers.Application.fortunes()
+GET        /update              controllers.Application.update(queries:String ?= "1")

+ 1 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/project/build.properties

@@ -0,0 +1 @@
+sbt.version=1.0.2

+ 1 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/project/plugins.sbt

@@ -0,0 +1 @@
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.7")

+ 17 - 0
frameworks/Java/play2-java/play2-java-jooq-hikaricp/source_code

@@ -0,0 +1,17 @@
+./play2-java-jooq-hikaricp/app/
+./play2-java-jooq-hikaricp/app/controllers
+./play2-java-jooq-hikaricp/app/controllers/Application.java
+./play2-java-jooq-hikaricp/app/utils
+./play2-java-jooq-hikaricp/app/utils/DatabaseExecutionContext.java
+./play2-java-jooq-hikaricp/app/models
+./play2-java-jooq-hikaricp/app/models/DefaultCatalog.java
+./play2-java-jooq-hikaricp/app/models/HelloWorld.java
+./play2-java-jooq-hikaricp/app/models/Indexes.java
+./play2-java-jooq-hikaricp/app/models/Keys.java
+./play2-java-jooq-hikaricp/app/models/Tables.java
+./play2-java-jooq-hikaricp/app/models/tables
+./play2-java-jooq-hikaricp/app/models/tables/Fortune.java
+./play2-java-jooq-hikaricp/app/models/tables/World.java
+./play2-java-jooq-hikaricp/app/models/tables/records
+./play2-java-jooq-hikaricp/app/models/tables/records/FortuneRecord.java
+./play2-java-jooq-hikaricp/app/models/tables/records/WorldRecord.java

+ 10 - 0
frameworks/Java/play2-java/setup_java_jooq_hikaricp.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+fw_depends mysql java sbt
+
+cd play2-java-jooq-hikaricp
+
+rm -rf target/universal/stage/RUNNING_PID
+
+sbt stage
+target/universal/stage/bin/play2-java-jooq-hikaricp &