A JavaFX desktop application for tracking student grades, where students are automatically categorized as Pass or Fail based on their grade. This version replaces the original in-memory data storage with a real MySQL database, accessed through JDBC.
This repository contains only the database-integration part of a larger university project. Adding a student through the UI performs a real
INSERTinto MySQL, and the Pass / Fail screens are populated by querying the database directly.
- Add a new student (name, subject, grade 0–10, date) through a simple form.
- Automatic Pass/Fail categorization based on the grade (
grade >= 5). - Two list screens (Pass / Fail) backed by a
TableView, with:- Sorting by subject, grade, or date.
- A right-click context menu to delete a record or move it to the other list (manual override for incorrect grade entries).
- All data is persisted in MySQL — nothing is lost when the app is closed.
| Class | Role | Notes |
|---|---|---|
Student |
Model | Holds id, name, subject, grade, date. getStatus() computes "Pass"/"Fail" from the grade. |
DBConnection |
Connection helper | Opens a Connection to MySQL via DriverManager. |
StudentDAO |
Data access | The only class that contains SQL: insertStudent(), getPassList(), getFailList(), deleteStudent(), updateGrade(). |
App |
Application bootstrap | Loads primary.fxml on start; exposes setRoot() for screen switching. |
PrimaryController |
Navigation | Routes to Add / Pass / Fail screens; no business logic. |
AddController |
Form input | Validates input, builds a Student, and calls studentDAO.insertStudent(...). |
PassController / FailController |
List display | Bind a TableView to the list returned by StudentDAO; handle sorting and the delete/move context-menu actions. |
Every SQL statement in StudentDAO uses PreparedStatement with ?
placeholders instead of string concatenation. This prevents SQL injection: a
value such as an apostrophe inside a student's name cannot alter the
structure of the query, because the driver always sends parameter values as
data, never as part of the SQL text. It also removes the need to manually
escape quotes, and lets the database cache the query's execution plan since
its structure never changes between calls — only the bound values do.
- No rows:
queryStudents()simply returns an emptyObservableListwhen theResultSethas no rows, so theTableViewshows an empty (not broken) table. - Connection lifecycle: every method uses try-with-resources on the
Connection,PreparedStatement, andResultSet, so they are closed automatically even if an exception is thrown. - Database unavailable:
SQLExceptions are caught in the controllers and shown as an alert dialog instead of crashing the application.
- Java 11
- JavaFX 13 (Controls + FXML)
- MySQL 8+ (via
mysql-connector-j) - Maven
If you don't already have MySQL Server + Workbench installed, download them
from dev.mysql.com. Make a
note of the password you set for the root user.
Open MySQL Workbench (or the mysql command line) and run
schema.sql (File → Open SQL Script → Run). This will:
- Create the
gradetrackerDBdatabase. - Create the
studentstable. - Insert 4 sample rows (2 Pass, 2 Fail).
Open src/main/java/com/mycompany/gradetracker/DBConnection.java and update
the constants to match your setup:
private static final String URL = "jdbc:mysql://localhost:3306/gradetrackerDB?useSSL=false&serverTimezone=UTC";
private static final String USER = "root";
private static final String PASSWORD = "your_password_here"; // put your own MySQL password heremvn clean javafx:runmysql-connector-j is declared as a Maven dependency in pom.xml, so no
manual JAR setup is needed.
- Click + Add, fill in a name, subject, grade (e.g.
7), and a date, then Submit. - Go to the Pass screen — the new student should appear there.
- Open MySQL Workbench and run:
You'll see the new row there — proof that it was actually written to the database.
SELECT * FROM gradetrackerDB.students;
.
├── pom.xml
├── schema.sql
└── src/main
├── java/com/mycompany/gradetracker/
│ ├── App.java
│ ├── DBConnection.java
│ ├── StudentDAO.java
│ ├── Student.java
│ ├── PrimaryController.java
│ ├── AddController.java
│ ├── PassController.java
│ └── FailController.java
└── resources/com/mycompany/gradetracker/
├── primary.fxml
├── add.fxml
├── pass.fxml
└── fail.fxml
This app started as a refactor of an earlier "WatchTracker" project and grew in three stages: a JavaFX app with in-memory storage, a relational schema designed separately in Azure SQL, and finally this MySQL/JDBC integration (the part in this repository), which replaced the in-memory storage with real persistence.