Pengantar DAO

Saat bekerja dengan database melalui JDBC atau bahkan melalui Hibernasi, kode sering kali ternyata lebih rumit daripada yang kita inginkan. Kueri basis data sering berisi:

  • validasi data
  • mengatur parameter permintaan
  • Pemilihan kueri HQL bergantung pada parameter kueri
  • membuat kueri menggunakan Criteria API
  • pengaturan cache
  • penanganan kesalahan awal, dll.

Oleh karena itu, praktik umum adalah membuat kelas khusus untuk bekerja dengan database. Kelas semacam itu disebut DAO, Objek Akses Data. Tugas mereka adalah menyembunyikan semua kerumitan dalam bekerja dengan database dan menyediakan antarmuka yang indah dan nyaman ke luar.

Contoh:

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();
   }
}

Kami memiliki kelas EmployeeDAO , yang dengannya kami mendapatkan objek bertipe Employee dari database. Kelas itu sendiri, meskipun diisi dengan anotasi, tidak berisi metode untuk menyimpan dirinya sendiri ke database.

Manfaat DAO

Ada banyak keuntungan dari pendekatan ini:

Pertama, kami telah sepenuhnya menyembunyikan pekerjaan dengan database di kelas DAO. Jika Anda memutuskan di masa mendatang untuk menulis ulang semua kueri dari HQL ke Criteria API atau Native Query, ini tidak akan memengaruhi kode di luar kelas ini dengan cara apa pun.

Kedua, Anda dapat memperumit perilaku metode ini. Anda dapat menambahkan caching, event, validasi parameter. Ini semua akan disembunyikan dari kode luar.

Ketiga, jika Anda membutuhkan metode yang belum ada, tambahkan saja di sini. Misalnya, saya memerlukan metode yang akan mengembalikan semua tugas pengguna yang telah kedaluwarsa. Maka saya hanya akan melakukan ini:

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();
  }
}

Saya menambahkan dua metode ke kelas:

  • getExpiredTasksCount() - mengembalikan jumlah tugas kedaluwarsa untuk pengguna
  • getExpiredTasks() - mengembalikan daftar tugas kedaluwarsa untuk pengguna

Saya perlu metode - saya menambahkannya. Dan bisa langsung saya pakai. Saya akan mengoptimalkannya nanti.

Selain itu, metode ini dapat ditutup dengan pengujian unit sebelum penulisan ulang dan pengoptimalan, sehingga kita akan mengetahui bahwa pekerjaan dengan database tetap sama seperti sebelumnya.

Pendekatan Standar

Sangat sering, kelas DAO memiliki metode yang sama. Misalnya, ini:

T getById (id panjang terakhir) Dapatkan objek dengan id-nya
Daftar<T> getItems (int dari, hitungan int) Dapatkan daftar objek dalam rentang tertentu
Daftar<T> getAll () Dapatkan semua objek dari tipe tertentu
int getCount () Cari tahu jumlah objek
T simpan (entitas T akhir) Simpan objek ke database
Pembaruan T (entitas T akhir) Perbarui objek dalam database
batal hapus (entitas T terakhir) Hapus objek dari database
batal deleteById (entitasId panjang terakhir) Hapus objek dari database dengan id

Metode ini ditemukan di hampir setiap kelas DAO di dunia. Sekarang, jika ada semacam kelas DAO, maka dengan probabilitas 90% akan ada metode seperti itu.

Ya, mungkin ada yang lain, tapi akan ada juga. Karena itu sangat nyaman. Dan itu memungkinkan Anda untuk tidak berinteraksi dengan basis atau Hibernasi secara langsung.

Dan jika ada metode yang identik, lalu apa yang mereka butuhkan? Itu benar, letakkan di kelas dasar.

Ini terlihat seperti ini:

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();
    }
}

Dan kemudian EmployeeDAO kita akan terlihat seperti ini:

public class EmployeeDAO extends AbstractHibernateDAO<Employee> {

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

Dan TaskDAO seperti ini:

public class TaskDAO extends AbstractHibernateDAO<Task> {

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

Dan kedua kelas ini akan memiliki semua metode yang kami nyatakan di AbstractHibernateDAO . Unifikasi sangat nyaman dan praktis.