java WEB开发中Struts2+Spring+Hibernate 设计模式

   

一、            Struts2技术

                                                                                                                                                                                        

Struts2是一个典型的MVC架构,给软件开发带来很大的方便。

MVC是一种设计模式,它强制性地使应用程序的输入、处理和输出分开。使用MVC模式,应用程序被分成三个核心部件:模型(Model,即M)、视图(View,即V)、控制器(Controller,即C)。它们各自处理自己的任务。

在Struts2中,其中M(业务层)用Java程序(业务类)来实现,V(表示层)用JSP来实现,C用Action类来实现。

 

1.浏览器发出的请求可以用下列方式:

1)     提交HTML网页form表单

<form action="login" method="GET">

     name: <input type="text" name="name"><br>

     pass: <input type="password" name="pass"><br>

     <input type="submit" value="submit">

       </form>

2)     直接在地址栏输入

http://localhost:8080/login?name=abc&pass=123

3)     点击超链接

       <html><body>

       <a href="login?name=abc&pass=123">test</a>

       </body></html>

在struts2编程中login只是请求的逻辑名字,而不是具体的jsp或servlet。

 

2.过滤器根据请求和Struts.xml配置文件去调用对应的Action

Strtuts2本质上是一个过滤器,所以需要在web.xml中配置一个Struts2的过滤器。具体配置如下:

<filter>

<filter-name>struts2</filter-nam<filter-class>org.apache.struts2.dispatcher.n.filter.StrutsPrepareAndExecuteFilter</filter-class>

</filter>

<filter-mapping>

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

                 <url-pattern>/*</url-pattern>

  </filter-mapping>

struts.xml是Struts2非常重要的配置文件,在项目的src下创建一个文件struts.xml,其内容如下:

<?xml version="1.0" encoding="GBK"?>

<!DOCTYPE struts PUBLIC

  "-//Apache Software Foundation//DTD Struts Configuration 2.0 //EN"

  "resources/struts-2.1.7.dtd">

<struts>

<constant name="struts.i18n.encoding" value="gbk"></constant>

<package name="team" extends="struts-default">

<action name="login" class="Longin">

<result name="success">/Success.jsp</result>

<result name="error">/Fail.jsp</result>

</action>

</package>

</struts>

请求Action的逻辑名字与Action类的对应关系在这里设定,如:login是逻辑名,Longin是处理请求的实际的Action类名,Struts2过滤器根据请求的逻辑名和struts.xml配置文件调用对应的Action类, Action类中必须有一个execute()方法。

浏览器发出的请求首先经过Struts2过滤器,Struts2过滤器根据请求和Struts2的配置文件调用对应的Action,Action调用执行业务类的方法,然后转发到JSP页面向客户端显示结果。

3.调用业务类

Action类只负责处理请求,通常不处理事务,在Action类的execute()方法中可以调用业务类的方法,业务类负责处理事务,如访问数据库等等。

4.转发

Action类也不显示结果,在Action类的execute()方法返回一个字符串,这个字符串可以是success或error,Struts2过滤器根据success或error转发到指定的JSP页面。

5.应答

JSP负责页面向客户端显示结果。

 

 

二、            Spring技术

 

Spring技术的核心是反向控制(IoC,Inverse of Control),也称为依赖注入(DI,Dependence Injection)。

 

反向控制(IoC),就是由容器控制程序之间的关系,而不是由程序代码直接操控。控制权从应用代码转到了外部容器,控制权的转移,就是反向控制。

 

依赖注入(DI),是这种设计理念的另一种描述。依赖注入是指组件间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。

 

Spring本质上是一个监听器,所以需要在web.xml中配置一个Spring监听器。具体配置如下:

 

<listener>

 

<listener-class>org.springframework.web.context.ContextLoaderListener

 

</listener-class>

 

</listener>

 

在Struts2中,在Action类的execute()方法中可以调用业务类的方法,业务类负责处理事务,当需要更换业务类时,Action类也必须随之修改,这是一件麻烦事。

 

利用Spring技术在Action类的execute()方法中不是直接调用业务类的方法,而是调用业务接口方法,也就是在Action类中使用的是接口,当需要更换业务类时,只要新业务类实现这个接口,然后在Spring的applicationContext.xml配置文件中,添加一个<bean />标签,其中属性id的值是接口,属性class的值是实现这个接口的类,如下所示:

 

<?xml version="1.0" encoding="UTF-8"?>

 

<beans

 

xmlns="http://www.springframework.org/schema/beans"

 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 

<bean id="teamService" class="business.TeamBusinessHibernate" />

 

<bean id="adminService" class="business.AdminBusiness" />

 

</beans>

 

applicationContext.xml是Spring的配置文件,在程序运行时根据这个配置文件注入相应的组件。

 

在Action类中创建ApplicationContext对象读取applicationContext.xml内容:

 

ApplicationContext ctx =

 

new ClassPathXmlApplicationContext("applicationContext.xml");

 

 

 

再用这个对象获取实现这个接口的类的实际对象。

 

teamService =(TeamService)ctx.getBean("teamService");

 

这样利用Spring技术可以在更换业务类时,不再需要修改Action类。

 

三、            Hibernate

 

Hibernate就是一种提供了对象关系映射(Object Relational Mapping)解决方案,就是将关系数据库中的表映射成为对象,把对数据库的操作转化为对象的操作,访问数据库不需要再使用SQL语句。

 

 

 

 

 

1.   添加jar文件

 

打开前面我们做的小组管理系统的项目,把Hibernate软件包里的hibernate3.jar添加到项目里。

 

2.   映射文件

 

每个和数据库的表对应的Java类都要有一个映射文件,指定类和表的对应关系,以及类的属性和表的列的对应关系。

 

在包bean里为Team类建立一个映射文件Team.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 package="bean">

 

         <class name="Team" table="team">

 

                   <id name="id" column="id">

 

                            <generator class="identity"/>

 

                   </id>

 

                   <property name="name"/>

 

                   <property name="leader"/>

 

                   <property name="slogan"/>

 

         </class>

 

</hibernate-mapping>

 

其中<class name="Team" table="team">指定了类和表的对应关系。

 

id元素是对类的标识符属性的声明,<id name="id" column="id">声明了类的标识符属性及其对应的数据库中表的列。generator元素指定了标识符的生成策略,<generator class="identity"/>指定了标识符由数据库自动生成。

 

property元素声明了类的属性及其对应的数据库中表的列,如果没有用column明确声明数据库中表的列,意味着数据库中表的列与类的属性同名。<property name="leader"/>声明了类Team的属性leader,对应数据库表team的列leader。

 

3.   Hibernate配置文件

 

Hibernate项目需要一个配置文件,用来设置数据库的连接信息以及其他一些全局的信息。

 

在src下创建一个文件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的工厂 -->

 

    <session-factory>

 

    <!-- 连接数据库的URL -->

 

    <property name="connection.url">jdbc:odbc:un</property>

 

    <!-- 连接本机数据库用户名 -->

 

   

 

    <!-- 连接数据库的驱动类 -->

 

    <property name="connection.driver_class">sun.jdbc.odbc.JdbcOdbcDriver</property>

 

    <!-- 数据库方言 -->

 

    <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>

 

    <!-- 类与表的映射文件在这里注册 -->

 

    <mapping resource="bean/Team.hbm.xml" />

 

    </session-factory>

 

</hibernate-configuration>

 

4.   创建辅助类

 

Hibernate需要一个全局的SessionFactory对象,SessionFactory对象可以创建并打开新的Session对象。一个Session对象代表一个单线程的单元操作。SessionFactory是一个线程安全的全局对象,只需要被实例化一次。

 

我们创建一个包util,在包util里创建一个辅助类HibernateUtil,创建SessionFactory对象,并提供获取SessionFactory对象的方法,内容如下:

 

package util;

 

import org.hibernate.SessionFactory;

 

import org.hibernate.cfg.Configuration;

 

public class HibernateUtil {

 

         private static final SessionFactory sessionFactory = buildSessionFactory();

 

         private static SessionFactory buildSessionFactory() {

 

                   try {

 

                            //根据hibernate.cfg.xml创建SessionFactory

 

                            return new Configuration().configure().buildSessionFactory();

 

                   }

 

                   catch(Throwable ex) {

 

                            System.err.println("Initial SessionFactory creation failed." + ex);

 

                            throw new ExceptionInInitializerError(ex);

 

                   }

 

         }

 

         public static SessionFactory getSessionFactory() {

 

                   return sessionFactory;

 

         }

 

 

 

}

 

这个辅助类在静态的初始化过程产生全局的SessionFactory对象,并提供了获取SessionFactory对象的方法getSessionFactory。

 

5.   用Hibernate实现增、删、改、查

 

在包business里创建一个类TeamBusinessHibernate,实现接口TeamService,内容如下:

 

package business;

 

import java.util.Collection;

 

import java.util.List;

 

import org.hibernate.*;

 

import bean.Team;

 

import service.TeamService;

 

import util.HibernateUtil;

 

public class TeamBusinessHibernate implements TeamService {

 

         private Session session;

 

         public TeamBusinessHibernate() {

 

                   SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

 

                   session = sessionFactory.openSession();

 

         }

 

         @Override

 

         public void addTeam(Team team) throws Exception {

 

                   Transaction trans = session.beginTransaction();

 

                   session.save(team);

 

                   trans.commit();

 

         }

 

 

 

         @Override

 

         public Collection<Team> allTeams() throws Exception {

 

                   session.clear();

 

                   String hql = "from Team";

 

                   Query query = session.createQuery(hql);

 

                   List<Team> teams = query.list();

 

                   return teams;

 

         }

 

 

 

         @Override

 

         public void deleteTeam(Team team) throws Exception {

 

                   Transaction trans = session.beginTransaction();

 

                   String hql = "delete Team where id=?";

 

                   Query query = session.createQuery(hql);

 

                   query.setInteger(0, team.getId());

 

                   query.executeUpdate();

 

                   trans.commit();

 

         }

 

 

 

         @Override

 

         public Team getTeamById(int id) throws Exception {

 

                   session.clear();

 

                   Team team = null;

 

                   String hql = "from Team where id=?";

 

                   Query query = session.createQuery(hql);

 

                   query.setInteger(0, id);

 

                   team = (Team)query.uniqueResult();

 

                   return team;

 

         }

 

 

 

         @Override

 

         public Team getTeamByName(String name) throws Exception {

 

                   session.clear();

 

                   Team team = null;

 

                   String hql = "from Team where name=?";

 

                   Query query = session.createQuery(hql);

 

                   query.setString(0, name);

 

                   team = (Team)query.uniqueResult();

 

                   return team;

 

         }

 

 

 

         @Override

 

         public void modifyTeam(Team team) throws Exception {

 

                   Transaction trans = session.beginTransaction();

 

                   String hql = "update Team set name=?,leader=?,slogan=? where id=?";

 

                   Query query = session.createQuery(hql);

 

                   query.setString(0, team.getName());

 

                   query.setString(1, team.getLeader());

 

                   query.setString(2, team.getSlogan());

 

                   query.setInteger(3, team.getId());

 

                   query.executeUpdate();

 

                   trans.commit();

 

         }

 

 

 

}

 

这个类定义了一个属性session,用来进行各种操作。

 

posted @ 2012-05-14 22:55  ydx926  阅读(657)  评论(0编辑  收藏  举报