The DAO with JPA and Spring – 带有JPA和Spring的DAO

最后修改: 2013年 8月 15日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

This article will show how to implement the DAO with Spring and JPA. For the core JPA configuration, see the article about JPA with Spring.

这篇文章将展示如何用Spring和JPA实现DAO。关于JPA的核心配置,请参阅关于JPA的文章与Spring。

2. No More Spring Templates

2.不再有Spring的模板

Starting with Spring 3.1, the JpaTemplate and the corresponding JpaDaoSupport have been deprecated in favor of using the native Java Persistence API.

从Spring 3.1开始,JpaTemplate和相应的JpaDaoSupport 已经被弃用,转而使用本地Java Persistence API。

Also, both of these classes are only relevant for JPA 1 (from the JpaTemplate javadoc):

另外,这两个类都只与JPA 1有关(从JpaTemplate javadoc)。

Note that this class did not get upgraded to JPA 2.0 and never will.

请注意,这个类没有被升级到JPA 2.0,而且永远不会被升级。

As a consequence, it is now best practice to use the Java Persistence API directly instead of the JpaTemplate.

因此,现在的最佳做法是直接使用Java Persistence API而不是JpaTemplate

2.1. Exception Translation Without the Template

2.1.不使用模板的例外情况翻译

One of the responsibilities of JpaTemplate was exception translation – translating the low-level exceptions into the higher level, generic Spring exceptions.

JpaTemplate的职责之一是异常翻译–将低级别的异常翻译成高级别的、通用的Spring异常。

Without the template, exception translation is still enabled and fully functional for all DAOs annotated with @Repository. Spring implements this with a bean postprocessor which will advise all @Repository beans with all the PersistenceExceptionTranslator found in the Container.

在没有模板的情况下,对于所有用@Repository注解的DAO来说,异常翻译仍然是启用的,而且功能齐全。Spring通过一个Bean Postprocessor来实现这一点,它将用容器中发现的所有@RepositoryBean的PersistenceExceptionTranslator来通知所有@RepositoryBean。

It is also important to note that the exception translation mechanism uses proxies – for Spring to be able to create proxies around the DAO classes, these must not be declared final.

还需要注意的是,异常转换机制使用代理–为了让Spring能够围绕DAO类创建代理,这些代理必须不被声明为最终

3. The DAO

3.DAO

First, we’ll implement the base layer for all the DAOs – an abstract class using generics and designed to be extended:

首先,我们将实现所有DAO的基础层–一个使用泛型的抽象类,旨在被扩展。

public abstract class AbstractJpaDAO< T extends Serializable > {

   private Class< T > clazz;

   @PersistenceContext
   EntityManager entityManager;

   public final 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 create( T entity ){
      entityManager.persist( entity );
   }

   public T update( T entity ){
      return entityManager.merge( entity );
   }

   public void delete( T entity ){
      entityManager.remove( entity );
   }
   public void deleteById( long entityId ){
      T entity = findOne( entityId );
      delete( entity );
   }
}

The main interesting aspect here is the way the EntityManager is injected – using the standard @PersistenceContext annotation. Under the hood, this is handled by the PersistenceAnnotationBeanPostProcessor – which processes the annotation, retrieves the JPA entity manager from the contains and injects it.

这里主要有趣的方面是注入EntityManager的方式–使用标准的@PersistenceContext注释。在引擎盖下,这是由PersistenceAnnotationBeanPostProcessor处理的–它处理注解,从包含中检索JPA实体管理器并将其注入。

The persistence post processor is either created explicitly by defining it in the configuration or automatically, by defining context:annotation-config or context:component-scan in the namespace config.

持久性后处理器要么通过在配置中定义明确地创建,要么通过在命名空间配置中定义context:annotation-configcontext:component-scan自动创建。

Also, note that the entity Class is passed in the constructor to be used in the generic operations:

另外,请注意,实体Class被传递到构造函数中,以用于泛型操作。

@Repository
public class FooDAO extends AbstractJPADAO< Foo > implements IFooDAO{

   public FooDAO(){
      setClazz(Foo.class );
   }
}

4. Conclusion

4.结论

This tutorial illustrated how to set up a DAO layer with Spring and JPA, using both XML and Java based configuration. We also discussed why not to use the JpaTemplate and how to replace it with the EntityManager. The final result is a lightweight, clean DAO implementation, with almost no compile-time reliance on Spring.

本教程说明了如何使用Spring和JPA设置DAO层,同时使用基于XML和Java的配置。我们还讨论了为什么不使用JpaTemplate以及如何用EntityManager取代它。最后的结果是一个轻量级的、干净的DAO实现,几乎不需要在编译时依赖Spring。

The implementation of this simple project can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

这个简单项目的实现可以在GitHub项目中找到–这是一个基于Maven的项目,所以应该很容易导入并按原样运行。