Java và MySQL – Mô hình DAO

Trong Java, mô hình Đạo (DAO – Data Access Object) là một thiết kế phổ biến để quản lý việc truy cập dữ liệu từ một nguồn dữ liệu (ví dụ như cơ sở dữ liệu). DAO tách rời lớp logic nghiệp vụ khỏi lớp tương tác trực tiếp với cơ sở dữ liệu, giúp mã nguồn dễ bảo trì và thay đổi.

1. Cấu trúc của mô hình DAO

Mô hình DAO thường bao gồm các thành phần sau:

  • Entity (hoặc Model): Lớp đại diện cho các bảng trong cơ sở dữ liệu. Mỗi đối tượng trong lớp này tương ứng với một hàng trong bảng.
  • DAO Interface: Định nghĩa các phương thức để tương tác với dữ liệu (CRUD – Create, Read, Update, Delete).
  • DAO Implementation: Triển khai các phương thức đã định nghĩa trong DAO Interface để thực hiện các thao tác trên cơ sở dữ liệu.
  • Service (Tùy chọn): Một lớp trung gian giữa DAO và lớp logic nghiệp vụ, giúp quản lý nghiệp vụ phức tạp hơn.

2. Ví dụ về mô hình DAO trong Java

2.1 Entity (Model)

Giả sử bạn có một bảng User trong cơ sở dữ liệu với các cột: id, name, và email.

public class User {
    private int id;
    private String name;
    private String email;

    // Getters and Setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

2.2 DAO Interface

Interface định nghĩa các phương thức CRUD.

import java.util.List;

public interface UserDAO {
    void addUser(User user);
    User getUser(int id);
    List<User> getAllUsers();
    void updateUser(User user);
    void deleteUser(int id);
}

2.3 DAO Implementation

Triển khai các phương thức của interface UserDAO.

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class UserDAOImpl implements UserDAO {

    private Connection connection;

    public UserDAOImpl(Connection connection) {
        this.connection = connection;
    }

    @Override
    public void addUser(User user) {
        String sql = "INSERT INTO User (name, email) VALUES (?, ?)";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setString(1, user.getName());
            statement.setString(2, user.getEmail());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public User getUser(int id) {
        User user = null;
        String sql = "SELECT * FROM User WHERE id = ?";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setInt(1, id);
            ResultSet resultSet = statement.executeQuery();
            if (resultSet.next()) {
                user = new User();
                user.setId(resultSet.getInt("id"));
                user.setName(resultSet.getString("name"));
                user.setEmail(resultSet.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return user;
    }

    @Override
    public List<User> getAllUsers() {
        List<User> users = new ArrayList<>();
        String sql = "SELECT * FROM User";
        try (Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sql)) {
            while (resultSet.next()) {
                User user = new User();
                user.setId(resultSet.getInt("id"));
                user.setName(resultSet.getString("name"));
                user.setEmail(resultSet.getString("email"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }

    @Override
    public void updateUser(User user) {
        String sql = "UPDATE User SET name = ?, email = ? WHERE id = ?";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setString(1, user.getName());
            statement.setString(2, user.getEmail());
            statement.setInt(3, user.getId());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteUser(int id) {
        String sql = "DELETE FROM User WHERE id = ?";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setInt(1, id);
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2.4 Sử dụng DAO trong Service hoặc Main

Bạn có thể sử dụng DAO trong lớp Service hoặc trực tiếp trong phương thức main.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        Connection connection = null;

        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");

            UserDAO userDAO = new UserDAOImpl(connection);

            // Tạo người dùng mới
            User newUser = new User();
            newUser.setName("John Doe");
            newUser.setEmail("[email protected]");
            userDAO.addUser(newUser);

            // Lấy thông tin người dùng
            User user = userDAO.getUser(1);
            System.out.println("User: " + user.getName() + ", " + user.getEmail());

            // Cập nhật thông tin người dùng
            user.setName("Jane Doe");
            userDAO.updateUser(user);

            // Xóa người dùng
            userDAO.deleteUser(2);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3. Lợi ích của mô hình DAO

  • Tách biệt: Tách rời logic truy xuất dữ liệu khỏi logic nghiệp vụ.
  • Dễ bảo trì: Dễ dàng thay đổi nguồn dữ liệu mà không ảnh hưởng đến các phần khác của ứng dụng.
  • Tái sử dụng: DAO có thể được sử dụng lại ở nhiều nơi trong ứng dụng.

Nếu bạn có thêm câu hỏi hoặc cần hỗ trợ về cách triển khai cụ thể, hãy cho tôi biết!