Spring实战第十一章

使用对象-关系映射持久化数据

11.1 在Spring中集成Hibernate

11.1.1 声明Hibernate的Session工厂

使用Hibernate所需的主要接口是org.hibernate.Session.Session接口提供了基本的数据访问功能。

获取Hibernate Session对象的标准方式是借助于Hibernate SessionFactory接口实现的类。SessionFactory主要负责Hibernate Session的打开、关闭以及管理。

在Spring中,我们要通过Hibernate SessionFactory bean来获取Hibernate SessionFactory。从3.1版本开始,Spring提供三个Session工厂bean供我们选择:
+ org.springframework.orm.hibernate3.LocalSessionFactoryBean
+ org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
+ org.springframework.orm.hibernate4.LocalSessionFactoryBean

11.1.2 构建不依赖于Spring的Hibernate代码

使用上下文Session(Contextual session),而不再使用HibernateTemplate.通过这种方式,会直接将Hibernate SessionFactory装配到Repository中,并使用它来获取Session。 如下:
借助HibernateSession实现不依赖于Spring的Repository

public HibernateSpitterRepository(SessionFactory sessionFactory){
  this.sessionFactory = sessionFactory;
}
private Session surrentSession(){
  return sessionFactory.getCurrentSession();
}
public void count(){
  return findAll().size();
}
public Spitter save(Spitter spitter){
  Serializable id = currentSession().save(spitter);
  return new Spitter((Long)id,
    spitter.getUsername(),
    spitter.getPassword(),
    spitter.getFullName(),
    spitter.getEmail(),
    spitter.isUpdateByEmail());
}
public Spitter findOne(Long id){
  return (Spitter) currentSession().get(Spitter.class,id);
}
public Spitter findByUsername(String username){
  return (Spitter) currentSession()
    .createCriteria(Spitter.class)
    .add(Restrictions.eq("username",username))
    .list().get(0);
}
public List<Spitter> findAll(){
  return (List<Spitter>) currentSession()
    .createCriteria(Spitter.class).list();
}

通过@Inject注解让Spring自动将一个SessionFactory注入到HibernateSpitterRepository的sessionFactory属性中。
在类上使用@Repository注解吗,为我们做两件事:
1. @Repository是Spring的另一种构造性注解,它能够像其他注解一样被Spring的组件扫描所扫描到。
2. 捕获平台相关的异常,然后使用Spring统一非检查型异常的形式重新抛出

11.2 Spring与Java持久化API

在Spring中使用JPA的第一步是要在Spring应用上下文中将实体管理器工厂(entity manager factory)按照bean的形式来进行配置。

11.2.1 配置实体管理器工厂

简单来讲,基于JPA的应用程序需要使用EntityManagerFactory的实现类来获取EntityManager实例。JPA定义了两种类型的实例管理器:
+ 应用程序管理类型(Application-managed):当应用程序向实体管理器工厂直接请求实体管理器时,工厂会创建一个实体管理器。在这种模式下,程序要负责打开和关闭实体管理器并在事务中对其进行控制。这种方式的实体管理器适合于不运行在JavaEE容器中的独立应用程序。
+ 容器管理类型(Container-managed):实体管理器由JavaEE创建和管理。应用程序根本不与实体管理器工厂打交道。相反,实体管理器直接通过注入或JNDI来获取。容器负责配置实体管理器工厂。这种类型的实体管理器最适用于JavaEE容器,在这种情况下回希望在persistence.xml指定的JPA配置之外保持一些自己对JPA的控制。

上述两种方式实现了同一个EntityManager接口。关键的区别不在于EntityManager本身,而是在于EntityManager的创建和管理方式。
应用程序管理类型的EntityManager是由EntityManagerFactory创建的,而后者是通过PersistenceProvider的createEntityManagerFactory()方法得到的。与此相对,容器管理类型的EntityManagerFactory是通过PersistenceProvider的createContainerManagerFactory()方法得到的.
不管使用哪种EntityManagerFactory,Spring都会负责管理EntityManager。
+ LocalEntityManagerFactoryBean生产应用程序管理类型的EntityManagerFactory
+ LocalContainerEntityManagerFactoryBean生产容器管理类型的EntityManagerFactory

配置应用程序管理类型的JPA

在类路径的META-INF目录下一个名为persistence.xml文件,作用在于定义一个或多个持久化单元(同一个数据源下的一个或多个持久化类)。

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
  <persistence-unit name="spitterPU">
    <class>com.habuma.spittr.domain.Spitter</class>
    <class>com.habuma.spittr.domain.Spittle</class>
    <properties>
      <property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver" />
      <property name="toplink.jdbc.url" value="jdbc:hsqldb:hsql://localhost/spitter/spitter" />
      <property name="toplink.jdbc.user" value="sa" />
      <property name="toplink.jdbc.password" value="" />
    </properties>
  </persistence-unit>
</persistence>

因为在persistence.xml中包含了大量的配置信息,所以在Spring中需要的配置就很少了。

@Bean
public LocalEntityManagerFactoryBean entityManagerFactoryBean(){
  LocalEntityManagerFactoryBean emfb = new LocalEntityManagerFactoryBean();
  emfb.setPersistenceUnitName("spitterPU");
  return emfb;
}
配置容器管理类型的JPA
从JNDI获取实体管理器工厂

11.2.2 编写基于JPA的Repository

package com.habuma.spittr.persistence;
import *;

@Repository
@Transactional
public class JpaSpitterRepository implements SpitterRepository{

  @PersistenceUnit
  private EntityManagerFactory emf;//注入EntityManagerFactory

  public void addSpitter(Spitter spitter){
    emf.createEntityManager().persist(spitter);//创建并使用EntityManager
  }

  public Spitter getSpitterById(Long id){
    return emf.createEntityManager().find(Spitter.class,id);
  }

  public void saveSpitter(Spitter spitter){
    emf.createEntityManager().merge(spitter);
  }
}

11.3 借助SpringData实现自动化的JPA Repository

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值