框架学习之Spring 第五节 SSH整合开发[Spring2.5+Hibernate3.3+Struts2]

来源:互联网 发布:什么软件可以测手速 编辑:程序博客网 时间:2024/06/05 12:42

1.首先整合Spring和Hibernate

①引入jar包:

hibernate核心安装包下的:

hibernate3.jar

lib\required\*.jar

lib\optional\ehcache-1.2.3.jar

hibernate 注解安装包下的

lib\test\slf4j-log4j12.jar

Spring安装包下的:

dist\spring.jar

dist\modules\spring-webmvc-struts.jar

lib\jakarta-commons\commons-logging.jar、commons-dbcp.jar、commons-pool.jar

lib\aspectj\aspectjweaver.jar、aspectjrt.jar

lib\cglib\cglib-nodep-2.1_3.jar

lib\j2ee\common-annotations.jar

lib\log4j\log4j-1.2.15.jar

 

数据库使用mysql:

添加 Mysql 驱动包  mysql-connector-java-5.1.16-bin.jar

 

后面还要进行单元测试,所以还有引入 junit4.jar,当然这个可以在后面由 Myeclipse 来进行,安装时已经有了这个jar包,Myeclipse会自动引入

 

②数据源配置的文件: jdbc.properties (放在src目录下)

driverClassName=org.gjt.mm.mysql.Driverurl=jdbc\:mysql\://localhost/hibernateusername=rootpassword=yingerinitialSize=1maxActive=500maxIdle=2minIdle=1

 

③Spring中的beans.xml (示例的最终版,放在src目录下)

<?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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">    <!-- 开启注解方式进行bean的管理和依赖注入 -->    <context:annotation-config/>        <!-- 数据源配置的文件的位置 -->    <context:property-placeholder location="jdbc.properties" />        <!-- 定义数据源 -->    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"        destroy-method="close">        <property name="driverClassName" value="${driverClassName}" />        <property name="url" value="${url}" />        <property name="username" value="${username}" />        <property name="password" value="${password}" />        <!-- 连接池启动时的初始值 -->        <property name="initialSize" value="${initialSize}" />        <!-- 连接池的最大值 -->        <property name="maxActive" value="${maxActive}" />        <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->        <property name="maxIdle" value="${maxIdle}" />        <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->        <property name="minIdle" value="${minIdle}" />    </bean>    <!-- 定义sessionFactory -->    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">        <property name="dataSource" ref="dataSource" />        <property name="mappingResources">            <list>                <value>com/yinger/domain/Person.hbm.xml</value>            </list>        </property>        <property name="hibernateProperties">            <value>                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect                hibernate.hbm2ddl.auto=update                hibernate.show_sql=true                hibernate.format_sql=false          </value>        </property>    </bean>        <!-- 定义事务管理器:此处的含义就是下面的事务管理器管理由sessionFactory创建的session -->    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">        <property name="sessionFactory" ref="sessionFactory" />    </bean>         <!--  开启注解方式使用事务  -->    <tx:annotation-driven transaction-manager="txManager" />        <!-- Spring管理的bean -->    <bean id="personService" class="com.yinger.service.impl.PersonServiceBean"></bean>    </beans>

④测试 Spring 和 Hibernate  的整合是否成功

新建domain对象:Person

package com.yinger.domain;public class Person {    private int id;    private String name;        public Person(){}        public Person(String name){        this.name = name;    }        public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    }

新建Person的映射文件: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="com.yinger.domain">    <class name="Person">        <id name="id">            <generator class="native" />        </id>        <property name="name" />    </class></hibernate-mapping>

新建业务层接口:PersonService

package com.yinger.service;import java.util.List;import com.yinger.domain.Person;public interface PersonService {    public void save(Person p);        public void update(Person p);        public void delete(int personid);        public Person getPerson(int personid);        public List<Person> getPersons();    }

新建上面的接口的实现类:PersonServiceBean

package com.yinger.service.impl;import java.util.List;import javax.annotation.Resource;import org.hibernate.SessionFactory;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.yinger.domain.Person;import com.yinger.service.PersonService;@Transactionalpublic class PersonServiceBean implements PersonService{        private SessionFactory sessionFactory;        @Resource //属性的setter方法注入对象    public void setSessionFactory(SessionFactory sessionFactory) {        this.sessionFactory = sessionFactory;    }    //保存    public void save(Person p) {//建议使用persist方法,而不是save方法        sessionFactory.getCurrentSession().persist(p);    }    //更新    public void update(Person p) {//建议使用merge方法(把对游离态的对象的更新与数据库同步),而不是update方法        sessionFactory.getCurrentSession().merge(p);    }    //删除    public void delete(int personid) {//建议得到对象的方法使用load,免去数据封装的过程        sessionFactory.getCurrentSession().delete(sessionFactory.getCurrentSession().load(Person.class, personid));    }    //得到指定id的person    @Transactional(propagation=Propagation.NOT_SUPPORTED)    public Person getPerson(int personid) {        return (Person)sessionFactory.getCurrentSession().get(Person.class, personid);    }    //得到所有的person    @Transactional(propagation=Propagation.NOT_SUPPORTED)    @SuppressWarnings("unchecked")    public List<Person> getPersons() {        return (List<Person>)sessionFactory.getCurrentSession().createQuery("from Person").list();    }}

 

基于PersonServiceBean 进行单元测试,编写测试类

package junit.test;import java.util.List;import org.junit.BeforeClass;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.yinger.domain.Person;import com.yinger.service.PersonService;public class SSHTest {    public static PersonService personService;        @BeforeClass  //这个方法是在单元测试实例生成之后就会执行的方法,可以在里面写上一些初始化操作    public static void setUpBeforeClass() throws Exception {        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");        personService = (PersonService)ctx.getBean("personService");    }    @Test    public void testSave() {        for(int i=0;i<5;i++){            Person person = new Person("personname"+(i+1));            personService.save(person);                }    }    @Test    public void testUpdate() {        Person person = personService.getPerson(2);        person.setName("yinger");        personService.update(person);    }    @Test    public void testDelete() {        personService.delete(3);    }    @Test    public void testGetPerson() {        personService.getPerson(4);    }    @Test    public void testGetPersons() {        List<Person> list = personService.getPersons();        for(Person person:list){            System.out.println(person.getName());        }    }}

 

首先测试第一个方法,输出结果:

log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).log4j:WARN Please initialize the log4j system properly.Hibernate: insert into Person (name) values (?)Hibernate: insert into Person (name) values (?)Hibernate: insert into Person (name) values (?)Hibernate: insert into Person (name) values (?)Hibernate: insert into Person (name) values (?)

数据库中的数据

18

 

测试delete方法:

Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from Person person0_ where person0_.id=?Hibernate: delete from Person where id=?

19

测试update方法: 【我不清楚为什么这里会有两条select语句,应该是一条就可以了的啊,是不是merge方法的原因呢?望高手指点!】

Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from Person person0_ where person0_.id=?Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from Person person0_ where person0_.id=?Hibernate: update Person set name=? where id=?
20

 

测试getPersons方法(getPerson就不用了)

Hibernate: select person0_.id as id0_, person0_.name as name0_ from Person person0_personname1yingerpersonname4personname5

数据库数据保持不变

从上面的测试中,我们可以看出,Spring 和 Hibernate 整合成功了!

接下来做 Hibernate中二级缓存的配置

在beans.xml中关于sessionFactory的配置中添加以下设置,最后如下所示:(假设二级缓存使用的是EhCacheProvider )

        <property name="hibernateProperties">            <value>                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect                hibernate.hbm2ddl.auto=update                hibernate.show_sql=true                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>

 

然后,自然要在Hibernate下载包中找到与EhCache缓存相关的jar包, 添加进去,然后找到EnCache的配置文件:encache.xml

<?xml version="1.0" encoding="UTF-8"?><!--     defaultCache节点为缺省的缓存策略     maxElementsInMemory 内存中最大允许存在的对象数量     eternal 设置缓存中的对象是否永远不过期     overflowToDisk 把溢出的对象存放到硬盘上     timeToIdleSeconds 指定缓存对象空闲多长时间就过期,过期的对象会被清除掉     timeToLiveSeconds 指定缓存对象总的存活时间     diskPersistent 当jvm结束是是否持久化对象     diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间 --><ehcache>    <diskStore path="D:\cache"/>    <defaultCache  maxElementsInMemory="1000" eternal="false" overflowToDisk="true"        timeToIdleSeconds="120"        timeToLiveSeconds="180"        diskPersistent="false"        diskExpiryThreadIntervalSeconds="60"/>    <cache name="com.yinger.domain.Person" maxElementsInMemory="100" eternal="false"    overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskPersistent="false"/></ehcache>

 

如上所示,cache标签中就可以添加需要使用二级缓存的类了

当然,也可以在类的映射文件中添加,例如在 Person.hbm.xml 中添加:

    <class name="Person">        <cache usage="read-write" region="com.yinger.domain.Person"/>        <id name="id">            <generator class="native" />        </id>        <property name="name" />    </class>

region的解释:Hibernate为每个实体类创建一个Region作为缓存区, 默认情况下使用类的全路径名做为这个Region的名称

这样同样可以使得Person可以使用二级缓存

 

2.整合Spring 和 Struts2

①引入jar包:

使用到struts2的lib目录下所有不带-plugin结尾的jar文件,但除了struts2-spring-plugin-2.0.11.1.jar

 

②在web容器中实例化spring容器和配置struts2

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">    <!-- 指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下寻找 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:beans.xml</param-value>    </context-param>    <!-- 对Spring容器进行实例化 -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- 配置struts2:注意struts1和struts2中的filter-class配置是不同的 -->    <filter>        <filter-name>struts2</filter-name>        <!--         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>         -->         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>    </filter>    <filter-mapping>        <filter-name>struts2</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

③配置struts2,编写struts.xml,我这里是包含了另外两个xml文件:

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <include file="strutsconstant.xml"></include>    <include file="strutspackage.xml"></include>    </struts>

strutsconstant.xml:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <!-- 配置一些常量值 constant -->    <!-- 通常,struts2按如下搜索顺序加载struts2常量:        struts-default.xml        struts-plugin.xml        struts.xml        struts.properties        web.xml        如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值.     -->    <!-- 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出 -->    <constant name="struts.i18n.encoding" value="UTF-8"/>    <!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理        如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 -->    <constant name="struts.action.extension" value="action,do"/>    <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->    <constant name="struts.serve.static.browserCache" value="false"/>    <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->    <constant name="struts.configuration.xml.reload" value="true"/>    <!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->    <constant name="struts.devMode" value="true" />    <!-- 默认的视图主题 -->    <constant name="struts.ui.theme" value="simple" />    <!-- 与spring集成时,指定由spring负责action对象的创建 -->    <constant name="struts.objectFactory" value="spring" />     <!-- 该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false -->     <constant name="struts.enable.DynamicMethodInvocation" value="false"/>    </struts>

strutspackage.xml:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <package name="person" namespace="/person" extends="struts-default">        <global-results>            <result name="message">/WEB-INF/page/message.jsp</result>        </global-results><!-- 这里使用了通配符,调用的方法名正是通配符中的字符串,class是交给Spring管理的bean(class名是bean的name或者id) -->        <action name="action_*" class="personAction" method="{1}">            <result name="list">/WEB-INF/page/persons.jsp</result>        </action>    </package></struts>

④在Spring的bean管理中添加一个新的bean:

<bean id="personAction" class="com.yinger.web.action.PersonAction"></bean>

注意:这个bean的id 对应struts中定义的action中的class名称

 

以下是测试:

⑤新建action:PersonAction

package com.yinger.web.action;import java.util.List;import javax.annotation.Resource;import com.yinger.domain.Person;import com.yinger.service.PersonService;public class PersonAction {        //由于这个类已经交给了Spring管理,所以可以使用Spring的依赖注入功能注入personService    //并且personService也已经交给了Spring管理    @Resource private PersonService personService;    private String message;    private List<Person> persons;        public String list(){        this.persons = personService.getPersons();        return "list";    }        public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }    public List<Person> getPersons() {        return persons;    }    public void setPersons(List<Person> persons) {        this.persons = persons;    }    }

 

⑥新建两个jsp,在WEB-INF目录下的page文件夹中

message.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>My JSP 'message.jsp' starting page</title>  </head>    <body>    <s:property value="message"/>  </body></html>

persons.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>人员列表</title>  </head>    <body>    <s:iterator value="persons">        id=<s:property value="id"/>---name=<s:property value="name"/><br/>    </s:iterator>  </body></html>

好了,一切OK!部署应用,然后启动Tomcat服务器(我的是Tomcat 6.0),最好要保证控制台没有报错,不然就要检查!

2011-8-26 21:59:00 org.apache.catalina.core.AprLifecycleListener init信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: 
D:\Program Files\MyEclipse Blue Edition\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\bin;D:\Program Files\Tomcat 6.0\bin2011-8-26 21:59:00 org.apache.coyote.http11.Http11Protocol init信息: Initializing Coyote HTTP/1.1 on http-80802011-8-26 21:59:00 org.apache.catalina.startup.Catalina load信息: Initialization processed in 1408 ms2011-8-26 21:59:00 org.apache.catalina.core.StandardService start信息: Starting service Catalina2011-8-26 21:59:00 org.apache.catalina.core.StandardEngine start信息: Starting Servlet Engine: Apache Tomcat/6.0.162011-8-26 21:59:04 org.apache.catalina.core.StandardContext addApplicationListener信息: The listener "org.springframework.web.context.ContextLoaderListener" is already configured for this context. The duplicate definition has been ignored.log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).log4j:WARN Please initialize the log4j system properly.2011-8-26 21:59:05 org.apache.catalina.core.ApplicationContext log信息: Initializing Spring root WebApplicationContext2011-8-26 21:59:19 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info信息: Parsing configuration file [struts-default.xml]2011-8-26 21:59:19 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info信息: Unable to locate configuration files of the name struts-plugin.xml, skipping2011-8-26 21:59:19 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info信息: Parsing configuration file [struts-plugin.xml]2011-8-26 21:59:19 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info信息: Parsing configuration file [struts.xml]2011-8-26 21:59:21 org.apache.catalina.core.StandardContext addApplicationListener信息: The listener "wdlab.base.BSLoginListener" is already configured for this context. The duplicate definition has been ignored.2011-8-26 21:59:22 org.apache.coyote.http11.Http11Protocol start信息: Starting Coyote HTTP/1.1 on http-80802011-8-26 21:59:22 org.apache.jk.common.ChannelSocket init信息: JK: ajp13 listening on /0.0.0.0:80092011-8-26 21:59:22 org.apache.jk.server.JkMain start信息: Jk running ID=0 time=0/84  config=null2011-8-26 21:59:22 org.apache.catalina.startup.Catalina start信息: Server startup in 21866 ms

 

打开IE,测试结果: 成功的输出了刚才的数据库中的数据!

21

 

SSH整合成功了!Congratulations!

最终的项目目录结构如下图所示:

22

分类: 框架学习之Spring, 框架学习之Struts2, 框架学习之Hibernate

<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* csdn 横长 */google_ad_slot = "7322168821";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击