Pambuka kanggo DAO

Nalika nggarap database liwat JDBC utawa malah liwat Hibernate, kode kasebut asring dadi luwih rumit tinimbang sing dikarepake. Pitakonan database asring ngemot:

  • validasi data
  • setelan paramèter request
  • Pilihan query HQL gumantung saka parameter query
  • mbangun pitakon nggunakake API Kriteria
  • setelan caching
  • nangani kesalahan dhisikan, etc.

Mulane, praktik umum yaiku nggawe kelas khusus kanggo nggarap database. Kelas kasebut diarani DAO, Obyek Akses Data. Tugase yaiku ndhelikake kabeh kerumitan nggarap database lan nyedhiyakake antarmuka sing apik lan trep ing njaba.

Tuladha:

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

Kita duwe kelas EmployeeDAO , kanthi bantuan kita entuk obyek saka jinis Employee saka database. Kelas kasebut, sanajan diisi karo anotasi, ora ngemot cara kanggo nyimpen dhewe menyang database.

Keuntungan saka DAO

Ana akeh kaluwihan kanggo pendekatan iki:

Pisanan, kita wis rampung ndhelikake karya karo database ing kelas DAO. Yen sampeyan mutusake kanggo nulis ulang kabeh pitakon saka HQL menyang API Kriteria utawa Native Query, iki ora bakal mengaruhi kode ing njaba kelas iki kanthi cara apa wae.

Kapindho, sampeyan bisa nggawe rumit prilaku metode kasebut. Sampeyan bisa nambah cache, acara, validasi parameter. Iki kabeh bakal didhelikake saka kode njaba.

Katelu, yen sampeyan butuh cara sing durung ana, sampeyan mung nambahake ing kene. Contone, aku butuh cara sing bakal ngasilake kabeh tugas pangguna sing wis kadaluwarsa. Banjur aku mung bakal nindakake iki:

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

Aku nambahake rong cara ing kelas:

  • getExpiredTasksCount () - ngasilake jumlah tugas kadaluwarsa kanggo pangguna
  • getExpiredTasks () - ngasilake dhaptar tugas sing kadaluwarsa kanggo pangguna

Aku butuh cara - aku nambahake. Lan aku bisa langsung nggunakake. Aku bakal ngoptimalake mengko.

Menapa malih, cara-cara kasebut bisa ditutupi karo tes unit sadurunge nulis ulang lan optimasi, supaya kita bakal ngerti yen karya karo database tetep padha.

Pendekatan Standar

Kerep banget, kelas DAO duwe metode sing padha. Contone, iki:

T getById (id long final) Entuk obyek kanthi id
Dhaptar<T> getItems (int from, int count) Entuk dhaptar obyek ing kisaran tartamtu
Daftar<T> getAll () Entuk kabeh obyek saka jinis tartamtu
int getCount () Temokake jumlah obyek
T nyimpen (entitas T pungkasan) Simpen obyek menyang database
T nganyari (entitas T pungkasan) Nganyari obyek ing database
void delete (entitas T pungkasan) Mbusak obyek saka database
void deleteById (final long entityId) Mbusak obyek saka database kanthi id

Cara iki ditemokake ing meh kabeh kelas DAO ing donya. Saiki, yen ana sawetara kelas DAO, banjur kanthi kemungkinan 90% bakal duwe metode kasebut.

Ya, bisa uga ana liyane, nanging uga bakal ana. Amarga trep banget. Lan ngidini sampeyan ora sesambungan karo basa utawa Hibernate langsung.

Lan yen ana cara sing padha, banjur apa sing dibutuhake? Sing bener, sijine ing kelas dhasar.

Iku katon kaya iki:

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

Banjur EmployeeDAO kita bakal katon kaya iki:

public class EmployeeDAO extends AbstractHibernateDAO<Employee> {

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

Lan TaskDAO kaya iki:

public class TaskDAO extends AbstractHibernateDAO<Task> {

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

Lan loro kelas kasebut bakal duwe kabeh metode sing diumumake ing AbstractHibernateDAO . Unifikasi trep banget lan praktis.