2012-08-23 54 views
1

我一直试图在hibernate中完全理解和实现一个GenericDAO层。我对这个概念很陌生,一直在做一些阅读和学习。我已经找到了关于GenericDAO Layer的示例实现的大量例子,这就是我最终的结果。休眠通用DAO,通用服务和通用视图层?

public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> { 

    private static Logger log = Logger.getLogger(GenericDAOImpl.class.getName()); 


    private SessionFactory sessionFactory; 


    @SuppressWarnings("unchecked") 
    public T findById(long id, Class<T> objectClass) { 
     log.info("Entered GenericDAOImpl findById(" + id +")"); 
     T result = (T) getSessionFactory().getCurrentSession().load(objectClass, id); 
     if(result != null){ 
      Hibernate.initialize(result); 
      return result; 
     }else{ 
      return null; 
     } 
    } 

    public boolean create(T newInstance) { 
     log.info("Entered GenericDAOImpl create()"); 
     if(newInstance == null){ 
      return false; 
     } 
     getSessionFactory().getCurrentSession().saveOrUpdate(newInstance); 
     return true;   
    } 


    public boolean updpate(T updateInstance) { 
     log.info("Entered GenericDAOImpl updpate()"); 
     if(updateInstance == null){ 
      return false; 
     } 
     getSessionFactory().getCurrentSession().update(updateInstance); 
     return true; 
    } 

    public boolean delete(T entity) { 
     log.info("Entered GenericDAOImpl delete()"); 
     if(entity == null){ 
      return false; 
     } 
     getSessionFactory().getCurrentSession().delete(entity); 
     return true; 
    } 

    @SuppressWarnings("unchecked") 
    public List<T> findByExample(T exampleInstance, Class<T> objectClass){ 
     log.info("Entered GenericDAOImpl findByExample()"); 
     Criteria searchCriteria = getSessionFactory().getCurrentSession().createCriteria(objectClass); 

     searchCriteria.add(Example.create(exampleInstance)); 

     return (List<T>)searchCriteria.list();   

    } 

    public SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    }  
} 

它好像这在理论上应该工作(可能需要一些调整)

我的问题是我可以使用一个通用的serviceview layer为“通过”分层架构方法?我不完全理解冬眠足以知道是否安全要做到这一点,其处理交易等交易...

也许像这样的服务层例如

public class GenericServiceImpl<T, ID extends Serializable> implements GenericService<T, ID>{ 

    private GenericDAO<T, ID> genericDao; 

    @Override 
    public T findById(long id, Class<T> objectClass) { 
     return this.getGenericDao().findById(id, objectClass); 
    } 

    @Override 
    public boolean create(T newInstance) { 
     return this.getGenericDao().create(newInstance); 
    } 

    @Override 
    public boolean updpate(T updateInstance) { 
     return this.getGenericDao().updpate(updateInstance); 
    } 

    @Override 
    public boolean delete(T entity) { 
     return this.getGenericDao().delete(entity); 
    } 

    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    @Override 
    public List findByExample(T exampleInstance, Class<T> objectClass) { 
     return this.getGenericDao().findByExample(exampleInstance, objectClass); 
    } 


    public GenericDAO<T, ID> getGenericDao() { 
     return genericDao; 
    } 

    public void setGenericDao(GenericDAO<T, ID> genericDao) { 
     this.genericDao = genericDao; 
    } 


} 

然后才能我继续做一个通用视图层?

请让我知道这种方法是否可以接受,或者如果有任何关于这种方法的问题。

在此先感谢您的想法和回应!

回答

3

您的服务,就其本身而言,只是将所有内容委托给底层的DAO。有时候这可能是需要的,但通常我会在业务层中加入“业务逻辑”。将逻辑放入服务层将有助于保持控制器层非常轻。

服务可以使用一个或多个DAO来完成它所需的任务。所以考虑一个简单的银行系统,在这里我有一个AccountDao

public class AccountDao implements GenericDao<Account, Long> { 
    // your save, insert, delete, find, etc 
} 
在我的服务

然后,我会把“makePayment”什么

@Service 
public class AccountService { 

    @Autowired 
    private AccountDao dao; 

    @Transactional 
    public void makePayment(Long fromId, Long toId, double amount) { 
     Account from = dao.find(fromId); 
     from.withdrawl(amount); 

     Account to = dao.find(toId); 
     to.deposit(amount); 

     dao.save(from); 
     dao.save(to); 
    } 
} 

使用交易服务层上,给你更多控制哪些操作需要在同一个事务中。

+0

感谢您的快速响应!因此,为了澄清,您仍然会为每个只会实现或扩展GenericDAO的hibernate域对象创建一个单独的DAO?我创建genericDAO的目的是为了减少多余的hibernate DAO类的数量? – Curt

+1

如果你的数据库操作是这么简单(只是更新,插入,删除)而没有专门的查询,那么你可以实例化几个通用的daos,每个类型一个。 – jeff

4

我实现了一个通用实体,道与服务对Hibernate

BaseEntity

@MappedSuperclass 
public class BaseEntity implements Serializable { 

    private static final long serialVersionUID = -932093556089251203L; 

    @Id 
    @GeneratedValue 
    private Long id; 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

} 

GenericDao

public interface GenericDao<T, ID extends Serializable> { 

    T save(T entity); 
    T update(T entity); 
    void delete(T entity); 
    T findById(long id); 
    List<T> findAll(); 
    void flush(); 
} 

GenericJpaDao

@Transactional 
public abstract class GenericJpaDao<T, ID extends Serializable> implements GenericDao<T, ID> { 

    private Class<T> persistentClass; 

    @PersistenceContext 
    private EntityManager entityManager; 

    public GenericJpaDao(Class<T> persistentClass) { 
     this.persistentClass = persistentClass; 
    } 

    protected EntityManager getEntityManager() { 
     return entityManager; 
    } 

    @PersistenceContext 
    public void setEntityManager(EntityManager entityManager) { 
     this.entityManager = entityManager; 
    } 

    public Class<T> getPersistentClass() { 
     return persistentClass; 
    } 

    @Transactional(readOnly=true) 
    public T findById(long id) { 
     T entity = (T) getEntityManager().find(getPersistentClass(), id); 
     return entity; 
    } 

    @SuppressWarnings("unchecked") 
    @Transactional(readOnly=true) 
    public List<T> findAll() { 
     return getEntityManager() 
      .createQuery("select x from " + getPersistentClass().getSimpleName() + " x") 
      .getResultList(); 
    } 

    public T save(T entity) { 
     getEntityManager().persist(entity); 
     return entity; 
    } 

    public T update(T entity) { 
     T mergedEntity = getEntityManager().merge(entity); 
     return mergedEntity; 
    } 

    public void delete(T entity) { 
     if (BaseEntity.class.isAssignableFrom(persistentClass)) { 
      getEntityManager().remove(
        getEntityManager().getReference(entity.getClass(), 
          ((BaseEntity)entity).getId())); 
     } else { 
      entity = getEntityManager().merge(entity); 
      getEntityManager().remove(entity); 
     } 
    } 

    public void flush() { 
     getEntityManager().flush(); 
    } 

} 

GenericService

public class GenericService<T, ID extends Serializable> { 
    @Autowired 
    private GenericDao<T, ID> genericDao; 

    public T find(long id) { 
     return this.getGenericDao().findById(id); 
    } 

    public List<T> all() { 
     return this.getGenericDao().findAll(); 
    } 

    @Transactional 
    public T create(T newInstance) { 
     return (T) this.getGenericDao().save(newInstance); 
    } 

    @Transactional 
    public T updpate(T updateInstance) { 
     return (T) this.getGenericDao().update(updateInstance); 
    } 

    @Transactional 
    public void delete(T entity) { 
     this.getGenericDao().delete(entity); 
    } 

    public GenericDao<T, ID> getGenericDao() { 
     return genericDao; 
    } 

    public void setGenericDao(GenericDao<T, ID> genericDao) { 
     this.genericDao = genericDao; 
    } 


} 

使用说明:

用户

@Entity 
@Table(name="USER") 
public class User extends BaseEntity { 

    private static final long serialVersionUID = -6189512849157712745L; 

    @Column(name="username", nullable = false) 
    private String username; 

    @Column(name="name", nullable = false) 
    private String name; 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

UserDAO的

public interface UserDAO extends GenericDao<User, Long> { 


} 

在UserDAOImpl

@Repository 
public class UserDAOImpl extends GenericJpaDao<User, Long> implements UserDAO { 

    public UserDAOImpl() { 
     super(User.class); 
    } 

    @PersistenceContext 
    private EntityManager entityManager; 

} 

,最后魔术服务我的服务Mysv

@Service 
public class Mysv extends GenericService<User, Long> { 

} 
1

只是为了您的信息,存在着对GenericDAO hibernate-generic-dao单独的代码库!为学习目的编写自己的代码总是很好的,但我相信阅读标准库和代码框架以学习专家已采用的标准也很重要。所以建议访问这个库。