`
baobaocc
  • 浏览: 4333 次
  • 性别: Icon_minigender_1
  • 来自: 南宁
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

JPA 设计模式

    博客分类:
  • java
 
阅读更多
大家给点JPA 设计模式点建议呀!
 作为JavaEE5 规范一部分的JPA,已经有众多的实现,比如:Hiberante,TopLink, EclipseLink和OpenJPA 等许多ORM框架。JPA不仅仅应用于EJB3中,你也可以应用EJB3之外的应用,比如Spring 中。甚至Gavin King Hiberante的作者 在Hiberante in Action 的第二版书中也推荐使用JPA。很明显,JPA将被广泛的应用。

  一旦你熟悉annotation,并尝试过Hello world之类的程序后,你会感觉,恩 JPA确实不错。然后,当你在你的项目中开始应用JPA时,你会发现其实并不那么简单,你需要考虑如何处理事务,惰性加载,移除对象实例,继承等等。这些问题会在本系列中给你答案。

  首先进入第一的设计模式 DAO。

  我们需要DAO吗?

  在二年前,我们已经讨论了这个问题了,讨论的结果是:是否使用DAO依赖于你的应用,类似于GOF的设计模式,如果是很简单的应用程序,应用设计模式,只能增加你的复杂度。 而对于复杂应用程序,正因为其复杂,应用设计模式可以减低复杂度,提高可维护性。 

  应用了DAO我们可以得到如下好处:

  1. 避免在任何存取数据的代码中引入EntityManager,减少了依赖。

  2. 对某些实体Bean操作增加限制。比如你不想对LogEntry提供删除操作,应用DAO,你仅仅做的是不要在LogEntry DAO中不要添加remove的方法。

  3. 理论上,应用DAO层,你一个自由切换其他的持久机制比如纯JDBC或者Ibatis.而实际上,JPA已经是一个抽象层,这种切 换是没有意义的。

  4.  你可以在一个实体中集中所有的查询避免这些查询在其他代码中出现。你可以使用named queries 在实体类中查询,但是您仍然需要正确的参数被设置。对应这种查询,你可以在DAO中设置参数,然后转换成正确的返回类型,比如:
 public List<ChangePlan> findExecutingChangePlans() {
      Query query = entityManager.createQuery(
            "SELECT plan FROM ChangePlan plan where plan.state = 'EXECUTING'");
      return (List<ChangePlan>) query.getResultList();
}

  然后,但你决定使用DAO时,如何正确合理的使用它呢? 在Spring的JpaTemplate的JavaDoc中建议,不要使用类似特殊的类,类似JpaDaoSupport。 而是你应该自己通过@PersistenceContext注释获取EntityManger来维护你的DAO。这种方式可以在EJB3的容器中工作,并且如果你在Spring的context 加入PersistenceAnnotationBeanpostProcessor Bean的话,在Spring2.0里也是没有问题的。

  类型安全且泛化的DAO pattern

  因为每一个DAO都包含一些相同的逻辑,所以我们应该抽取这些逻辑放入到父类中。

  实体类

  比如,我们想实例化OrderClass:

@Entity
@Table(name = "ORDERS")
public class Order {
        @Id
        @GeneratedValue
        private int id;
        private String customerName;
        private Date date;
 
        public int getId() { return id; }
        public void setId(int id) { this.id = id; }
 
        public String getCustomerName() { return customerName; }
        public void setCustomerName(String customerName) { this.customerName = customerName; }
 
        public Date getDate() { return date; }
        public void setDate(Date date) { this.date = date;}


public interface Dao<K, E> {
      void persist(E entity);
      void remove(E entity);
      E findById(K id);
}

  K ,E为泛型,你可以加其他的方法比如:List findAll().

  然后我们定义一个自接口,实现特殊的方法,比如,我们想查找一定条件的Order信息:

public interface OrderDao extends Dao<Integer, Order> {
        List<Order> findOrdersSubmittedSince(Date date);
}

  基本DAO的实现

  第三步就是创建基本的JPA DAO的实现。它实现了Dao接口。

public abstract class JpaDao<K, E> implements Dao<K, E> {
        protected Class<E> entityClass;
 
        @PersistenceContext
        protected EntityManager entityManager;
 
        public JpaDao() {
               ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
               this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
        }
 
        public void persist(E entity) { entityManager.persist(entity); }
 
        public void remove(E entity) { entityManager.remove(entity); }
 
        public E findById(K id) { return entityManager.find(entityClass, id); }

上述实现是直接明了的,大家还要注意几点:

  JpaDao的构造方法是通过ParameterizedType获取具体的实体类。

  通过@PersistenceContext 获取EntityManager

  entityClass和EntityManager是Protected类型,子类可以直接访问。

  特殊的DAO实现

  最后,我们创建特殊的DAO,它扩张了基本的DAO接口实现了OrderDAO接口

public class JpaOrderDao extends JpaDao<Integer, Order> implements OrderDao {
        public List<Order> findOrdersSubmittedSince(Date date) {
               Query q = entityManager.createQuery(
                       "SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");
               q.setParameter("date_since", date);
               return (List<Order>) q.getResultList();

  DAO的使用

  在EJB3中,

@EJB(name="orderDao")
private OrderDao orderDao;

  在Spring中,我们使用XML bean 文件,或者通过autowiring 如下:

@Autowired
public OrderDao orderDao;

  总之。当我们获取到了DAO的引用后,我们可以如下使用:

Order o = new Order();
o.setCustomerName("Peter Johnson");
o.setDate(new Date());
orderDao.persist(o);

  当然,我们可以再OrderDao接口中加入其它的查询:

List<Order> orders = orderDao.findOrdersSubmittedSince(date);
for (Order each : orders) {
        System.out.println("order id = " + each.getId());
}


  总之,使用了类型安全的DAO Pattern有如下优势:

  1.    从Client的角度讲,不会直接依赖于JPA的API

  2.    通过泛型实现类型安全,避免Cast异常。

  3.    集中处理所有跟JPA相关的代码。

  4.    可以在集中点上加入事务,log 性能测试等逻辑。

  5.    通过一个类可以测试数据库访问代码。

  希望这些可以说服你使用DAO Pattern . 接下来我们将讨论Bidirectional assocations 双向关联模式。

转:http://tech.ddvip.com/2009-09/1253758626134158_2.html
分享到:
评论
1 楼 mercyblitz 2010-03-14  
 2.    通过泛型实现类型安全,避免Cast异常。

这个不是DAO的事情。

LZ何不直接用SessionFacade?直接业务操作比中间DAO要强。

相关推荐

    JPA API 开发手册

    ### JPA设计模式 1. **单一责任原则(SRP)**: 每个实体类只关注其业务逻辑,数据库操作交由JPA处理。 2. **依赖注入(DI)**: 通常结合Spring等框架,通过依赖注入实现实体管理器的创建和管理。 3. **贫血模型与...

    JPA中文解释,JPA的API

    描述中提到"JPA的API非常简洁,但是描述很全面",这表明JPA设计时注重了易用性和完整性。尽管它的API接口数量相对较少,但涵盖了数据持久化的各个方面,包括实体管理、查询、事务控制等。例如,`EntityManager`是JPA...

    JPA

    理解并熟练掌握JPA的各种关系映射机制对于高效地设计和实现数据密集型应用程序至关重要。通过上述讨论,我们可以看到JPA如何简化了实体之间的关系处理,使得开发者能够更专注于业务逻辑而不是底层数据操作。

    使用 SpringBoot + SpringDataJPa 设计通用的权限管理系统.zip

    - **JSON 格式**:数据交互采用 JSON 格式,方便前后端分离的开发模式。 6. **安全性**: - **CSRF 防御**:防止跨站请求伪造,通常在表单提交或敏感 API 调用时添加 CSRF 令牌。 - **XSS 防御**:避免跨站脚本...

    struts2 jpa project

    总的来说,"struts2 jpa project"是一个综合性的实例,它涵盖了MVC设计模式、ORM、数据库操作等多个核心概念。对于想要学习如何在实际项目中整合Struts2和JPA的开发者来说,这是一个非常有价值的参考资料。通过深入...

    设计模式,hibernate电子书

    设计模式的掌握有助于构建健壮的系统架构,而JPA和Hibernate的使用则能有效地处理数据持久化问题,尤其是在大型企业级应用中,它们能显著提高开发效率和应用性能。因此,深入理解并实践这些知识点,无论是对于个人...

    尚硅谷 jpa

    - **简单易用**:JPA 设计时考虑到了易用性,创建实体类非常直观且简单,只需要使用 `javax.persistence.Entity` 注解即可。 - **强大的查询能力**:JPA 支持 JPQL (Java Persistence Query Language),这是一种面向...

    JPA(hibernate) Dao 和 DaoSupport

    DAO模式是一种设计模式,用于隔离业务逻辑层和数据访问层,使得业务代码不会直接与数据库交互,而是通过DAO接口进行操作。这样可以提高代码的可测试性和可维护性。在JPA和Hibernate中,DAO通常用于执行CRUD(创建、...

    Java EE设计模式:Spring企业级开发最佳实践

    《Java EE设计模式:Spring企业级开发最佳实践》是一本深度探讨如何在企业级环境中有效利用Java EE设计模式和Spring框架的专著。该书由人民邮电出版社出版,旨在帮助开发者掌握在复杂的企业级应用中,如何通过设计...

    Hibernate JPA jar包

    - **Repository(仓库)**:仓库接口是一种设计模式,用于提供对特定领域对象的CRUD操作。在Hibernate JPA中,我们可以自定义Repository接口,实现对实体的数据库操作。 **2. Hibernate JPA的使用步骤** - **配置*...

    关于SH JPA 简单的CRUD操作

    Restful API是一种Web服务设计模式,通过HTTP方法(GET, POST, PUT, DELETE)对应CRUD操作。在SH JPA中,我们可以使用Spring MVC或Spring WebFlux构建Restful接口,定义如`@PostMapping`、`@GetMapping`、`@...

    SpringMVC+JPA+Freeemarker

    它遵循Model-View-Controller(MVC)设计模式,将业务逻辑、数据和用户界面分离,提高了代码的可维护性和可测试性。SpringMVC通过DispatcherServlet处理HTTP请求,通过拦截器、控制器、模型、视图和数据绑定等机制...

    java e e与设计模式

    设计模式则是软件开发中的最佳实践,它们是解决常见问题的模板,可以在不同场景下重复使用,以提高代码的可读性、可维护性和灵活性。 在Java EE开发中,设计模式扮演着至关重要的角色。以下是一些在Java EE开发中...

    j2ee的设计模式(最新版)

    "j2ee的设计模式(最新版)"这个标题暗示我们将探讨的是如何在J2EE环境中应用设计模式来提高代码的可维护性、可扩展性和可重用性。 首先,我们需要理解J2EE的主要组件和架构层次,包括客户端层、Web层、业务逻辑层...

    传智播客JPA学习笔记.pdf

    JPA提供了加载(find, persist, merge, refresh, detach等方法)、更新(通过Entity Manager操作)和删除(remove方法)对象的API,这些操作遵循Unit Of Work和Identity Map设计模式。 **8. 分析JPA与持久化实现...

    SSH-JPA.ZIP_SSH JPA DAO_java web ssh jpa_jpa_ssh_ssh jpa

    2. Struts2:这是一个基于MVC(Model-View-Controller)设计模式的Web框架,用于简化Java Web应用程序的开发。它处理HTTP请求,调度到相应的控制器,更新模型,然后与视图进行交互。在SSH-JPA中,Struts2是用户界面...

    springboot+jpa+oracle

    RESTful API设计是现代Web服务的主流模式,它遵循HTTP协议,使接口更加清晰、简洁。项目中的"RESTful API 设计.png"可能展示了如何在Spring Boot中创建RESTful API,包括定义Controller层的接口,使用@...

    手动创建 SpringMvc +SpringDataJpa+Hibernate+ freemarker mavenProject+ 环境切换 webDemo

    总结来说,本项目是一个基础的Web开发框架,结合了SpringMVC的MVC设计模式、Spring Data JPA的数据访问层、Hibernate的ORM能力以及FreeMarker的模板引擎,同时还实现了环境配置的灵活切换,为开发高效、可维护的Web...

Global site tag (gtag.js) - Google Analytics