Pengenalan kepada DAO
Apabila bekerja dengan pangkalan data melalui JDBC atau bahkan melalui Hibernate, kod itu sering menjadi lebih rumit daripada yang kita mahukan. Pertanyaan pangkalan data selalunya mengandungi:
- pengesahan data
- menetapkan parameter permintaan
- Pemilihan pertanyaan HQL bergantung pada parameter pertanyaan
- membina pertanyaan menggunakan API Kriteria
- tetapan caching
- pengendalian ralat awal, dsb.
Oleh itu, amalan biasa adalah untuk mencipta kelas khas untuk bekerja dengan pangkalan data. Kelas sedemikian dipanggil DAO, Objek Akses Data. Tugas mereka adalah untuk menyembunyikan semua kerumitan bekerja dengan pangkalan data dan menyediakan antara muka yang cantik dan mudah 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 mempunyai kelas EmployeeDAO , dengan bantuannya kami mendapatkan objek jenis Employee daripada pangkalan data. Kelas itu sendiri, walaupun diisi dengan anotasi, tidak mengandungi kaedah untuk menyimpan dirinya ke pangkalan data.
Kebaikan DAO
Terdapat banyak kelebihan untuk pendekatan ini:
Pertama, kami telah menyembunyikan sepenuhnya kerja dengan pangkalan data dalam kelas DAO. Jika anda memutuskan pada masa hadapan untuk menulis semula semua pertanyaan daripada HQL kepada API Kriteria atau Native Query, ini tidak akan menjejaskan kod di luar kelas ini dalam apa jua cara.
Kedua, anda boleh merumitkan tingkah laku kaedah ini. Anda boleh menambah caching, peristiwa, pengesahan parameter. Ini semua akan disembunyikan daripada kod luar.
Ketiga, jika anda memerlukan kaedah yang belum wujud, anda hanya menambahnya di sini. Sebagai contoh, saya memerlukan kaedah yang akan mengembalikan semua tugas pengguna yang telah tamat tempoh. Kemudian 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 menambah dua kaedah ke kelas:
- getExpiredTasksCount() - mengembalikan bilangan tugasan yang telah tamat tempoh untuk pengguna
- getExpiredTasks() - mengembalikan senarai tugasan yang telah tamat tempoh untuk pengguna
Saya memerlukan kaedah - saya menambahnya. Dan saya boleh menggunakannya dengan segera. Saya akan mengoptimumkannya kemudian.
Selain itu, kaedah ini boleh diliputi dengan ujian unit sebelum menulis semula dan pengoptimuman, jadi kita akan tahu bahawa kerja dengan pangkalan data kekal sama seperti dahulu.
Pendekatan Standard
Selalunya, kelas DAO mempunyai kaedah yang sama. Sebagai contoh, ini:
T getById (id panjang akhir) | Dapatkan objek dengan idnya |
Senaraikan<T> getItems (int from, int count) | Dapatkan senarai objek dalam julat tertentu |
Senarai<T> getAll () | Dapatkan semua objek daripada jenis tertentu |
int getCount () | Ketahui bilangan objek |
T simpan (entiti T akhir) | Simpan objek ke pangkalan data |
Kemas kini T (entiti T akhir) | Kemas kini objek dalam pangkalan data |
batal padam (entiti T akhir) | Padam objek daripada pangkalan data |
void deleteById (entiti panjang akhir) | Padam objek daripada pangkalan data dengan id |
Kaedah ini terdapat dalam hampir setiap kelas DAO di dunia. Sekarang, jika terdapat beberapa jenis kelas DAO, maka dengan kebarangkalian 90% ia akan mempunyai kaedah sedemikian.
Ya, mungkin ada yang lain, tetapi akan ada juga. Kerana ia sangat mudah. Dan ia membolehkan anda tidak berinteraksi dengan pangkalan atau Hibernate secara langsung.
Dan jika terdapat kaedah yang sama, maka apa yang mereka perlukan? Betul, letak dalam kelas asas.
Ia kelihatan 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 kami akan kelihatan seperti ini:
public class EmployeeDAO extends AbstractHibernateDAO<Employee> {
public EmployeeDAO (){
super(Employee.class );
}
}
Dan TaskDAO adalah seperti ini:
public class TaskDAO extends AbstractHibernateDAO<Task> {
public TaskDAO (){
super(Task.class );
}
}
Dan kedua-dua kelas ini akan mempunyai semua kaedah yang kami isytiharkan pada AbstractHibernateDAO . Penyatuan adalah sangat mudah dan praktikal.
GO TO FULL VERSION