Write a Java program that establishes a connection to a PostgreSQL database, performs CRUD operations on a table named "employees", and closes the connection. Use prepared statements and handle exceptions properly.
PLAINFORMAT
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class EmployeeDatabase {

    private static final String URL = "jdbc:postgresql://localhost:5432/your_database_name";
    private static final String USER = "your_username";
    private static final String PASSWORD = "your_password";

    public static void main(String[] args) {
        EmployeeDatabase employeeDatabase = new EmployeeDatabase();
        try {
            Connection connection = employeeDatabase.connect();

            // Perform CRUD operations here
            int id = 1;
            String name = "John Doe";
            double salary = 50000;

            employeeDatabase.createEmployee(connection, id, name, salary);
            employeeDatabase.readEmployee(connection, id);
            employeeDatabase.updateEmployee(connection, id, 60000);
            employeeDatabase.deleteEmployee(connection, id);

            employeeDatabase.closeConnection(connection);
        } catch (SQLException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    public Connection connect() throws SQLException {
        return DriverManager.getConnection(URL, USER, PASSWORD);
    }

    public void createEmployee(Connection connection, int id, String name, double salary) throws SQLException {
        String sql = "INSERT INTO employees(id, name, salary) VALUES(?, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, id);
        preparedStatement.setString(2, name);
        preparedStatement.setDouble(3, salary);

        int rowsAffected = preparedStatement.executeUpdate();
        System.out.println(rowsAffected + " row(s) inserted.");
    }

    public void readEmployee(Connection connection, int id) throws SQLException {
        String sql = "SELECT * FROM employees WHERE id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, id);

        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.println("ID: " + resultSet.getInt("id"));
            System.out.println("Name: " + resultSet.getString("name"));
            System.out.println("Salary: " + resultSet.getDouble("salary"));
        }
    }

    public void updateEmployee(Connection connection, int id, double newSalary) throws SQLException {
        String sql = "UPDATE employees SET salary = ? WHERE id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setDouble(1, newSalary);
        preparedStatement.setInt(2, id);

        int rowsAffected = preparedStatement.executeUpdate();
        System.out.println(rowsAffected + " row(s) updated.");
    }

    public void deleteEmployee(Connection connection, int id) throws SQLException {
        String sql = "DELETE FROM employees WHERE id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, id);

        int rowsAffected = preparedStatement.executeUpdate();
        System.out.println(rowsAffected + " row(s) deleted.");
    }

    public void closeConnection(Connection connection) throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
    }
}