Deploy a Java Movie Database to Heroku (Step-by-Step)

Java Movie Database Tutorial: CRUD App with JDBC and Swing

This tutorial walks through building a simple desktop CRUD (Create, Read, Update, Delete) movie database using Java, JDBC for database access, and Swing for the GUI. It assumes Java 11+ and a relational database (SQLite for simplicity). You’ll get a working app with a movies table, forms to add/edit movies, and a list view with delete functionality.

What you’ll build

  • SQLite database with a movies table
  • Data Access Object (DAO) using JDBC
  • Swing GUI: list of movies, add/edit form, delete action
  • Basic validation and exception handling

Project setup

  1. Create a Maven project (or plain Java project). Example Maven coordinates:

    • GroupId: com.example
    • ArtifactId: java-movie-db
    • Java version: 11+
  2. Add dependency for SQLite (if using Maven):

xml

<dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.42.0.0</version> </dependency>

Database schema (SQLite)

Create a file movies.db in the project root or let the app create it. SQL schema:

sql

CREATE TABLE IF NOT EXISTS movies ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, director TEXT, year INTEGER, genre TEXT, rating REAL );

Data model

Create a simple Movie class.

java

public class Movie { private int id; private String title; private String director; private Integer year; private String genre; private Double rating; // constructors, getters, setters, toString }

JDBC DAO

Create MovieDao with methods: initialize(), listAll(), findById(id), insert(movie), update(movie), delete(id). Example key methods:

java

import java.sql.*; import java.util.ArrayList; import java.util.List; public class MovieDao { private final String url = “jdbc:sqlite:movies.db”; public MovieDao() throws SQLException { initialize(); } public void initialize() throws SQLException { try (Connection conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement()) { String sql = “CREATE TABLE IF NOT EXISTS movies (” + “id INTEGER PRIMARY KEY AUTOINCREMENT,” + “title TEXT NOT NULL,” + “director TEXT,” + “year INTEGER,” + “genre TEXT,” + “rating REAL)”; stmt.execute(sql); } } public List<Movie> listAll() throws SQLException { List<Movie> list = new ArrayList<>(); String sql = “SELECT id, title, director, year, genre, rating FROM movies ORDER BY title”; try (Connection conn = DriverManager.getConnection(url); PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery()) { while (rs.next()) { Movie m = new Movie(); m.setId(rs.getInt(“id”)); m.setTitle(rs.getString(“title”)); m.setDirector(rs.getString(“director”)); int y = rs.getInt(“year”); m.setYear(rs.wasNull() ? null : y); m.setGenre(rs.getString(“genre”)); double r = rs.getDouble(“rating”); m.setRating(rs.wasNull() ? null : r); list.add(m); } } return list; } public Movie findById(int id) throws SQLException { String sql = “SELECT id, title, director, year, genre, rating FROM movies WHERE>; try (Connection conn = DriverManager.getConnection(url); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, id); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { Movie m = new Movie(); m.setId(rs.getInt(“id”)); m.setTitle(rs.getString(“title”)); m.setDirector(rs.getString(“director”)); int y = rs.getInt(“year”); m.setYear(rs.wasNull() ? null : y); m.setGenre(rs.getString(“genre”)); double r = rs.getDouble(“rating”); m.setRating(rs.wasNull() ? null : r); return m; } } } return null; } public void insert(Movie m) throws SQLException { String sql = “INSERT INTO movies(title,director,year,genre,rating) VALUES(?,?,?,?,?)”; try (Connection conn = DriverManager.getConnection(url); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, m.getTitle()); ps.setString(2, m.getDirector()); if (m.getYear() == null) ps.setNull(3, Types.INTEGER); else ps.setInt(3, m.getYear()); ps.setString(4, m.getGenre()); if (m.getRating() == null) ps.setNull(5, Types.REAL); else ps.setDouble(5, m.getRating()); ps.executeUpdate(); } } public void update(Movie m) throws SQLException { String sql = “UPDATE movies SET title=?, director=?, year=?, genre=?, rating=? WHERE>; try (Connection conn = DriverManager.getConnection(url); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, m.getTitle()); ps.setString(2, m.getDirector()); if (m.getYear() == null) ps.setNull(3, Types.INTEGER); else ps.setInt(3, m.getYear()); ps.setString(4, m.getGenre()); if (m.getRating() == null) ps.setNull(5, Types.REAL); else ps.setDouble(5, m.getRating()); ps.setInt(6, m.getId()); ps.executeUpdate(); } } public void delete(int id) throws SQLException { String sql = “DELETE FROM movies WHERE>; try (Connection conn = DriverManager.getConnection(url); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, id); ps.executeUpdate(); } } }

Swing GUI

Create a main frame with:

  • JTable to list movies (backed by AbstractTableModel)
  • Buttons: Add, Edit, Delete, Refresh
  • Modal dialog for Add/Edit with input fields: title, director, year, genre, rating

Key parts:

  • MovieTableModel extending AbstractTableModel to wrap List.
  • MainFrame: loads list via MovieDao.listAll(), sets table model, wires button actions.
  • Add/Edit Dialog: validates title required, year numeric (optional), rating between 0–10 (optional).

Example MovieTableModel skeleton:

java

public class MovieTableModel extends AbstractTableModel { private final List<Movie> movies; private final String[] cols = {“ID”,“Title”,“Director”,“Year”,“Genre”,“Rating”}; public MovieTableModel(List<Movie> movies) { this.movies = movies; } public int getRowCount() { return movies.size(); } public int getColumnCount() { return cols.length; } public String getColumnName(int c) { return cols[c]; } public Object getValueAt(int r, int c) { Movie m = movies.get(r); switch(c) { case 0: return m.getId(); case 1: return m.getTitle(); case 2: return m.getDirector(); case 3: return m.getYear(); case 4: return m.getGenre(); case 5: return m.getRating(); default: return null; } } public Movie getMovieAt(int row) { return movies.get(row); } }

MainFrame action examples:

  • Add: open dialog, on OK call dao.insert(movie), refresh table.
  • Edit: get selected row, open dialog populated, on OK call dao.update(movie), refresh.
  • Delete: confirm, dao.delete(id), refresh.
  • Refresh: reload list from dao and update model.

Simple Add/Edit dialog example

Use JDialog with JTextFields and JButtons. On OK parse and validate inputs, construct Movie, close and return.

Validation rules

  • Title required (non-empty)
  • Year optional; if provided must be integer between 1888 and current year (2026)
  • Rating optional; if provided must be number 0.0–10.0

Error handling

  • Show JOptionPane dialogs for SQL errors or validation failures.
  • Use try-with-resources for JDBC.
  • Keep UI responsive: for longer ops consider SwingWorker.

How to run

  • Build with Maven: mvn package
  • Run: java -cp target/java-movie-db.jar;path/to/sqlite-jdbc.jar com.example.MainFrame (Adjust classpath for your environment.)

Next steps / enhancements

  • Use H2 or PostgreSQL for production.
  • Add search/filtering, sorting, pagination.
  • Replace Swing with JavaFX or convert to a REST API + web frontend.
  • Add unit tests for DAO.

This provides the essentials to implement a CRUD Java Movie Database with JDBC and Swing. Use the provided DAO and table model patterns to complete the UI and behavior.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *