جاوا و تکنولوژی های آن

java programming language

در این وبلاگ به بررسی نکات موجود در جاوا و تکنولوژی های آن می پردازیم

طبقه بندی موضوعی


در این بخش به ساده سازی ساخت لایه DAO با امکاناتی که در بخش قبلی توضیح داده شد و استفاده از Java Generics میپردازیم



DAO های Hibernate و  JPA :


معمولا در پروژه ها لایه DAO شامل از چندین پیاده سازی تشکیل شده است که abstract مشترک ندارند و بین Entity ها و DAO کلاس ها روابط one to one وجود دارد و باعث میشه کلی کد تکرار شده داشته باشیم که نگهداری و توسعه آتی را سخت خواهد کرد این پیاده سازی های متعدد میتواند در یک DAO با پارامتر های متنوع و کاربردی جایگزین شود 

این پیاده سازی واحد DAO میتواند بگونه ای طراحی شود که هیچگونه functionality ای را از دست ندهیم و تمام ویژگی هایی عملکردی را دارا باشد و این اطمینان را میتوان با استفاده از Java Generic بدست بیاوریم 


در ادامه ما دو نوع پیاده سازی یکی برای Hibernate و دیگری برای JPA را ارائه میدهیم تا با این روش آشنا شویم این دو نوع به هیچ وجه کامل نیستند اما ما میتوانیم متد هایی را برای کاملتر شدن بکار بگیریم




طراحی Abstract Hibernate DAO :


public abstract class AbstractHibernateDao<T extends Serializable> {
    private Class<T> clazz;
  
    @Autowired
    SessionFactory sessionFactory;
  
    public void setClazz(Class< T > clazzToSet){
       this.clazz = clazzToSet;
    }
  
    public T findOne(long id){
      return (T) getCurrentSession().get(clazz, id);
    }
 
    public List findAll() {
        return getCurrentSession().createQuery("from " + clazz.getName()).list();
    }
 
    public T create(T entity) {
        getCurrentSession().saveOrUpdate(entity);
        return entity;
    }
 
    public T update(T entity) {
        return (T) getCurrentSession().merge(entity);
    }
 
    public void delete(T entity) {
        getCurrentSession().delete(entity);
    }
 
    public void deleteById(long entityId) {
        T entity = findOne(entityId);
        delete(entity);
    }
 
    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}


در مثال بالا میتوانیم ببینیم که چطور با استفاده از SessionFactory متد های دسترسی به دیتای کاملتری را طراحی کرده ایم 




طراحی Hibernate Generic DAO :


بعد از طراحی Abstract Hibernate DAO نوبت طراحی Hibernate Generic DAO است که با استفاده از Java Generic طراحی میشود 


@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class GenericHibernateDao<T extends Serializable>
  extends AbstractHibernateDao<T> implements IGenericDao<T>{
   //
}


نکته اول این است که نوع پیاده سازی Generic خودش پارامتر بندی شده است که به استفاده کننده اجازه میدهد پارامتر دلخواه خود را انتخاب کند و این امکان را فراهم میکند که پیاده سازی های متعدد حذف شوند و مزایای type safe بودن را داشته باشیم 


نکته دوم این است که این Generic DAO دارای Scope@ از نوع Prototype است و این یعنی در هر بار درخواست نمونه جدیدی از آن ساخته میشود و این امکان را خواهیم داشت که در صورت لزوم چندین DAO با پارامتر های مختلف داشته باشیم 


دقت داشته باشید که DAO ها در قالب Bean در Spring استفاده میشوند و اگر Scope@ آنرا مشخص نکنیم آنرا Singleton در نظر میگیرد و در طول حیات Container یک نمونه از DAO خواهیم داشت



IGenericDao اینترفیسی است که دارای متد های مورد نیاز DAO است و در تمامی فرزندانی که از آن پیاده سازی کنند وجود خواهد داشت و ساختاری بدین شکل دارد :


public interface IGenericDao<T extends Serializable> {
 
   T findOne(final long id);
 
   List<T> findAll();
 
   void create(final T entity);
 
   T update(final T entity);
 
   void delete(final T entity);
 
   void deleteById(final long entityId);
}




حال ببینیم با استفاده از JPA طراحی DAO چگونه خواهد بود 


طراحی AbstractJpaDao از HibernateJpaDao بسیار ساده تر است :


public abstract class AbstractJpaDao< T extends Serializable > {
 
   private Class< T > clazz;
 
   @PersistenceContext
   EntityManager entityManager;
 
   public void setClazz( Class< T > clazzToSet ) {
      this.clazz = clazzToSet;
   }
 
   public T findOne( Long id ){
      return entityManager.find( clazz, id );
   }
   public List< T > findAll(){
      return entityManager.createQuery( "from " + clazz.getName() )
       .getResultList();
   }
 
   public void save( T entity ){
      entityManager.persist( entity );
   }
 
   public void update( T entity ){
      entityManager.merge( entity );
   }
 
   public void delete( T entity ){
      entityManager.remove( entity );
   }
   public void deleteById( Long entityId ){
      T entity = getById( entityId );
      delete( entity );
   }
}


مثل پیاده سازی  Hibernate Dao ما مستقیما از Java Persistence API استفاده کرده ایم بدون اینکه از JpaTemplate کمک بگیریم 




طراحی Jpa Generic Dao :


مشابه روش Hibernate 

@Repository
@Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericJpaDao< T extends Serializable >
 extends AbstractJpaDao< T > implements IGenericDao< T >{
   //
}




روش استفاده و تزریق DAO در برنامه :


تا اینجای طراحی ما یک اینترفیس DAO واحد داریم که از آن استفاده میکنیم و کلاس Entity را به آن معرفی میکنیم :


@Service
class FooService implements IFooService{
 
   IGenericDao<Foo> dao;
 
   @Autowired
   public void setDao(IGenericDao<Foo> daoToSet) {
      dao = daoToSet;
      dao.setClazz(Foo.class);
   }
 
   // ...
}


ما از تزریق نوع setter method استفاده کردیم که در این روش میتوانیم پارامتر های سفارشی خودمان را به آن اضافه کنیم 


* البته روش های دیگری وجود دارد که میتوان کلاس Entity را برای DAO مشخص کرد مانند Reflection یا حتی XML ولی بدلیل خوانایی بالاتر از  روش فوق در کد بالا استفاده شده است 









نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی