实习总结(十四)---S2SH整合开发

       我们实习的时间总共有一个,现在转眼三个月已经过去了。其实这一个周的时间已经是自己支配了,下一个周也是吧。当然我们不是玩儿了,而是更加的辛苦,得花更多的精力与时间了。因为在实习结束的时候,如果拿不出一份自己的作品。那就惨了,所以咧。。。我们的最终作品是开发一个OA办公业务系统,我以前的文章里面有这个系统的介绍,在这里给出该系统的结构图:

实习总结(十四)---S2SH整合开发_第1张图片

(我把图片保存以后上传就是黑色背景,上一次都不是这样的,有一点不美观)

       写这一篇文章的目的不是介绍这个OA系统,是想对开发中用到的S2SH技术加以总结,以便自己日后复习也方便大家参考。

+===========================================================================================+

      首先先给出一幅大家应该理解的系统结构图:

    实习总结(十四)---S2SH整合开发_第2张图片

           上面这一幅图在J2EE结构中下面几个层面的关系:

          

表现层:由JSP页面组成。
MVC层:使用Struts 2框架技术。
业务逻辑层:使用业务逻辑组件构成。
DAO层:使用DAO组件构成。
Hibernate持久层:使用Hibernate框架技术。
数据库层:使用MySQL数据库存储数据。

 

 

 

 

 

      <!--  由于结合这三者开发项目相对更加容易,方便了向我们这种不太愿意花时间写一些废代码的人。-->

 

      <!--Spring+Hibernate+Struts2整合开发-->

一、 Spring+Hibernate整合:

Spring整合Hibernate,是做了一个很大的调整的,因为spring可以把管理Hibernate的工作都做了,以前的hibernate.cfg.xml文件都去掉了,而将这些内容都交给了spring来管理了。

1、 applicationContext.xml文件中应该配置如下内容:

 

//配置数据连接类

<bean id="dataSource"

class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName"

value="org.gjt.mm.mysql.Driver">

</property>

<property name="url" value="jdbc:mysql://localhost:3306/test"></property>

<property name="username" value="root"></property>

</bean>

//配置session工厂类

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref bean="dataSource" />

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">

org.hibernate.dialect.MySQLDialect

</prop>

<prop key="hibernate.show_sql">true</prop>

</props>

</property>

<property name="mappingResources">

 <value>com/hejianjiao/vo/Person.hbm.xml</value>

</property>

</bean>

2、可以使用spring中的HibernateDAOSupportHibernateTemplate类来进行数据持久化操作:

AHibernateDAOSupport类中定义了对sessionsessionFactory的操作方法与getHibernateTemplate方法来获得一个HibernateTemplate实例; 

BHibernateTemplate类中定义了对数据持久化的各种封装的方法,我们可以用它来对数据进行操作。

因此在使用时,我们可以继承HibernateDAOSupport类,然后实例化HibernateTemplate类来进行数据持久化。

二、 Spring+Struts2整合:

1spring配置在web.xml文件中的上下文监听器:

 

<context-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>/WEB-INF/applicationContext*.xml</param-value>

</context-param>

<listener>

<listener-class>org.springframwork.web.content.ContextLoaderListener</listener-class>

</listener>

2struts2配置在web.xml文件中的过滤器:

 

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

</filter>

<filter-mapping>

  <filter-name>struts2</filter-name>

  <url-patter>/*</url-patter>

</filter-mapping>

3、设置struts.xml文件,就可以使用springIOC来管理strutsAction

 

<content name="struts.objectFactory" value="spring" >

4、第三步设置后,以后在struts.xml 文件中配置一个action时,它的class就不是一个类了,而是在applicationContext.xml文件中定义过的类的ID,struts.xml文件中就只需要引用定义好的类的id 就可以了。

然后特别要注意的一个问题:action是一个请求就是一个action对象,而在spring中则不是的,它是自动分配类的实例的,是使用的单态模式来生产类的实例的,不符合action,因此在applicationContext.xml文件中定义每个action时,都要在类后加上:

 

scope="prototype" 属性

 来标明才不会出错。

三、 三者组合开发:

一般在组合开发时,没有什么难的,只要把上面两步做好就可以是三个组合开发了。

这里有一个公式:(Spring+Hibernate)  +   (Spring+Struts2)  =   (Spring+Hibernate+Struts2)

四、 组合开发架构细节

1、 先从最底层开发,先开发POJO类,和Hibernate映射文件。它相当于系统的数据库层。

2、 再开发DAO层,它是对于数据进行持久化的一层,专门处理各种数据增、删、改、查的功能。并且使用DAO工厂模式,以保证和上层没有任何的联系,并且可以方便于类与接口的扩展。

3、 第三是开发manager层,它相当于软件的业务逻辑层,即专门处理各种业务逻辑。实现系统的业务处理功能。并且它隔离事务,使与下层的数据持久和上层的数据操作没有任何的联系。

4、 Action层,也即软件的表示层,处理action的接收与回复。各actionspring管理。

五、 组合开发中的一些问题:

1、 在组合开发中,常见的一个问题就是session的管理,当我们使用HibernateTemplate操作数据库时,可以不对session进行显示的操作,spring可以自动处理session的打开与关闭。

我们可以在web.xml文件中显示的配置一个session管理的过滤器,它专门帮助我们关闭session

<filter>

        <filter-name>lazyLoadingFilter</filter-name>

<filter-class>

org.springframwork.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

</filter>

<filter-mapping>

         <filter-name>lazyLoadingFilter</filter-name>

         <url-pattern>*.action</url-pattern>

</filter-mapping>

注:它一定要在struts2的过滤器之前。因为web.xml文件的过滤器执行是有顺序的。而session一定在前面进行。

它会在所有的action处理完了,页面显示完了,就会自动关闭session

六、 spring事务处理

1、事务的处理也交给了spring来管理,要在applicationContext.xml文件中上配置事务管理类:

//实施事务管理的bean

<bean id=”transactionManager” 

class=”org.springframwork.orm.hibernate3.HibernateTransactionManager”>

       <property name=”sessionFactory”>

           <ref bean=”sessionFactory” />

</property>

</bean>

它是通过sessionFactory来管理,因此在传进来一个sessionFactory来接管事务处理。

2、 声明式事务处理:

spring中对事务进行管理时,可以显示地进行事务处理的定义:

 

对于事务的其它传播属性,则可以参考其它文档进行相关的了解。

//给事务添加的属性

<tx:advice id=”txAdvice” transaction-manager=”transactionManager”>

     <tx:attributes >

//propagation表示的是事务的传播特性,使用required时,是当检测到add开头的方法时,就看此时有没有开启的事务,如果有则将方法放进事务中去,如果没有,则新建一个事务。然后将方法放进去。

          <tx:method name=”add*” propagation=”REQUIRED”>

          <tx:method name=”delete*” propagation=”REQUIRED”>

           <tx:method name=”update*” propagation=”REQUIRED”>

//如果检测到其它的方法,则给其只读数据库的属性。即当本方法在读时,其它的方法不能再去写了。保证一个事务的完整性。

           <tx:method name=”*” read-only=”true”>

</tx:attributes>

</tx:advice>

      上一个配置是针对于所有包中类的事务处理方法的设置。下面一段是<aop:config/> 的定义,它确保由 'txAdvice' bean定义的事务通知在应用中合适的点被执行。首先我们定义了 一个切面,它匹配 HibernateDAO 接口定义的所有操作,我们把该切面叫做 'allManagerMethod'。然后我们用一个通知器(advisor)把这个切面与 'txAdvice' 绑定在一起,表示当 'allManagerMethod' 执行时,'txAdvice' 定义的通知事务逻辑将被执行。这就是AOP切面工程:

 

<aop:config>

      <aop:pointcut id=”allManagerMethod” 

expression=”execution(*  com.hejianjiao.hibernate.HibernateDAO.*(..))”/>

//调用上面配置的事务属性,可以将它给本aop pointcut。

      <aop:advisor advice-ref=”txAdvice” pointcut-ref=”allManagerMethod”/>

//如果还有其它的定义,则可以再加上pointcut、advisor来定义本切面点的事务逻辑。

</aop:config>


//expression中的内容是要执行本切面的一个接口,中的所有方法:如:一个接口中定义了操作数据的方法:com.hejianjiao.hibernate.HibernateDAO,则下面execution括号中的内容就为:* com.hejianjiao.hibernate.HibernateDAO.*(..)。而如果在com.hejianjiao.hibernate包中还有其它的类也有操作方法,我们要一起定义的话,就可以写为:*  com.hejianjiao.*.*(..),其中(..)表示的是方法,前面的第一个*是操作的接口或者类。

上面的配置将为由 'HibernateDAO' 定义的bean创建一个代理对象,这个代理对象被装配了事务通知,所以当它的相应方法被调用时,一个事务将被启动、挂起、被标记为只读,或者其它(根据该方法所配置的事务语义)。

3、编程式事务处理:

这个方法是使用注入的方式来对事务进行限制操作,使用TransactionTemplatePlatformTransactionManager类进行方法的限制。

1、 第一种方式使用TransactionTemplate

2、 第二种方是式是使用PlatformTransactionManager

七、 注意的问题:

在整合了strutsspring后,它的bean都交给了spring了,就让我们在类中不需要再去实例化,可以直接使用,而且在strutsaction中,对于数据的表单的接收都使用了对象的形式来进行操作,不需要再支操作对象中的属性了,如:

public class EmployeeAction extends ActionSupport {

 /**

  * 对Employee对象进行操作的action类

  * 

  * @author 陆健美

  */


 /**

  * 引入EmployeeManager 接口对象

  */

 private EmployeeManager employeeManager;

 private Employee employee;

 private String id;

 private List employees;

 /**

  * 添加Employee对象

  * 

  * @return 根据返回值来确定action的跳转

  */

 public String saveEmployee() throws Exception {

 if (employeeManager.saveEmployee(employee)) {

 return SUCCESS;

 } else {

 this.addFieldError("name", "对象保存失败!");

return "fail";

 }

 }

 /**

  * 删除Employee对象

  * 

  * @return 根据返回值来确定action的跳转

  */

 public String deleteEmployee() throws Exception {

 if (employeeManager.deleteEmployee(id)) {

 return SUCCESS;

 } else {

 this.addFieldError("name", "对象删除失败!");

return "fail";

 }
}


 /**

  * 更新Employee对象

  * 

  * @return 根据返回值来确定action的跳转

  */

 public String updateEmployee() throws Exception {

 employee = this.getEmployee();

 if (employeeManager.updateEmployee(employee)) {

 return SUCCESS;

 } else {

 this.addFieldError("name", "更新对象失败!");

return "fail";

 }

 }


 /**

  * 查看所有Employee列表

  * 

  * @return 根据返回值来确定action的跳转

  */

 public String getAllEmployee() throws Exception {

 employees = employeeManager.getAllEmployee();

 return SUCCESS;

 }


 /**

  * 根据ID获取Employee对象

  * 

  * @return 根据返回值来确定action的跳转

  */

 public String editEmployee() throws Exception {

 employee = employeeManager.getEmployeeById(id);

 return SUCCESS;

 }


 @Override

 public void validate() {

 // TODO Auto-generated method stub

 super.validate();

 }


 public String getId() {

 return id;

 }


 public void setId(String id) {

 this.id = id;

 }


 public List getEmployees() {

 return employees;

 }


 public void setEmployees(List employees) {

 this.employees = employees;

 }


 public Employee getEmployee() {

 return employee;

 }


 public void setEmployee(Employee employee) {

 this.employee = employee;

 }


 public void setEmployeeManager(EmployeeManager employeeManager) {

 this.employeeManager = employeeManager;

 }
}

       对于页面的接收,我们可以直接使用对象进行接收,也直接使用对象进行操作,spring 会自动给我们set进对象中去。

 

 


你可能感兴趣的:(实习总结(十四)---S2SH整合开发)