Blog

Vaadin + jOOQ: Implementing Business Web Applications in Plain Java

By  
Alejandro Duarte
Alejandro Duarte
·
On Oct 14, 2016 7:21:00 AM
·

Note: This post has been updated to use Vaadin 8.

When speaking about business applications, you might find that a lot of them fall into the “data-centric” kind of application where SQL is frequently the key technology. Similarly, when speaking about web applications, you’ll end up with HTML rendered on the browser, most likely with the help of JavaScript. If we put this into the context of Java, web business applications can be implemented by directly using SQL, HTML, JavaScript, and of course Java. Vaadin and jOOQ enable you to implement data-centric web applications using only one language: Java.

This step by step guide shows you how to implement a Spring-based web application that connects to a MySQL server in order to query data that can be filtered from the UI. This guide assumes you know the very basics of Maven and Spring Framework (particularly the concept of dependency injection).

Step 1: Create a Spring-based project

Create a new Spring Boot application by going to http://start.spring.io and adding the Vaadin, jOOQ, and MySql dependencies as shown in the following figure:

Screen Shot 2016-10-04 at 14.38.32.pngClick the Generate Project button and extract the generated zip file. You should get a Maven project you can import into your favorite IDE.

Step 2: Create a MySQL database

Connect to the MySQL instance and create a new schema:

CREATE SCHEMA demo;

Create the following table:

CREATE TABLE customer(
    id SERIAL, first_name VARCHAR(255),
    last_name VARCHAR(255)
);

Add some test data, such as the following:

INSERT INTO customer(first_name, last_name) VALUES('Lukas', 'Eder');
INSERT INTO customer(first_name, last_name) VALUES('Mario', 'Fusco');
INSERT INTO customer(first_name, last_name) VALUES('Edson', 'Yanaga');
INSERT INTO customer(first_name, last_name) VALUES('Anton', 'Arhipov');
INSERT INTO customer(first_name, last_name) VALUES('Andres', 'Almiray');

Step 3: Configure the database connection

jOOQ allows you to reverse-engineer the database into a set of Java classes modeling the tables, sequences, and stored procedures, among other database objects.

Start by configuring the database connection in the application.properties file inside the src/main/resources directory:

spring.datasource.url=jdbc:mysql://localhost/demo
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jooq.sql-dialect=MySQL

Remember to change the username and password used to connect to your own database.

Step 4: Reverse-engineer the database

Add the Properties Maven plugin and the jOOQ Code Generator plugin for Maven in the plugins section of the pom.xml file:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>properties-maven-plugin</artifactId>
   <version>1.0.0</version>
   <executions>
       <execution>
           <phase>initialize</phase>
           <goals>
               <goal>read-project-properties</goal>
           </goals>
           <configuration>
               <files>
                   <file>src/main/resources/application.properties</file>
               </files>
           </configuration>
       </execution>
   </executions>
</plugin>
<plugin>
   <groupId>org.jooq</groupId>
   <artifactId>jooq-codegen-maven</artifactId>
   <version>3.8.4</version>
   <executions>
       <execution>
           <goals>
               <goal>generate</goal>
           </goals>
       </execution>
   </executions>
   <configuration>
       <jdbc>
           <url>${spring.datasource.url}</url>
           <user>${spring.datasource.username}</user>
           <password>${spring.datasource.password}</password>
           <driver>${spring.datasource.driver}</driver>
       </jdbc>
       <generator>
           <database>
               <name>org.jooq.util.mysql.MySQLDatabase</name>
               <inputSchema>demo</inputSchema>
           </database>
           <target>
               <packageName>com.example</packageName>
               <directory>target/generated-sources/jooq</directory>
           </target>
       </generator>
   </configuration>
</plugin>

The previous snippet uses the connection properties defined in the application.properties file to avoid duplicating this configuration. Make sure the <inputSchema> element contains the name of the MySQL database you previously created.

Run the following Maven command:

    mvn clean install

This will reverse-engineer the database and generate the corresponding Java classes in the target/generated-sources/jooq/ directory.

Note that if you are using Eclipse, you have to give it an extra “hint” for it to pick the generated sources directory and not to complain about missing “m2e connectors”.

Step 5: Create a back-end service class

Create the following CustomerService class:

package com.example;

import com.example.tables.records.CustomerRecord;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

import static com.example.Tables.*;

@Component
public class CustomerService {

    @Autowired
    private DSLContext dslContext;

    public List<CustomerRecord> searchByName(String name) {
        String filter = name + "%";
        return dslContext
            .selectFrom(CUSTOMER)
            .where(CUSTOMER.FIRST_NAME.likeIgnoreCase(filter)
            .or(CUSTOMER.LAST_NAME.likeIgnoreCase(filter)))
            .fetchInto(CustomerRecord.class);
    }
}

Spring Boot will automatically create a bean of type DSLContext that you can use to query the database using plain Java but in a way that resembles SQL. Visit the official documentation site of jOOQ for more information about the capabilities of its API.

Step 6: Implement the UI

Create a Vaadin UI by implementing the VaadinUI class:

package com.example;

import com.example.tables.records.CustomerRecord;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Grid;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@SpringUI
public class VaadinUI extends UI {

    @Autowired
    private CustomerService service;

    private Grid<CustomerRecord> grid = new Grid(CustomerRecord.class);

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        TextField filter = new TextField("Filter by name:");
        filter.addValueChangeListener(e -> updateGrid(filter.getValue()));

        VerticalLayout layout = new VerticalLayout(filter, grid);
        setContent(layout);
        updateGrid("");
        grid.setColumns("firstName", "lastName");
    }

    private void updateGrid(String filter) {
        List<CustomerRecord> customers = service.searchByName(filter);
        grid.setItems(customers);
    }

}

This class creates a UI containing a Grid component to show all the customers in the database and a filter to search by first or last name. Notice how the VaadinUI class is annotated with @SpringUI. This means we can inject the CustomerService bean in this class and use it to fetch customers.

Step 7: Run the application

Spring Initializr created the Application class with a standard main method defining the entry point of the Java application. When you run the application using this method, Spring Boot configures and runs a Tomcat server on port 8080 (all this can be configured).

Before running the application you have to build it. You can use the following command to build and run the application:

    mvn install spring-boot:run

The following is a screenshot of the application:

Screen Shot 2016-10-04 at 16.50.49.png

Check out the full jOOQ + Vaadin example from GitHub

Alejandro Duarte
Alejandro Duarte
Software Engineer and Developer Advocate at MariaDB Corporation. Author of Practical Vaadin (Apress), Data-Centric Applications with Vaadin 8 (Packt), and Vaadin 7 UI Design by Example (Packt). Passionate about software development with Java and open-source technologies. Contact him on Twitter @alejandro_du or through his personal blog at www.programmingbrain.com.
Other posts by Alejandro Duarte