hibernate+spring+struts2整合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate+spring+struts2整合相关的知识,希望对你有一定的参考价值。

这三个都是java的知名框架(SSH)
struts2,作为控制器,也就相当于servlet,采用拦截器机制处理用户的请求。
hibernate,持久化框架。
spring,java分层的轻量级框架。用来管理,提供依赖注入,切面等。
如有错误,欢迎指正。
SSH框架整合
首先时web.xml配置,hibernate的一大亮点就是延迟加载,就是在你需要的时候才会真正的发送SQL语句。
加上OpenSessionInView是因为如果在首页需要在数据库加载数据时如果时延迟加载则会引发首页无数据的问题,只要使用了hibernate框架,就应该在web页面配置OpenSessionInView。

<!--web.xml配置-->
<!-- hibernateOpenSessionInView,交由spring管理,此类位与spring的orm包中,需要单独下载,openSessionInView需要配置在web.xml第一个,如果不是可能会引发问题。版本不一样,路径可能不一样-->
  <filter>
   <filter-name>openSessionInView</filter-name>
   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
   <filter-name>openSessionInView</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>
 
<!--struts的拦截器配置-->
  <!-- struts -->
  <filter>
   <filter-name>struts</filter-name>
   <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
   <filter-name>struts</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <!-- tomcat启动时加载applicationContext.xml文件 -->
   <context-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>classpath:applicationContext.xml</param-value> 
    </context-param> 
  <!-- spring监听 -->
   <listener> 
        <listener-class> 
            org.springframework.web.context.ContextLoaderListener 
        </listener-class> 
 </listener>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

applicationContext配置(我用的STS,自动增加命名空间,个人觉得方便)
<!--第一步就是配置dataSource,我这里配的时c3p0,配置大方式都是大同小异,-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  <!--驱动-->
  <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
  <!--连接地址,用户名,密码,这里使用的硬编码,也可以导入方式-->
      <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
      <property name="user" value="scott"/>
      <property name="password" value="scott"/>
   <!--连接池中保留的最大连接数。默认值: 15 -->   
           <property name="maxPoolSize" value="20"/>  
           <!-- 连接池中保留的最小连接数,默认为:3-->  
         <property name="minPoolSize" value="2"/>  
         <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3-->  
         <property name="initialPoolSize" value="2"/>  
         <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->   
         <property name="maxIdleTime">60</property>  
         <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->   
         <property name="checkoutTimeout" value="3000"/>
         <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->
         <property name="acquireIncrement" value="2"/>  
         <!--定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次-->   
         <property name="acquireRetryAttempts" value="0"/>  
         <!--重新尝试的时间间隔,默认为:1000毫秒-->   
         <property name="acquireRetryDelay" value="1000" />  
         <!--关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务 -->   
         <property name="autoCommitOnClose">false</property>  
         <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。默认值: null -->   
         <property name="automaticTestTable">Test</property>  
         <!--如果为false,则获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常,但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认: false-->   
         <property name="breakAfterAcquireFailure">false</property>  
         <!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->   
         <property name="idleConnectionTestPeriod">60</property>  
         <!--c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0-->   
         <property name="maxStatements">100</property>  
         <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。默认值: 0 -->   
         <property name="maxStatementsPerConnection"></property>
</bean> 
 <!-我这里使用的是用实体类生成表,实际中不是这样的,但是大同小异,我会写上注释->
 <!--sessionFactory,用来生成session,DAO(持久化层)的session就从这里获取-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <!--org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean这个类中有一个属性叫dataSource,需引用dataSource(上面配置的c3p0)数据源-->
  <property name="dataSource" ref="dataSource"></property>
  <!--全包扫描,根据entity包生成里面所有的实体类,注意,实体类如果有数据库关键字,或者实体类与表明重复,表有可能生成失败(重复一定会生成失败)-->
  <property name="packagesToScan">
   <list>
    <value>entity</value>
   </list>
  </property>
  <!--hibernate的属性配置-->
  <property name="hibernateProperties">
   <props>
    <!--第一次生成表的时候update应该改成create,之后在改为update,不然每次表都会重新生成-->
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <prop key="hibernate.format_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    <!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
   </props>
  </property>
</bean>

<!--声明式事务-->
 <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
<!--对事务进行管理,hibernate有五种事务机制,这里不一一说明,read-only="true"式只读事务,只能读,不能修改,name="login*"这里也使用了通配符-->
<tx:advice id="txadvice" transaction-manager="txManager">
  <tx:attributes>
   <tx:method name="login*" propagation="REQUIRED" rollback-for="java.lang.Exception" read-only="true"/>
   <tx:method name="query*" propagation="REQUIRED" rollback-for="java.lang.Exception" read-only="true"/>
   <tx:method name="Add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
   <tx:method name="get*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
   <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
   <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
   <tx:method name="del" rollback-for="java.lang.Exception"/>
  </tx:attributes>
 </tx:advice>
 <!--通过AOP进行事务增强,主要用于DAO层,expression="execution(* dao.*.*(..))"这里使用了通配符-->
<aop:config>
  <aop:pointcut id="allTestServiceMethod" expression="execution(* dao.*.*(..))"/>
  <aop:advisor pointcut-ref="allTestServiceMethod" advice-ref="txadvice" />
</aop:config>

<!--struts2.xml配置-->
<!--交由spring管理,高版本的struts2默认就是交给spring管理,可以打开struts的配置文件查看-->
<constant name="struts.objectFactory" value="spring"/>
<!--这里的action有两种写法-->
<!--第一种,action对应的类不用写出完全限定名,但是在applicationContext.xml里面的bean就是这里的类的名字,bean所对应的类需要写出完全限定名-->
<action name="loginAction" class="loginAction">
   <result name="success">loginOk.jsp</result>
   <result name="ERROR">index.jsp</result>
</action>

<!--第二种,action对应的类写出完全限定名,但是在applicationContext.xml里面的bean就是引用struts.xml的action的名字-->
<action name="loginAction" class="loginAction">
   <result name="success">loginOk.jsp</result>
   <result name="ERROR">err.jsp</result>
</action>
<!--DAO,BIZ,Service,impl全部都写在bean里面-->


以上就是SSH整合。SSH整合需要下载相应jar包。
如有错误,请指正。










































































































































以上是关于hibernate+spring+struts2整合的主要内容,如果未能解决你的问题,请参考以下文章

createSQLQuery is not valid without active transaction解决方法

spring 学习之三(spring 与hibernate, struts2整合)

Struts2 + Spring + Hibernate 分页

Struts2+Spring+Hibernate(SSH)框架的搭建

struts2集成Spring,Hibernate的问题!!

Spring:Spring整合Hibernate,之后整合Struts2