Spring整合Hibernate
  由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心SQL语句,直接与对象打交道。 将Hibernate做完映射之后的对象交给Spring来管理是再合适不过的事情了, Spring也同时提供了对Hibernate的SessionFactory的集成功能。实例如下:

1、首先Hibernate完成OR映射功能

POJO类:Person.java 【注意:必须要保留一个无参的构造方法】
public class Person {
  private Integer id;
  private String name;
  
  public Person(){}
  
  public Person(String name) {
    this.name = name;
  }
  
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}
完成从对象到数据库字段的对应关系的映射配置:Person.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
                "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.comp.bean">
        <class name="Person" table="person">
          <cache usage="read-write" region="cn.comp.bean.Person"/>
                <id name="id">
                        <generator class="native"/>
                </id>
                <property name="name" length="10" not-null="true"/>
        </class>
</hibernate-mapping>

2、让Hibernate完成后的对象交给Spring来管理

配置Hibernate与Spring的关系:beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <context:annotation-config/>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
         <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
         <property name="url" value="jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=UTF-8"/>
         <property name="username" value="root"/>
         <property name="password" value="123456"/>
            <!-- 连接池启动时的初始值 -->
     <property name="initialSize" value="1"/>
     <!-- 连接池的最大值 -->
     <property name="maxActive" value="500"/>
     <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
     <property name="maxIdle" value="2"/>
     <!--    最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
     <property name="minIdle" value="1"/>
     </bean>
    
  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
     <property name="mappingResources">
            <list>
                <value>cn/itcast/bean/Person.hbm.xml</value>
            </list>
     </property>
            <property name="hibernateProperties">
            <value>
                    hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                    hibernate.hbm2ddl.auto=update
                    hibernate.show_sql=false
                    hibernate.format_sql=false
                    hibernate.cache.use_second_level_cache=true
                                hibernate.cache.use_query_cache=false
                         hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
                </value>
            </property>
  </bean>
  <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
  </bean>
  <tx:annotation-driven transaction-manager="txManager"/>
  <bean id="personService" class="cn.comp.service.impl.PersonServiceBean"/>
  <bean id="personList" class="cn.comp.web.PersonAction"/>
</beans>
抽取业务接口:PersonService.java
public interface PersonService {

  public void save(Person person);

  public void update(Person person);

  public Person getPerson(Integer personid);

  public void delete(Integer personid);

  public List<Person> getPersons();

}
实现类完成对业务逻辑的操作:PersonServiceBean.java
@Transactional
public class PersonServiceBean implements PersonService {
  @Resource private SessionFactory sessionFactory;

  public void save(Person person){
    sessionFactory.getCurrentSession().persist(person);
  }
  
  public void update(Person person){
    sessionFactory.getCurrentSession().merge(person);
  }
  @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
  public Person getPerson(Integer personid){
    return (Person)sessionFactory.getCurrentSession().get(Person.class, personid);
  }

  public void delete(Integer personid){
    sessionFactory.getCurrentSession().delete(
        sessionFactory.getCurrentSession().load(Person.class, personid));
  }
  @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
  @SuppressWarnings("unchecked")
  public List<Person> getPersons(){    
    return sessionFactory.getCurrentSession().createQuery("from Person").list();
  }
  
}

3、完成对实现类的测试

对实现类的测试类: PersonServiceTest.java
public class PersonServiceTest {
  private static PersonService personService;
  
  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    try {
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
      personService = (PersonService)applicationContext.getBean("personService");
    } catch (RuntimeException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void testSave() {
    personService.save(new Person("小张"));
  }

  @Test
  public void testUpdate() {
    Person person = personService.getPerson(1);
    //....
    person.setName("小丽");
    personService.update(person);
  }

  @Test
  public void testGetPerson() {
    Person person = personService.getPerson(2);
    System.out.println(person.getName());
    try {
      System.out.println("请关闭数据库");
      Thread.sleep(1000*15);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("第二次开始获取");
    person = personService.getPerson(2);
    System.out.println(person.getName());
  }

  @Test
  public void testDelete() {
    personService.delete(1);
  }

  @Test
  public void testGetPersons() {
    List<Person> persons = personService.getPersons();
    for(Person person : persons){
      System.out.println(person.getName());
    }
  }
}
 
4、附件
中间使用到DBCP作为数据库连接缓存,关于其性能参考本文章的附件部分