一、Spring 整合 Hibernate

1.简介

  • Spring 支持大多数流行的 ORM 框架, 包括 Hibernate JDO, TopLink, Ibatis 和 JPA。

  • Spring 对这些 ORM 框架的支持是一致的, 因此可以把和 Hibernate 整合技术应用到其他 ORM 框架上.

  • Spring 2.0 同时支持 Hibernate 2.x 和 3.x. 但 Spring 2.5 只支持 Hibernate 3.1 或更高版本


2. Spring 整合 Hibernate 整合什么 ?

  • 有 IOC 容器来管理 Hibernate 的 SessionFactory

  • 让 Hibernate 使用上 Spring 的声明式事务


3. 在 Spring 中配置 SessionFactory

  • 需要为该工厂 Bean 指定 configLocation 属性来加载 Hibernate 配置文件.

  • 如果在 Spring IOC 容器中配置数据源. 可以将该数据源注入到 LocalSessionFactoryBean 的 dataSource 属性中. 该属性可以指定的数据源会覆盖掉 Hibernate 配置文件里的数据库配置

<!-- 配置 Hibernate 的 SessionFactory 实例: 通过 Spring 提供的 LocalSessionFactoryBean 进行配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <!-- 配置数据源属性 -->
  <property name="dataSource" ref="dataSource"></property>
  <!-- 配置 hibernate 配置文件的位置及名称 -->
  <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
  <!-- 配置 hibernate 映射文件的位置及名称, 可以使用通配符 -->
  <property name="mappingLocations" 
value="classpath:me/ziry/hibernate/model/*.hbm.xml"></property>
</bean>


  • 可以将所有配置合并到 LocalSessionFactoryBean 中,从而忽略 Hibernate 配置文件. 

  • 可以在 LocalSessionFactoryBean 的 mappingResources 属性中指定 XML 映射文件的位置.该属性为 String[] 类型. 因此可以指定一组映射文件.

  • 在 hibernateProperties 属性中指定数据库方言等.

<!-- 配置 Hibernate 的 SessionFactory 实例: 通过 Spring 提供的 LocalSessionFactoryBean 进行配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <!-- 配置数据源属性 -->
  <property name="dataSource" ref="dataSource"></property>
  <!-- 使用 hibernateProperties 属相来配置 Hibernate 原生的属性 -->
  <property name="hibernateProperties">
    <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
      <prop key="hibernate.show_sql">true</prop>
      <prop key="hibernate.format_sql">true</prop>
      <prop key="hibernate.hbm2ddl.auto">update</prop>
    </props>
  </property>
  <!-- 配置 hibernate 映射文件的位置及名称 -->
  <property name="mappingResources">
    <list>
      <value>me/ziry/user.hbm.xml</value>
    </list>
  </property>
</bean>


4. 用 Spring 的 ORM 模板持久化对象

  • 在单独使用 ORM 框架时, 必须为每个 DAO 操作重复某些常规任务. 例如: 打开关闭 Session 对象; 启动, 提交, 回滚事务等.

  • 同 JDBC 一样, Spring 采取了相同的方法 ------ 定义模板类和 DAO 支持类来简化 ORM 框架的使用. 而且 Spring 在不同的事务管理 API 之上定义了一个事务抽象层. 对于不同的 ORM 框架, 只需要选择相应的事务管理器实现.

  • Spring 对不同数据存储策略的支持类

  • HibernateTemplate 确保了 Hibernate 会话能够正确地打开和关闭. 

  • HibernateTemplate 也会让原生的 Hibernate 事务参与到 Spring 的事务管理体系中来. 从而利用 Spring 的声明式事务管理事务.


5. 使用 Hibernate 模板

  • HibernateTemplate 中的模板方法管理会话和事务. 如果在一个支持事务的 DAO 方法中有多个 Hibernate 操作, 模板方法可以确保它们会在同一个会话和事务中运行. 因此没有必要为了会话和事务管理去和 Hibernate API 打交道.

  • 通过为 DAO 方法添加 @Transactional 注解将其声明为受事务管理的.

  • HibernateTemplate 类是线程安全的, 因此可以在 Bean 配置文件中只声明一个实例, 并将该实例注入到所有的 Hibernate DAO 中.

(目前已不推荐使用Sprign 的Hibernate 模板 ,因为增加了代码耦合,减少的DAO层的移植性)


6. 整合步骤:

1). 加入 hibernate

①. jar 包

antlr-2.7.7.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.2.Final.jar
hibernate-core-4.2.4.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
javassist-3.15.0-GA.jar
jboss-logging-3.1.0.GA.jar
jboss-transaction-api_1.1_spec-1.0.1.Final.jar
c3p0-0.9.1.2.jar
mysql-connector-java-5.1.7-bin.jar

链接:http://pan.baidu.com/s/1mhYYPF6 密码:cba0


②. 添加 hibernate 的配置文件: hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
    <!-- 配置 hibernate 的基本属性 -->
    
    <!-- 1. 数据源需配置到 IOC 容器中, 所以在此处不再需要配置数据源 -->
    
    <!-- 2. 关联的 .hbm.xml 也在 IOC 容器配置 SessionFactory 实例时在进行配置 -->
    
    <!-- 3. 配置 hibernate 的基本属性: 方言, SQL 显示及格式化, 生成数据表的策略以及二级缓存等. -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    
    <!-- 配置 hibernate 二级缓存相关的属性. -->
 
  </session-factory>
</hibernate-configuration>


③. 编写了持久化类对应的 .hbm.xml 文件。 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="me.ziry.model.User" table="User">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
    
    </class>
</hibernate-mapping>


2). 加入 Spring

①. jar 包

com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar

链接:http://pan.baidu.com/s/1pK9knxT 密码:sifv


②. 加入 Spring 的配置文件

【applicationContext.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:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="me.ziry.spring.hibernate">
</context:component-scan>
	
<!-- 配置数据源 -->
<!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
	
<bean id="dataSource" 
          class="com.mchange.v2.c3p0.ComboPooledDataSource">
  <property name="user" value="${jdbc.user}"></property>
  <property name="password" value="${jdbc.password}"></property>
  <property name="driverClass" value="${jdbc.driverClass}"></property>
  <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

  <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
  <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
	
<!-- 配置 Hibernate 的 SessionFactory 实例: 通过 Spring 提供的 LocalSessionFactoryBean 进行配置 -->
<bean id="sessionFactory" 
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <!-- 配置数据源属性 -->
  <property name="dataSource" ref="dataSource"></property>
  <!-- 配置 hibernate 配置文件的位置及名称 -->
  <!--  
  <property name="configLocation" value="classpath:hibernate.cfg.xml">
  </property>
  -->
  <!-- 使用 hibernateProperties 属相来配置 Hibernate 原生的属性 -->
  <property name="hibernateProperties">
    <props>
       <prop key="hibernate.dialect">
       org.hibernate.dialect.MySQL5InnoDBDialect
       </prop>
       <prop key="hibernate.show_sql">true</prop>
       <prop key="hibernate.format_sql">true</prop>
       <prop key="hibernate.hbm2ddl.auto">update</prop>
    </props>
  </property>
  <!-- 配置 hibernate 映射文件的位置及名称, 可以使用通配符 -->
  <property name="mappingLocations" 
    value="classpath:me/ziry/hibernate/model/*.hbm.xml"></property>
</bean>

<!-- 配置 Spring 的声明式事务 -->
<!-- 1. 配置事务管理器 -->
<bean id="transactionManager" 
  class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 2. 配置事务属性, 需要事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="purchase" propagation="REQUIRES_NEW"/>
      <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- 3. 配置事务切点, 并把切点和事务属性关联起来 -->
<aop:config>
  <aop:pointcut expression="execution(* me.ziry.spring.hibernate.service.*.*(..))" 
			id="txPointcut"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

</beans>


3). 整合.

示例代码:

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import me.ziry.dao.BookShopDao;
@Repository
public class BookShopDaoImpl implements BookShopDao {
  @Autowired
  private SessionFactory sessionFactory;
  //不推荐使用 HibernateTemplate 和 HibernateDaoSupport
  //因为这样会导致 Dao 和 Spring 的 API 进行耦合
  //可以移植性变差
  //private HibernateTemplate hibernateTemplate;
  //获取和当前线程绑定的 Session. 
  private Session getSession(){
    return sessionFactory.getCurrentSession();
  }
  @Override
  public int findBookPriceByIsbn(String isbn) {
    String hql = "SELECT b.price FROM Book b WHERE b.isbn = ?";
    Query query = getSession().createQuery(hql).setString(0, isbn);
    return (Integer)query.uniqueResult();
  }
}


二、web 应用中访问 Spring

1. 在通用的 web 应用中访问 Spring

通过注册 Servlet 监听器 ContextLoaderListener, Web 应用程序可以加载 Spring 的ApplicationContext 对象. 这个监听器会将加载好的ApplicationContext 对象保存到 Web 应用程序的 ServletContext 中. 随后, Servlet 或可以访问 ServletContext 的任意对象就能通过一个辅助方法来访问 Spring 的应用程序上下文了.


2. 在通用的 web 应用中访问 Spring 具体实现

· 在 web.xml 文件中注册 Spring 提供的 Servlet 监听器[org.springframework.web.context Class ContextLoaderListener], 它会在当前 web 应用被加载时将 Spring 的 ApplicationContext 保存到 ServletContext 对象中. 

[org.springframework.web.context Class ContextLoaderListener]监听器通过查找 web 应用初始化参数 contextConfigLocation 来获取 Bean 配置文件的位置. 如果有多个 Bean 配置文件, 可以通过逗号或空格进行分隔. contextConfigLocation 的默认值为 /WEB-INF/applicationContext.xml. 若实际的文件和默认值一致则可以省略这个 web 应用的初始化参数


3. 在 WEB 环境下使用 Spring 具体步骤

①. 需要额外加入的 jar 包:

spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar


②. Spring 的配置文件, 和非 WEB 环境没有什么不同


③. 需要在 web.xml 文件中加入如下配置:

<!-- 配置 Spring 配置文件的名称和位置 -->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!-- 启动 IOC 容器的 ServletContextListener -->
<listener>
  <listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>


④. 在 web 应用程序中访问 Spring 的 ApplicationContext 对象

public class TestServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  
    //1. 从 appication 域对象中得到 IOC 容器的实例
    WebApplicationContext applicationContext = 
      WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
      
    /*
     * 另外一种写法
       ApplicationContext applicationContext2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
    */
    
    //2. 从 IOC 容器中得到 bean
    User user = ctx.getBean(User.class);
    
    //3. 使用 bean
    user.sayHello();
    
  }
  
}


三、 整合 Struts2

  • Struts2 通过插件实现和 Spring 的整合. 

  • Struts2 提供了两种和 Spring整合基本的策略:

   --将 Action 实例交给 Spring 容器来负责生成, 管理, 通过这种方式, 可以充分利用 Spring 容器的 IOC 特性, 提供最好的解耦

   --利用  Spring 插件的自动装配功能, 当 Spring 插件创建 Action 实例后, 立即将 Spring 容器中对应的业务逻辑组件注入 Action 实例. 


1. 让 Spring 管理控制器

  • 将 Action 实例交给 Spring 容器来负责生成, 管理, 通过这种方式, 可以充分利用 Spring 容器的 IOC 特性, 提供最好的解耦

  • 整合流程:

①. 正常加入 Struts2


②. 安装 Spring 插件: 把 struts2-spring-plugin-2.2.1.jar 复制到当前 WEB 应用的 WEB-INF/lib 目录下

通过添加 struts2-spring-plugin-2.3.15.3.jar 以后, Struts2 会先从 IOC 容器中

获取 Action 的实例.

if (appContext.containsBean(beanName)) {
    o = appContext.getBean(beanName);
} else {
    Class beanClazz = getClassInstance(beanName);
    o = buildBean(beanClazz, extraContext);
}

 

③. 在 Spring 的 IOC 容器中配置 Struts2 的 Action

注意: 在 IOC 容器中配置 Struts2 的 Action 时, 需要配置 scope 属性, 其值必须为 prototype

<bean id="TestAction" 
class="me.ziry.action.TestAction"
scope="prototype">
<property name="userService" ref="userService"></property>
</bean>


④. 在 Struts 配置文件中配置 action, 但其 class 属性不再指向该 Action 的实现类, 而是指向 Spring 容器中 Action 实例的 ID

<action name="usersave" class="TestAction">
<result>/success.jsp</result>
</action>


2. 自动装配

  • 利用  Spring 插件的自动装配功能, 当 Spring 插件创建 Action 实例后, 立即将 Spring 容器中对应的业务逻辑组件注入 Action 实例. 

  • 配置自动装配策略: Spring 插件的自动装配可以通过 struts.objectFactory.spring.autoWire 常量指定, 该常量可以接受如下值:

  --name: 根据属性名自动装配. 

  --type: 根据类型自动装配. 若有多个 type 相同的 Bean, 就抛出一个致命异常; 若没有匹配的 Bean, 则什么都不会发生, 属性不会被设置

  --auto: Spring 插件会自动检测需要使用哪种方式自动装配方式

  --constructor: 同 type 类似, 区别是 constructor 使用构造器来构造注入所需的参数

·整合流程:

  --安装 Spring 插件

  --正常编写 struts 配置文件

  --编写 spring 配置文件, 在该配置文件中不需要配置 Action 实例


相关jar包下载:

链接:http://pan.baidu.com/s/1bpLurt9 密码:5lem



纯干货!Spring4 简单教程 共 4 篇 分别:



注意:转载请注明出处,谢谢!

注意:本文归作者所有,未经作者允许,不得转载