8

Can anyone give me one example of a class that connects JavaFX with MySQL, dont want Main class, have one, just want a example of a class that connects any application to a MySQL database and gets a row from that database into a table, searched the whole internet and i didn't find anything straight to the point i do not want anything fancy just something to get the job done please. Something clean and simple.

marcS
  • 83
  • 1
  • 1
  • 5
  • You shouldn't do this with one class: it's very bad practice to mix such different pieces of functionality (database connection on the one hand, UI on the other hand) in one place. Separate it into different components. – James_D Sep 03 '14 at 20:09
  • @James_D i didn't say to do it with one class i ment that i want a good simple clean and clear example of a class that connects my javaFX project to a MySQL database and a example of how to get the data from the database into a table. I haven't seen anything like it on google or youtube or facebook or stackoverflow etc – marcS Sep 03 '14 at 20:17
  • Well, there are hundreds of examples of displaying data in a `TableView`, and hundreds of examples of retrieving data from a database. I will put something together but I'm not sure what there is that doesn't exist elsewhere. – James_D Sep 03 '14 at 20:21

2 Answers2

22

At a minimum, you need three classes: one to represent your data, one for your UI, and one to manage the database connection. In a real app you'd need more than this, of course. This example follows the same basic example as the TableView tutorial

Suppose your database has a person table with three columns, first_name, last_name, email_address.

Then you would write a Person class:

import javafx.beans.property.StringProperty ;
import javafx.beans.property.SimpleStringProperty ;

public class Person {
    private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
    public StringProperty firstNameProperty() {
        return firstName ;
    }
    public final String getFirstName() {
        return firstNameProperty().get();
    }
    public final void setFirstName(String firstName) {
        firstNameProperty().set(firstName);
    }

    private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
    public StringProperty lastNameProperty() {
        return lastName ;
    }
    public final String getLastName() {
        return lastNameProperty().get();
    }
    public final void setLastName(String lastName) {
        lastNameProperty().set(lastName);
    }

    private final StringProperty email = new SimpleStringProperty(this, "email");
    public StringProperty emailProperty() {
        return email ;
    }
    public final String getEmail() {
        return emailProperty().get();
    }
    public final void setEmail(String email) {
        emailProperty().set(email);
    }

    public Person() {}

    public Person(String firstName, String lastName, String email) {
        setFirstName(firstName);
        setLastName(lastName);
        setEmail(email);
    }

}

A class to access the data from the database:

import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.SQLException ;
import java.sql.Statement ;
import java.sql.ResultSet ;

import java.util.List ;
import java.util.ArrayList ;

public class PersonDataAccessor {

    // in real life, use a connection pool....
    private Connection connection ;

    public PersonDataAccessor(String driverClassName, String dbURL, String user, String password) throws SQLException, ClassNotFoundException {
        Class.forName(driverClassName);
        connection = DriverManager.getConnection(dbURL, user, password);
    }

    public void shutdown() throws SQLException {
        if (connection != null) {
            connection.close();
        }
    }

    public List<Person> getPersonList() throws SQLException {
        try (
            Statement stmnt = connection.createStatement();
            ResultSet rs = stmnt.executeQuery("select * from person");
        ){
            List<Person> personList = new ArrayList<>();
            while (rs.next()) {
                String firstName = rs.getString("first_name");
                String lastName = rs.getString("last_name");
                String email = rs.getString("email_address");
                Person person = new Person(firstName, lastName, email);
                personList.add(person);
            }
            return personList ;
        } 
    }

    // other methods, eg. addPerson(...) etc
}

And then a UI class:

import javafx.application.Application ;
import javafx.scene.control.TableView ;
import javafx.scene.control.TableColumn ;
import javafx.scene.control.cell.PropertyValueFactory ;
import javafx.scene.layout.BorderPane ;
import javafx.scene.Scene ;
import javafx.stage.Stage ;

public class PersonTableApp extends Application {
    private PersonDataAccessor dataAccessor ;

    @Override
    public void start(Stage primaryStage) throws Exception {
        dataAccessor = new PersonDataAccessor(...); // provide driverName, dbURL, user, password...

        TableView<Person> personTable = new TableView<>();
        TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
        firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
        TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
        lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
        TableColumn<Person, String> emailCol = new TableColumn<>("Email");
        emailCol.setCellValueFactory(new PropertyValueFactory<>("email"));

        personTable.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        personTable.getItems().addAll(dataAccessor.getPersonList());

        BorderPane root = new BorderPane();
        root.setCenter(personTable);
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception {
        if (dataAccessor != null) {
            dataAccessor.shutdown();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

(I just typed that in without testing, so there may be typos, missing imports, etc, but it should be enough to give you the idea.)

James_D
  • 201,275
  • 16
  • 291
  • 322
5

In addition to the answer of James_D:

I wanted to connect to a remote (MySQL) database, so I changed the constructor and connected by url-only:

public UserAccessor(String dbURL, String user, String password) throws SQLException, ClassNotFoundException {
    connection = DriverManager.getConnection(dbURL, user, password);
}

Init via:

UserAccessor userAccessor = new UserAccessor(
   "jdbc:mysql://xxx.xxx.xxx.xxx:YOUR_PORT", "YOUR_DB_USER", "YOUR_PASSWORD")

Please note: You will also need to include the connector lib. I choosed mysql-connector-java-5.1.40-bin.jar which came with IntelliJ and was located under /Users/martin/Library/Preferences/IntelliJIdea2017.1/jdbc-drivers/MySQL Connector/J/5.1.40/mysql-connector-java-5.1.40-bin.jar

Kudos belong to James_D.

Martin Pfeffer
  • 12,471
  • 9
  • 59
  • 68