ĐẠO

Có sẵn

Giới thiệu về ĐẠO

Khi làm việc với cơ sở dữ liệu thông qua JDBC hoặc thậm chí thông qua Hibernate, mã thường trở nên cồng kềnh hơn chúng ta mong muốn. Một truy vấn cơ sở dữ liệu thường chứa:

  • xác nhận dữ liệu
  • thiết lập thông số yêu cầu
  • Lựa chọn truy vấn HQL tùy thuộc vào tham số truy vấn
  • xây dựng truy vấn bằng cách sử dụng API tiêu chí
  • cài đặt bộ nhớ đệm
  • xử lý lỗi ban đầu, v.v.

Do đó, thông lệ chung là tạo các lớp đặc biệt để làm việc với cơ sở dữ liệu. Các lớp như vậy được gọi là DAO, Đối tượng truy cập dữ liệu. Nhiệm vụ của họ là che giấu tất cả sự phức tạp khi làm việc với cơ sở dữ liệu và cung cấp một giao diện đẹp và thuận tiện cho bên ngoài.

Ví dụ:

public class EmployeeDAO {

   public List<Employee> getEmployeeList(int from, int count) {
   	String hqlQuery = “from Employee;
   	Query<Employee> query = session.createQuery(hqlQuery, Employee.class);
   	query.setFirstResult(from);
   	query.setMaxResults(count);
   	return query.getResultList();
  }

	public int getEmployeeCount() {
	     String hqlQuery = “select count(*) from Employee;
     	Query<Integer> query = session.createQuery(hqlQuery, Integer.class);
     	return query.getSingleResult();
   }

	public Employee getEmployeeByUniqName(String name) {
	     String hqlQuery = “from Employee where name = :name”;
     	Query<Integer> query = session.createQuery(hqlQuery, Employee.class);
     	query.setParameterr(“name”, name);
     	return query.getSingleResult();
   }
}

Chúng tôi có một lớp EmployeeDAO , với sự trợ giúp của nó, chúng tôi có được các đối tượng thuộc loại Employee từ cơ sở dữ liệu. Bản thân lớp, mặc dù được nhồi nhét bằng các chú thích, nhưng không chứa các phương thức để lưu chính nó vào cơ sở dữ liệu.

Lợi ích của DAO

Có rất nhiều lợi thế cho phương pháp này:

Đầu tiên, chúng ta đã ẩn hoàn toàn công việc với cơ sở dữ liệu trong lớp DAO. Nếu trong tương lai bạn quyết định viết lại tất cả các truy vấn từ HQL sang API tiêu chí hoặc Truy vấn gốc, điều này sẽ không ảnh hưởng đến mã bên ngoài lớp này theo bất kỳ cách nào.

Thứ hai, bạn có thể làm phức tạp hành vi của các phương pháp này. Bạn có thể thêm bộ nhớ đệm, sự kiện, xác thực tham số. Tất cả điều này sẽ được ẩn khỏi mã bên ngoài.

Thứ ba, nếu bạn cần một phương pháp chưa tồn tại, bạn chỉ cần thêm nó vào đây. Ví dụ: tôi cần một phương thức sẽ trả về tất cả các tác vụ của người dùng đã hết hạn. Sau đó, tôi sẽ chỉ làm điều này:

public class EmployeeDAO {

   public List<Task> getExpiredTasks(int userId, int from, int count) {
   	String hqlQuery = “from Task where task.user.id = :id and deadline < curdate();
   	Query<Task> query = session.createQuery(hqlQuery, Task.class);
   	query.setFirstResult(from);
   	query.setMaxResults(count);
   	return query.getResultList();
  }

   public int getExpiredTasksCount(int userId) {
   	String hqlQuery = “select count(*) from Task where task.user.id = :id and deadline < curdate();
   	Query<Integer> query = session.createQuery(hqlQuery, Integer.class);
   	return query.getSingleResult();
  }
}

Tôi đã thêm hai phương thức vào lớp:

  • getExpiredTasksCount() - trả về số lượng nhiệm vụ đã hết hạn cho người dùng
  • getExpiredTasks() - trả về danh sách các tác vụ đã hết hạn cho người dùng

Tôi cần các phương pháp - tôi đã thêm chúng. Và tôi có thể sử dụng nó ngay lập tức. Tôi sẽ tối ưu hóa chúng sau.

Hơn nữa, các phương pháp này có thể được kiểm tra đơn vị trước khi viết lại và tối ưu hóa, vì vậy chúng tôi sẽ biết rằng công việc với cơ sở dữ liệu vẫn như cũ.

Phương pháp tiêu chuẩn

Rất thường xuyên, các lớp DAO có các phương thức giống nhau. Ví dụ:

T getById (id dài cuối cùng) Nhận một đối tượng theo id của nó
Danh sách<T> getItems (int từ, int đếm) Nhận danh sách các đối tượng trong một phạm vi nhất định
Danh sách<T> getAll () Nhận tất cả các đối tượng của một loại nhất định
int getCount () Tìm hiểu số lượng đối tượng
Lưu T (thực thể T cuối cùng) Lưu đối tượng vào cơ sở dữ liệu
Cập nhật T (thực thể T cuối cùng) Cập nhật đối tượng trong cơ sở dữ liệu
xóa void (thực thể T cuối cùng) Xóa một đối tượng khỏi cơ sở dữ liệu
hiệu xóaById (thực thể dài cuối cùng) Xóa đối tượng khỏi cơ sở dữ liệu theo id

Các phương thức này được tìm thấy trong hầu hết các lớp DAO trên thế giới. Bây giờ, nếu có một loại lớp DAO nào đó, thì với xác suất 90% nó sẽ có các phương thức như vậy.

Vâng, có thể có những người khác, nhưng cũng sẽ có những người khác. Vì nó rất tiện lợi. Và nó cho phép bạn không tương tác trực tiếp với cơ sở hoặc Hibernate.

Và nếu có những phương pháp giống hệt nhau, thì chúng cần gì? Đúng vậy, đặt nó trong lớp cơ sở.

Nó trông giống như thế này:

public abstract class AbstractHibernateDao<T > {
    private final Class<T> clazz;
    private SessionFactory sessionFactory;

    public AbstractHibernateDao(final Class<T> clazzToSet)   {
    	this.clazz = clazzToSet;
    }

    public T getById(final long id) {
    	return (T) getCurrentSession().get(clazz, id);
    }

    public List<T> getItems(int from, int count) {
    	Query query = getCurrentSession().createQuery(clazz , "from " + clazz.getName())
    	query.setFirstResult(offset);
    	query.setMaxResults(count);
  	  return query.singleResult();
    }

    public List<T> findAll() {
    	return getCurrentSession().createQuery(clazz, "from " + clazz.getName()).list();
    }

    public T create(final T entity) {
    	getCurrentSession().saveOrUpdate(entity);
    	return entity;
    }

    public T update(final T entity) {
    	return (T) getCurrentSession().merge(entity);
    }

    public void delete(final T entity) {
    	getCurrentSession().delete(entity);
    }

    public void deleteById(final long entityId) {
    	final T entity = getById(entityId);
    	delete(entity);
    }

    protected Session getCurrentSession() {
    	return sessionFactory.getCurrentSession();
    }
}

Và sau đó EmployeeDAO của chúng ta sẽ như thế này:

public class EmployeeDAO extends AbstractHibernateDAO<Employee> {

   public EmployeeDAO (){
  	super(Employee.class );
   }
}

TaskDAO là như thế này:

public class TaskDAO extends AbstractHibernateDAO<Task> {

   public TaskDAO (){
  	super(Task.class );
   }
}

Và cả hai lớp này sẽ có tất cả các phương thức mà chúng ta đã khai báo trên AbstractHibernateDAO . Thống nhất là rất thuận tiện và thiết thực.

Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào