技术开发 频道

Spring PK EJB 3.0,我们该选择哪一个?



    持久化是企业级应用的关键组件。当然,SpringEJB对于持久化都提供了强大的支持。Spring的设计策略是在产品中集成主流的持久化框架如JDBCHibernateJDOiBatis等。而在最新的EJB3.0规范中,实体beanJPAJAVA持久化API)取代;相应地在Spring 2.0中,也增加了对于JPA的支持。JPA旨在提供一个轻量级的对象-关系映射框架。在EJB 3.0中专门定义了操作持久化服务的接口和映射实体对象到关系数据库的方法。

持久化——功能对比

图一. 航班预订模型。模型涉及了对象-关系映射的诸多概念:组合,双向和三向关联等。

如下的单元测试用来验证机票对象生成、与航班关联、分配座位、最后结果存入数据库。

public void testSave() { Ticket ticket = TicketMother.create(); Flight outboundFlight = flightDAO.findById(1); Flight returnFlight = flightDAO.findById(2); ticket.setOutboundFlight(outboundFlight); ticket.setReturnFlight(returnFlight); ticket.getPassenger().setFlightDetails(outboundFlight, new PassengerFlightDetails(getSeatForFlight(outboundFlight, "2A"))); ticket.getPassenger().setFlightDetails(returnFlight, new PassengerFlightDetails(getSeatForFlight(returnFlight, "2B"))); ticketDAO.save(ticket); ticket = ticketDAO.findById(ticket.getId()); assertEquals("John", ticket.getPassenger().getFirstName()); assertEquals("2A", ticket.getPassenger().getDetailsForFlight (ticket.getOutboundFlight()) .getSeat().getNumber()); }

 

 

 

以上测试在Spring and EJB 3.0环境下都成功通过。这说明Spring EJB 3.0在基本的ORM持久化方面功能相当,并且其实现方式非常相似。Hibernate是最流行的对象关系映射工具,以下是Spring/Hibernate组合的TicketDAO类的实现:

public class TicketSpringDAO extends HibernateDaoSupport implements TicketDAO { public Ticket save(Ticket ticket) { getHibernateTemplate().saveOrUpdate(ticket); return ticket; } ... } EJB 3.0的实现如下: @Stateless public class TicketEJBDAO implements TicketDAO { @PersistenceContext(unitName = "flightdb") private EntityManager em; public Ticket save(Ticket ticket) { em.persist(ticket); return ticket; } ... }

 

 

显然,从实现的角度来看,两个产品非常相似。Spring设计了HibernateDaoSupport类,将SpringHibernate间的交互操作抽象出来,通过HibernateDaoSupport类可访问Hibernate的诸多特性,以及SpringHibernate模版。而在EJB 3.0中,则是凭借容器来注入实体对象管理器。

HibernateSessionJPA的实体对象管理器功用相当,但其间细微的差别值得重视。HibernateSession是实体对象的缓存同时也是对象-关系映射引擎的接口。而在JPA中,持久化场景承担了缓存的角色,实体管理器则承担接口的角色。

在映射方式方,基于Spring/Hibernate的应用以XML映射文件的方式实现。

<hibernate-mapping package="org.jug.flight.domain" default-lazy="false"> <class name="Ticket"> <id name="id" column="id"> <generator class="native" /> </id> <property name="status" type="Status" /> <many-to-one name="outboundFlight" column="outbound_flight" /> <many-to-one name="returnFlight" column="return_flight" /> <many-to-one name="passenger" column="passenger_id" cascade="all" /> </class> </hibernate-mapping>

 

 

基于JPA的应用通常采用注释的方式,好处是减少了配置以及映射数据毗邻相关实体对象的工作量,从而提高了可视性。 

@Entity public class Ticket implements Serializable { @Id @GeneratedValue private long id; private Status status; private double price; @ManyToOne(cascade = CascadeType.PERSIST) private Passenger passenger; private Flight outboundFlight; private Flight returnFlight; ... }

     Spring/Hibernate EJB 3.0/JPA在通过ORM实现持久化方面功能相似。

0
相关文章