织梦网站错位,企业网站建设立项请示,WordPress管理员邮件,wordpress 有趣的插件1.概述 本文将着重于通过对系统中的所有实体使用单个通用的数据访问对象来简化DAO层 #xff0c;这将导致优雅的数据访问 #xff0c;而不会造成不必要的混乱或冗长。 2. Hibernate和JPA DAO 大多数生产代码库都有某种DAO层。 通常#xff0c;实现范围从没有抽象基类的多个… 1.概述 本文将着重于通过对系统中的所有实体使用单个通用的数据访问对象来简化DAO层 这将导致优雅的数据访问 而不会造成不必要的混乱或冗长。 2. Hibernate和JPA DAO 大多数生产代码库都有某种DAO层。 通常实现范围从没有抽象基类的多个类到某种通用类。 但是一件事是一致的- 总是多于一件事-最有可能的是DAO与系统中的实体之间存在一对一的关系。 同样根据所涉及泛型的级别实际的实现方式可能从大量重复的代码变为几乎为空的代码大部分逻辑分组在基本抽象类中。 通常可以通过使用Java Generics提供的类型安全性 用单个参数化DAO替换这些多个实现这样就不会损失任何功能。 接下来介绍此概念的两种实现 一种用于Hibernate中心持久性层另一种针对JPA 。 这些实现绝不是完整的-仅包括某些数据访问方法但是可以很容易地使它们变得更彻底。 2.1。 抽象的休眠DAO public abstract class AbstractHibernateDao T extends Serializable {private Class T clazz;AutowiredSessionFactory sessionFactory;public final void setClazz( Class T clazzToSet ){this.clazz clazzToSet;}public T findOne( long id ){return (T) getCurrentSession().get( clazz, id );}public List T findAll(){return getCurrentSession().createQuery( from clazz.getName() ).list();}public void create( T entity ){getCurrentSession().persist( entity );}public void update( T entity ){getCurrentSession().merge( entity );}public void delete( T entity ){getCurrentSession().delete( entity );}public void deleteById( long entityId ){T entity findOne( entityId );delete( entity );}protected final Session getCurrentSession(){return sessionFactory.getCurrentSession();}
} DAO直接使用Hibernate API而不依赖于任何Spring模板例如HibernateTemplate 。 Hibernate DAO教程介绍了模板的使用以及在DAO中自动装配的SessionFactory的管理。 2.2。 通用休眠DAO 现在已经完成了抽象DAO我们只需实现一次即可- 通用DAO实现将成为唯一需要的实现 Repository
Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericHibernateDao T extends Serializable extends AbstractHibernateDao T implements IGenericDao T {//
} 首先请注意通用实现本身是参数化的 -允许客户根据具体情况选择正确的参数。 这将意味着客户端将获得类型安全的所有好处而无需为每个实体创建多个工件。 其次注意这些通用DAO实现的原型范围 。 使用此范围意味着Spring容器将在每次请求DAO时包括自动装配时创建一个新的DAO实例。 这将允许服务根据需要将具有不同参数的多个DAO用于不同的实体。 这个作用域如此重要的原因是由于Spring初始化容器中bean的方式。 将通用DAO保留为没有作用域将意味着使用默认的singleton作用域 这将导致DAO的单个实例位于容器中。 对于任何一种更复杂的情况这显然都是主要的限制。 IGenericDao只是所有DAO方法的接口因此我们可以将Spring的实现注入或任何需要的中 public interface IGenericDaoT extends Serializable {T findOne(final long id);ListT findAll();void create(final T entity);T update(final T entity);void delete(final T entity);void deleteById(final long entityId);
} 2.3。 JPA DAO摘要 public abstract class AbstractJpaDao T extends Serializable {private Class T clazz;PersistenceContextEntityManager 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再次不依赖于现已弃用的 Spring JpaTemplate 。 2.4。 通用JPA DAO 与Hibernate实现类似JPA数据访问对象也很简单 Repository
Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericJpaDao T extends Serializable extends AbstractJpaDao T implements IGenericDao T {//
}3.注入此DAO 现在Spring将注入一个DAO 。 此外 类需要指定 Service
class FooService implements IFooService{IGenericDao Foo dao;Autowiredpublic void setDao( IGenericDao Foo daoToSet ){dao daoToSet;dao.setClazz( Foo.class );}// ...} Spring 使用setter注入自动装配新的DAO实例以便可以使用Class对象自定义实现。 在此之后DAO已完全参数化可供服务使用。 当然还有其他方法可以为DAO指定类-通过反射甚至以XML。 我偏向于这种简单的解决方案因为与使用反射相比其可读性和透明度更高。 4。结论 本文通过提供通用DAO的单个可重用实现讨论了数据访问层的简化 。 在基于Hibernate和JPA的环境中都介绍了此实现。 结果是简化了的持久层没有不必要的混乱。 有关使用基于Java的配置和项目的基本Maven pom设置Spring上下文的分步介绍请参阅本文 。 参考在baeldung博客上使用JCG合作伙伴 Eugen Paraschiv的Spring和Java Generics简化了DAO 。 翻译自: https://www.javacodegeeks.com/2011/12/simplifying-data-access-layer-with.html