JavaFX JDBC MySQL Tutorial

In this tutorial, we will learn how to create a JavaFX application with database connectivity. In this JavaFx application, we create a Registration Form and we will store user registration form data into MySQL database using JDBC API.
In this tutorial, we use the MySQL Connector/J driver. It is the official JDBC driver for MySQL.
Before getting started with the actual implementation, let's briefly discuss what is JDBC, MySQL Connector/J driver.

What is JDBC?

Java Database Connectivity or JDBC API provides industry-standard and database-independent connectivity between the Java applications and relational database servers(relational databases, spreadsheets, and flat files). 
Using the JDBC API, we can access virtually any data source, from relational databases to spreadsheets and flat files. JDBC technology also provides a common base on which tools and alternate interfaces can be built.
Check out complete JDBC tutorial at https://www.javaguides.net/p/jdbc-tutorial.html.

MySQL Connector/J

To connect to MySQL in Java, MySQL provides MySQL Connector/J, a driver that implements the JDBC API. MySQL Connector/J is a JDBC Type 4 driver. The Type 4 designation means that the driver is a pure Java implementation of the MySQL protocol and does not rely on the MySQL client libraries.
In this tutorial, we use mysql-connector-java-8.0.15, check out the latest release at https://mvnrepository.com/artifact/mysql/mysql-connector-java.
MySQL is a leading open-source database management system. It is a multi-user, multithreaded database management system. MySQL is especially popular on the web. It is one part of the very popular LAMP platform consisting of Linux, Apache, MySQL, and PHP.

What will you learn?

In this tutorial, you’ll learn -
  1. How to create the layout of a JavaFX application window using FXML.
  2. How to add UI controls like Text Field, Password Field, and Button.
  3. How to validate UI controls like Text Field, Password Field
  4. How to connect JavaFX application with MySQL database via JDBC API.

Tools and Technologies used

  • JDK 1.8
  • MySQL Connector Java - 8.0.13
  • JDBC - 4.2
  • Eclipse IDE
  • JavaFX

Development steps

  1. Create a Simple Maven Project
  2. Add Dependencies
  3. Project Structure
  4. Database Setup
  5. Create the Main Application Class
  6. Create the Layout for Our Application using FXML
  7. Create a register controller to handle form data
  8. Create JDBCDao for Database operations
  9. Run application
  10. Output

1. Create a Simple Maven Project

Let's create a simple maven project and name this project as "javafx-registration-form-mysql-tutorial". Refer below step by step tutorial to create a simple maven project.

2. Add Dependencies

Let's add MySQL driver maven dependency to above-created maven project:
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.javaguides.javafx</groupId>
    <artifactId>javafx-registration-form-mysql-tutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>javafx-registration-form-mysql-tutorial</name>
    <description>javafx-registration-form-mysql-tutorial</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mainClass>com.javaguides.javafx.registration.MainApp</mainClass>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3. Project Structure

Refer below screenshot to create a project or packaging structure for this application -

4. Database Setup

Make sure that you have installed MySQL server on your machine.
Let's first create a database with the following SQL statement:
create database javafx_registration;
Now, let's create a registration table in the above-created database with the following SQL statement:
CREATE TABLE registration
( 
 id BIGINT PRIMARY KEY AUTO_INCREMENT,
 full_name varchar(250) NOT NULL,
 email_id varchar(250) NOT NULL,
 password varchar(250)
);

5. Create the Main Application Class

Let’s first write the MainApp application class. As usual, For creating a JavaFX application, we’ll need to extend our Main class from javafx.application.Application and override its start() method.
package com.javaguides.javafx.registration;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class MainApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        System.out.println(getClass());
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/registration_form.fxml"));
        stage.setTitle("User Registration");
        stage.setScene(new Scene(root, 800, 500));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
We first load the FXML document using FXMLLoader. We wil create registration_form.fxml file in next step.

6. Create the Layout for Our Application using FXML

We’ll use JavaFX GridPane layout for designing the registration form. It enables us to create a flexible grid of rows and columns in which to layout UI-controls.
<?import javafx.scene.layout.GridPane?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Button?>
<GridPane fx:controller="com.javaguides.javafx.registration.RegisterController"
    xmlns:fx="http://javafx.com/fxml" alignment="center"
          hgap="10" vgap="10">
    <padding>
        <Insets top="40" right="40" bottom="40" left="40"/>
    </padding>
    <columnConstraints>
        <ColumnConstraints minWidth="100" prefWidth="100"
                           maxWidth="Infinity" halignment="RIGHT"></ColumnConstraints>
        <ColumnConstraints minWidth="200" prefWidth="200"
                           maxWidth="Infinity" hgrow="ALWAYS"></ColumnConstraints>
    </columnConstraints>
    <!-- Add Header Label -->
    <Label text="Registration Form (FXML)" GridPane.columnIndex="0" 
           GridPane.rowIndex="0" GridPane.columnSpan="2" 
           GridPane.rowSpan="1" GridPane.halignment="CENTER" >
        <font>
            <Font name="Arial" size="24" ></Font>
        </font>
        <GridPane.margin>
            <Insets top="20" right="0" bottom="20" left="0"></Insets>
        </GridPane.margin>
    </Label>
    <!-- Add Name Label -->
    <Label text="Full Name : " GridPane.columnIndex="0" 
           GridPane.rowIndex="1" ></Label>
    <!-- Add Name Text Field -->
    <TextField fx:id="fullNameField" prefHeight="40" 
               GridPane.columnIndex="1" GridPane.rowIndex="1"/>
    <!-- Add Email Label -->
    <Label text="Email ID : " GridPane.columnIndex="0" 
           GridPane.rowIndex="2" ></Label>
    <!-- Add Email Text Field -->
    <TextField fx:id="emailIdField" prefHeight="40" 
               GridPane.columnIndex="1" GridPane.rowIndex="2"/>
    <!-- Add Password Label -->
    <Label text="Password : " GridPane.columnIndex="0" 
           GridPane.rowIndex="3" ></Label>
    <!-- Add Password Field -->
    <PasswordField fx:id="passwordField" prefHeight="40" 
                   GridPane.columnIndex="1" GridPane.rowIndex="3"/>
    <!-- Add Submit Button -->
    <Button fx:id="submitButton" text="Submit"
            prefWidth="100" prefHeight="40" defaultButton="true"
            GridPane.columnIndex="0" GridPane.rowIndex="4"
            GridPane.columnSpan="2" GridPane.rowSpan="1"
            GridPane.halignment="CENTER"
            onAction="#register">
        <GridPane.margin>
            <Insets top="20" right="0" bottom="20" left="0"></Insets>
        </GridPane.margin>
    </Button>
</GridPane>
The above FXML document is self-explanatory.
In the above FXML document, We create a GridPane layout which is center aligned and has a horizontal and vertical gap of 10.
We also specify the padding of 40px on each side. The layout also defines the controller that will be used to handle any mouse or keyboard events using fx:controller property.
GridPane.columnIndex and GridPane.rowIndex properties allow us to place ui controls in a particular cell.
The Submit button has an onAction property which calls a method named submitButton. This method has to be defined in the FXML controller and that’s we will create in the next step.

7. Create a register controller to handle form data

Let's create a RegisterController.java class and add the following content to it:
package com.javaguides.javafx.registration;

import java.sql.SQLException;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Window;

public class RegisterController {

    @FXML
    private TextField fullNameField;

    @FXML
    private TextField emailIdField;

    @FXML
    private PasswordField passwordField;

    @FXML
    private Button submitButton;

    @FXML
    public void register(ActionEvent event) throws SQLException {

        Window owner = submitButton.getScene().getWindow();

        System.out.println(fullNameField.getText());
        System.out.println(emailIdField.getText());
        System.out.println(passwordField.getText());
        if (fullNameField.getText().isEmpty()) {
            showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter your name");
            return;
        }

        if (emailIdField.getText().isEmpty()) {
            showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter your email id");
            return;
        }
        if (passwordField.getText().isEmpty()) {
            showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter a password");
            return;
        }

        String fullName = fullNameField.getText();
        String emailId = emailIdField.getText();
        String password = passwordField.getText();

        JdbcDao jdbcDao = new JdbcDao();
        jdbcDao.insertRecord(fullName, emailId, password);

        showAlert(Alert.AlertType.CONFIRMATION, owner, "Registration Successful!",
            "Welcome " + fullNameField.getText());
    }

    private static void showAlert(Alert.AlertType alertType, Window owner, String title, String message) {
        Alert alert = new Alert(alertType);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.initOwner(owner);
        alert.show();
    }
}
Note that the FXMLLoader will automatically inject values defined in the FXML document into corresponding references in the controller class.
So, the fullNameFieldemailIdFieldpasswordField and submitButton references specified in the above controller will automatically be injected by the objects created from the FXML document.
The @FXML annotation is mandatory for private member fields of the controller class, otherwise, field injection won’t work. However, it can be omitted for public fields.
We validate form fields and store to a database using JdbcDao class.

8. Create JDBCDao for Database operations

Here are steps to connect to the MySQL database:
  1. Establishing a connection
  2. Create a statement
  3. Execute the query
  4. Using try-with-resources Statements to Automatically Close JDBC Resources
From JDBC 4.0, we don't need to include 'Class.forName()' in our code, to load JDBC driver. When the method 'getConnection' is called, the 'DriverManager' will automatically load the suitable driver among the JDBC drivers that were loaded at initialization and those loaded explicitly using the same class loader as the current application.
Connection conn = DriverManager.getConnection(Urldatabase,Username,Password);
Any JDBC 4.0 drivers that are found in your classpath are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)
Here is complete code to store user registration form-data:
 package com.javaguides.javafx.registration;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcDao {

    // Replace below database url, username and password with your actual database credentials
    private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/javafx_registration?useSSL=false";
    private static final String DATABASE_USERNAME = "root";
    private static final String DATABASE_PASSWORD = "root";
    private static final String INSERT_QUERY = "INSERT INTO registration (full_name, email_id, password) VALUES (?, ?, ?)";


    public void insertRecord(String fullName, String emailId, String password) throws SQLException {

        // Step 1: Establishing a Connection and 
        // try-with-resource statement will auto close the connection.
        try (Connection connection = DriverManager
            .getConnection(DATABASE_URL, DATABASE_USERNAME, DATABASE_PASSWORD);

            // Step 2:Create a statement using connection object
            PreparedStatement preparedStatement = connection.prepareStatement(INSERT_QUERY)) {
            preparedStatement.setString(1, fullName);
            preparedStatement.setString(2, emailId);
            preparedStatement.setString(3, password);

            System.out.println(preparedStatement);
            // Step 3: Execute the query or update query
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            // print SQL exception information
            printSQLException(e);
        }
    }

    public static void printSQLException(SQLException ex) {
        for (Throwable e: ex) {
            if (e instanceof SQLException) {
                e.printStackTrace(System.err);
                System.err.println("SQLState: " + ((SQLException) e).getSQLState());
                System.err.println("Error Code: " + ((SQLException) e).getErrorCode());
                System.err.println("Message: " + e.getMessage());
                Throwable t = ex.getCause();
                while (t != null) {
                    System.out.println("Cause: " + t);
                    t = t.getCause();
                }
            }
        }
    }
}

9. Run application

In order to run this JavaFX application, open MainApp.java file which contains main() method so right click-> Run As -> Java Application.

10. Output

Following are some screenshots of the application we just built.

Registration form validation:

Registration form enter valid data: 

Registration form submit success: 

Reference

Get source code of this tutorial on my GitHub Repository.

Comments