Lab: Building a User Management System with a Database
Objective
By the end of this lab, you will:
1. Create a `DBAccess` class to manage database connections and operations.
2. Refactor the `Users` class to use `DBAccess` for database interactions.
3. Integrate the database with a forms application for user registration and login.
Step 1: Set Up the Database
1. Open your H2 database console or use the provided configuration.
2. Create a `Users` table using the following SQL:
CREATE TABLE IF NOT EXISTS Users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
3. Record your database URL, username, and password. These will be used to connect your
application to the database.
Step 2: Create the DBAccess Class
**Goal**: Create a class to manage database connections and basic operations.
1. Define a `DBAccess` class with:
- A private static instance (`DBAccess`): ensures only one database connection is created.
- A private constructor: sets up the connection to the database.
- A `getInstance()` method: returns the single instance of `DBAccess`.
public class DBAccess {
private static DBAccess instance;
private Connection connection;
private DBAccess() {
String jdbcURL = "jdbc:h2:~/mydatabase";
String username = "sa";
String password = "";
try {
connection = DriverManager.getConnection(jdbcURL,
username, password);
System.out.println("Database connection
established.");
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("Failed to connect to the
database");
}
}
public static DBAccess getInstance() {
if (instance == null) {
instance = new DBAccess();
}
return instance;
}
public Connection getConnection() {
return connection;
}
}
2. Test your `DBAccess` class by calling `DBAccess.getInstance()` in a simple test.
Step 3: Add User Insertion Logic
**Goal**: Add a method to insert new users into the database.
1. Add a `public boolean insertUser(User user)` method to `DBAccess`.
2. Use a `PreparedStatement` to insert values into the `Users` table. The SQL should look like
this:
INSERT INTO Users (username, email, password) VALUES (?, ?, ?);
3. Set the placeholders (`?`) using values from the `User` object:
- `user.getFirstName()` + " " + `user.getLastName()` for the username.
- `user.getEmail()` for the email.
- `user.getPassword()` for the password.
4. Handle exceptions to check for duplicate email errors (unique constraint violations).
Step 4: Add Email Validation
**Goal**: Ensure no two users have the same email.
1. Add a `public boolean isEmailUnique(String email)` method in `DBAccess`.
2. Write a query to check if an email exists in the database:
SELECT COUNT(*) FROM Users WHERE email = ?;
3. Use a `PreparedStatement` to set the `?` placeholder to the email address provided. Then
execute the query and get the result using a `ResultSet`.
4. Check if the result is `0` (email is unique) or greater than `0` (email already exists). Return
`true` for unique emails and `false` otherwise.
**Hint**: Here's how you can use `ResultSet` to get the count:
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
return count == 0;
}
Step 5: Refactor the Users Class
**Goal**: Use `DBAccess` to delegate database tasks and keep validation logic in `Users`.
1. Update the `addUser` method to:
- Call `DBAccess.isEmailUnique()` to check if the email is already in use.
- Call `DBAccess.insertUser()` to add the user to the database if validation passes.
2. Ensure that `Users` still handles password validation (e.g., checking for strength).
public boolean addUser(User user) {
DBAccess dbAccess = DBAccess.getInstance();
if (!dbAccess.isEmailUnique(user.getEmail())) {
System.out.println("Email is already in use.");
return false;
}
if (!isPasswordStrong(user.getPassword())) {
System.out.println("Password is not strong enough.");
return false;
}
return dbAccess.insertUser(user);
}
private boolean isPasswordStrong(String password) {
return password.length() >= 8 && password.matches(".*[A-
Z].*") && password.matches(".*[0-9].*");
}
3. Test this method by creating a `Users` object and calling `addUser` with various `User` objects.
Step 6: Integrate with the Forms Application
**Goal**: Connect the database logic with your forms for user registration and login.
1. In your registration form:
- Collect user input for first name, last name, email, and password.
- Create a `User` object with the input data.
- Call the `addUser()` method from the `Users` class to register the user.
2. In your login form:
- Collect user input for email and password.
- Add a `validateLogin(String email, String password)` method to `DBAccess`.
- Use this method to verify the user's credentials.
public boolean validateLogin(String email, String password) {
String sql = "SELECT COUNT(*) FROM Users WHERE email = ? AND
password = ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sql)) {
pstmt.setString(1, email);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
return rs.next() && rs.getInt(1) > 0;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
3. Show messages on the form based on success or failure (e.g., 'Registration successful!' or
'Invalid email or password').
Step 7: Test the Complete Application
**Goal**: Test your forms with different scenarios to ensure everything works as expected.
1. Test registration with:
- A valid user.
- A user with a duplicate email.
- A user with a weak password.
2. Test login with:
- Correct credentials.
- Incorrect email or password.
3. Verify that the database updates correctly after each test.
- Use the H2 console or a database viewer to check the `Users` table.
Step 7: Test the Complete Application (with Hints)
**Goal**: Test your forms with different scenarios to ensure everything works as expected.
1. Test registration with the following scenarios:
- A valid user: Ensure the user is added to the database.
- A duplicate email: Try registering the same email again and confirm that the application
prevents it.
- A weak password: Test with passwords that fail your strength checks.
**Hint for Testing Registration**:
- Use your form's input fields to enter details and observe the messages displayed (e.g., 'Email
already exists').
- Open the H2 database console and run a query to verify the data: