Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
133: JDBC Fundamentals
Alright, let's get into JDBC. I've got a local H2 database running for a small project I'm working onβa vinyl record inventory tracker. I've already got a table called records with columns for id, artist, album_title, and release_year. Now I need to actually get that data into my Java app.
Wait, how do I actually talk to the DB?
My first instinct is usually to just "connect," but Java doesn't just magically know where my database is or what language it speaks. I need a bridge. That's where the JDBC Driver comes in. Since I'm using H2, I've added the dependency to my project, but now I need to establish a Connection.
Connection conn = DriverManager.getConnection("jdbc:h2:mem:vinyl_db", "sa", "");
System.out.println("Connected!");
I tried running this, and it immediately complained about a SQLException. Java forces us to handle this because, in the real world, databases go down, passwords expire, or the network hiccups. I could wrap it in a try-catch, but there's a bigger problem here: if I just open a connection and leave it, I'm leaking resources. Eventually, the database will refuse new connections because I've left too many "ghost" sessions open. I'll use a try-with-resources block instead; it handles the closing for me automatically.
The "Empty" Result Set
Now that I'm connected, I want to see my records. I'll create a Statement and run a basic query. I'll try to just print the result directly to see what happens:
try (Connection conn = DriverManager.getConnection("jdbc:h2:mem:vinyl_db", "sa", "");
Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("SELECT * FROM records");
System.out.println(rs);
}
Of course, that didn't work. It printed something like org.h2.jdbc.ResultSet@4fca21. It's an object, not a list of strings. I remember the first time I did this; I expected a List or an Array. But JDBC uses a ResultSet, which is more like a cursor pointing to a row in the database.
Here is the tricky part: when the ResultSet is first returned, the cursor is positioned before the first row. If I try to call rs.getString("artist") immediately, it'll throw an error because I'm not actually pointing at a record yet.
Walking through the rows
To actually get the data, I have to call .next(). This moves the cursor forward one row and returns true if there's actually data there. If it hits the end of the table, it returns false. This makes a while loop the perfect tool for the job.
try (Connection conn = DriverManager.getConnection("jdbc:h2:mem:vinyl_db", "sa", "");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM records")) {
while (rs.next()) {
// Now the cursor is on a valid row
int id = rs.getInt("id");
String artist = rs.getString("artist");
String album = rs.getString("album_title");
int year = rs.getInt("release_year");
System.out.printf("ID: %d | %s - %s (%d)%n", id, artist, album, year);
}
} catch (SQLException e) {
e.printStackTrace();
}
This works. I'm manually mapping the database columns to Java variables. It's a bit tedious, and if I change a column name in the DB, this code breaks. In a larger project, I'd map these straight into a VinylRecord POJO, but for the fundamentals, this is the core loop of JDBC: Connect $\rightarrow$ Statement $\rightarrow$ ResultSet $\rightarrow$ Iterate.
A quick note on the "Statement"
I used a Statement here, which is fine for a hardcoded "SELECT * FROM records". But if I wanted to search for a specific artist using a variable, I'd be tempted to do something like "SELECT * FROM records WHERE artist = '" + userInput + "'". Please, don't do that. That's how you get hit with SQL Injection attacks. For anything involving variables, we'll use PreparedStatement, but we'll save that for the next lesson once you're comfortable with this basic flow.
π Practical Task
Exercise: Vinyl Collection Record Fetcher
You are tasked with writing a small utility class to verify the connection to a database. Your goal is to create a method that retrieves and prints all albums released after a specific year from a database.
Requirements:
- Create a class named
VinylDatabaseManager. - Implement a method
public void printRecentAlbums(int yearCutoff). - Use a try-with-resources block to manage the
Connection,Statement, andResultSet. - The SQL query should be:
"SELECT artist, album_title FROM records WHERE release_year > " + yearCutoff. - Inside the
while(rs.next())loop, print the artist and album title in the format:"Artist: [artist], Album: [album]". - Assume the connection string is
"jdbc:h2:mem:vinyl_db"with username"sa"and an empty password.
Note: Since you don't have a live H2 server running in this editor, focus on the correct JDBC syntax and resource management. Ensure your SQLException is handled via a try-catch block surrounding the resource block.
There are no comments for now.