- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
Guided: Lightweight Data Persistence with JDBC and Records
In this Code Lab, you'll apply modern Java SE practices to implement a data access layer with JDBC. You will use Java Records as data carriers and interact with an H2 relational database using a clean, testable architecture.
Lab Info
Table of Contents
-
Challenge
Introduction
Welcome to this Code Lab on lightweight data persistence with JDBC and Java Records! While Object-Relational Mapping (ORM) frameworks like Hibernate are powerful, they can sometimes be overkill for simpler applications. Understanding how to use JDBC directly is a fundamental skill for any Java developer.
In this lab, you'll learn modern JDBC techniques, including using
try-with-resourcesfor safe resource management,PreparedStatementto prevent SQL injection, and Java Records for creating clean, immutable Data Transfer Objects (DTOs).The Scenario
You'll build the data access layer for a simple product catalog application. You are provided with a basic Maven project structure. Your job is to implement the
ProductDao(Data Access Object) to perform Create, Read, Update, and Delete (CRUD) operations against an in-memory H2 database. info> If you get stuck on a task, there are complete code solutions for each task located in thesolutionfolder. >This lab experience was developed by the Pluralsight team using Forge, an internally developed AI tool utilizing Gemini technology. All sections were verified by human experts for accuracy prior to publication. For issue reporting, please contact us. -
Challenge
Step 2: Defining the Data Model
Before you interact with the database, you need a way to represent your data in Java. Traditionally, this was done with verbose JavaBean classes. With modern Java, you can use Records.
What are Records?
Introduced in Java 16, a
recordis a special kind of class designed to be a transparent, immutable data carrier. When you declare a record, the Java compiler automatically generates:- A canonical constructor (taking all components as arguments).
publicaccessor methods for each component (e.g.,product.name()).- Implementations of
equals(),hashCode(), andtoString().
This makes them perfect for representing data retrieved from a database.
-
Challenge
Step 3: Connecting to the Database
The foundation of any JDBC application is the
Connection. AConnectionrepresents a session with the database. It's best practice to centralize the logic for creating these connections.You will use the H2 database engine in its in-memory mode. This is extremely convenient for development and testing because the database exists only as long as the application is running, and it requires no external setup.
You will also create a utility to set up our database schema (the tables and their structure) when the application starts.
-
Challenge
Step 4: Creating and Reading Data (CRUD)
Now that you can connect to the database and have a table, you can start implementing your CRUD operations in the
ProductDaoclass. Begin with 'Read' and 'Create'.Key JDBC Concepts
PreparedStatement: This is the preferred way to execute parameterized SQL queries. It pre-compiles the SQL and allows you to safely bind values to parameters, which is your primary defense against SQL injection attacks.ResultSet: When you execute a query that returns data (likeSELECT), the results are contained in aResultSetobject. You can iterate through it to access each row and retrieve column values by name or index.try-with-resources: This Java feature is essential for working with JDBC. Resources likeConnection,Statement, andResultSetmust be closed to prevent resource leaks. Atry-with-resourcesblock automatically closes any resource declared within it, whether the block completes normally or throws an exception.
-
Challenge
Step 5: Updating and Deleting Data (CRUD)
To complete the set of core database operations, you will now implement the 'Update' and 'Delete' functionality. The principles are very similar to what you've already done. You'll use a
PreparedStatementto execute a DML (Data Manipulation Language) command and check the return value to see how many rows were affected. -
Challenge
Step 6: Handling Transactions
By default, JDBC connections operate in
auto-commitmode. This means every single SQL statement (INSERT,UPDATE,DELETE) is immediately committed as its own transaction. This is simple, but often not what you want.Imagine you need to update the prices of ten products. If the fifth update fails due to a database error, the first four updates are already permanent. This leaves your data in an inconsistent state.
Transactions solve this. By disabling auto-commit, you can group a series of statements. They all succeed together (
commit), or they all fail together (rollback), ensuring your data remains consistent. This is often referred to as atomicity. ### Running the ApplicationTo run the main application and see the example CRUD operations in action:
./run.shOr you can use Maven directly:
mvn compile exec:javaThis will:
- Initialize the in-memory H2 database with the products table
- Create sample products (Laptop and Smartphone)
- Display all products
- Find a product by ID
- Update a product's price
- Delete a product
- Display the final state of all products
-
Challenge
Summary
Congratulations on completing this Code Lab!
To summarize here's what you've learned:
Java Records
You learned how to use Java Records as clean, immutable data carriers, replacing verbose JavaBean classes with concise, compiler-generated code.
JDBC Fundamentals
You mastered the fundamentals of JDBC, including:
- Establishing database connections
- Executing parameterized queries with
PreparedStatementto prevent SQL injection - Processing
ResultSetobjects to map database rows to Java objects
CRUD Operations
You implemented a complete CRUD (Create, Read, Update, Delete) data access layer, learning how to:
- Insert records with auto-generated keys
- Query single and multiple records
- Update existing data
- Delete records
Transaction Management
Most importantly, you discovered how to manage transactions to ensure data integrity, grouping multiple database operations into atomic units that either all succeed or all fail together.
Resource Management Best Practices
By using
try-with-resourcesthroughout, you also learned best practices for resource management, ensuring that database connections, statements, and result sets are properly closed even when exceptions occur.
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.