欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Ssi的整合(Struts2+Spring+Ibatis)

程序员文章站 2022-03-17 12:45:03
...

Ssi的整合(Struts2+Spring+Ibatis)

1 jar包的下载

         本文好用的三个框架版本分别为

         struts-2.3.8 spring-framework-3.0.5.RELEASEibatis-2.3.4.726

下载地址:struts

Struts2

http://archive.apache.org/dist/struts/binaries/struts-2.3.8-all.zip

Spring

http://www.springsource.org/spring-community-download(进入后需要录入信息后才能下载)

Ibatis

http://archive.apache.org/dist/ibatis/binaries/ibatis.java/ibatis-2.3.4.726.zip

 

2 程序搭建---Struts2

2.1首先在eclipse新建web工程,新建创建的web目录结构如下:

ssi-release

         |__compensate

         |___webapps

                   |___META-INF

                            |___MANIFEST.MF 

                   |___WEB-INF

                            |___classes

                            |___lib

                            |___web.xml

                   |___index.jsp

 

2.2拷贝Struts2基本的jar包到工程下的lib目录

commons-fileupload-1.2.2.jar

commons-io-2.0.1.jar

commons-lang3-3.1.jar

freemarker-2.3.19.jar

javassist-3.11.0.GA.jar

ognl-3.0.6.jar

struts2-core-2.3.8.jar

xwork-core-2.3.8.jar

log4j-1.2.15.jar(非必须,便于使用log4j所以此处添加本jar包)

2.3web.xml中添加Struts2的控制分发的Filter

    <filter>

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

        <filter-class>

            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

        </filter-class>

    </filter>

    <filter-mapping>

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

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

    </filter-mapping>

其中mapping<url-pattern>/*</url-pattern>表示过滤所有请求

 

2.3编写Struts2测试action

        创建com.jshand.ssi.action

        com.jshand.ssi.action包下创建TestAction类实现com.opensymphony.xwork2.Action接口

并实现方法execute方法,代码如下

package com.jshand.ssi.action;

 

import com.opensymphony.xwork2.Action;

 

/**

 *@file_nameTestAction.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun2,2013  12:37:18PM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicclass TestAction implements Action{

   

    public String actionStr = "com.jshand.ssi.action.TestAction";

   

    public String execute() throws Exception{

       System.out.println("execute Struts2 Action ......");

       returnSUCCESS;

    }

    public String getActionStr() {

       returnactionStr;

    }

 

    publicvoid setActionStr(String actionStr) {

       this.actionStr = actionStr;

    }

}

其中actionStr属性定义了一个字符串,并设置了setget方法目的是讲测试Struts2封装的参数传递,将接收的或者默认的字符串输出到jsp中。

2.3编写Struts2的配置文件struts.xml

在源文件目录(工程下compensate目录)创建struts.xml文件,

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

<!DOCTYPE struts PUBLIC  "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"

    "http://struts.apache.org/dtds/struts-2.3.dtd">

 

<struts>

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

        <action name="test" class="com.jshand.ssi.action.TestAction">

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

        </action>

    </package>

</struts>

主要配置xmlaciton节点,

name属性为自定义属性,同一个package不允许出现相同name

class属性为之前编写的TestAction的全路径

<action name="test" class="com.jshand.ssi.action.TestAction">

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

</action>

 

 

 

action子节点中添加一个result节点当执行完Action后跳转到index.jsp中,在index.jsp中添加如下代码${actionStr},使输入的参数或这作用域内的属性输出到index.jsp

<body>

    This is my JSP page. <br>

    ${actionStr}

  </body>

启动中间件,本文用到的是tomcat6,在浏览器中输入

http://localhost:8080/ssi-release/test.action?actionStr=testParameter

控制台输出如下:


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

 

浏览器跳转到index.jsp,并输出接受到的参数


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

说明Struts2配置成功!接下来我们整合SpringStruts2

3 程序搭建---整合SpringStruts2

Struts2一样大多数框架的第一个步骤都是拷贝jar包到工程中,并配置环境变量 Spring所需要的包如下,其中struts2-spring-plugin-2.3.8.jar为整合struts2Spring的包,当然这个包不是必须的,我们可以通过其他方法进行处理。

aopalliance-1.0.jar

aspectj-DEVELOPMENT-20130313082900.jar

aspectjlib-1.5.2.jar

aspectjweaver.jar

commons-attributes-api.jar

commons-attributes-compiler.jar

commons-logging-1.1.1.jar

commons-logging.jar

org.springframework.aop-3.0.5.RELEASE.jar

org.springframework.asm-3.0.5.RELEASE.jar

org.springframework.aspects-3.0.5.RELEASE.jar

org.springframework.beans-3.0.5.RELEASE.jar

org.springframework.context-3.0.5.RELEASE.jar

org.springframework.context.support-3.0.5.RELEASE.jar

org.springframework.core-3.0.5.RELEASE.jar

org.springframework.expression-3.0.5.RELEASE.jar

org.springframework.instrument-3.0.5.RELEASE.jar

org.springframework.instrument.tomcat-3.0.5.RELEASE.jar

org.springframework.jdbc-3.0.5.RELEASE.jar

org.springframework.jms-3.0.5.RELEASE.jar

org.springframework.orm-3.0.5.RELEASE.jar

org.springframework.oxm-3.0.5.RELEASE.jar

org.springframework.test-3.0.5.RELEASE.jar

org.springframework.transaction-3.0.5.RELEASE.jar

org.springframework.web-3.0.5.RELEASE.jar

org.springframework.web.portlet-3.0.5.RELEASE.jar

org.springframework.web.servlet-3.0.5.RELEASE.jar

org.springframework.web.struts-3.0.5.RELEASE.jar

struts2-spring-plugin-2.3.8.jar

 

3.1web.xml中注册,应用程序启动时,Spring的监听器(Listener),其中context-param节点是初始化监听器的配置文件,即注册的bean从哪里获取,此处使用的是默认文件

WEB-INF

|___applicationContext.xml

 

    <!-- 指明spring配置文件在何处 -->

<!--

    <context-param>

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

       <param-value>classpath*:applicationContext*.xml</param-value>

    </context-param>

-->

    <listener>

       <listener-class>

           org.springframework.web.context.ContextLoaderListener

       </listener-class>

    </listener>

 

3.2编写测试用bean对象

         此处模仿MVC三层机制,Action中去调用业务辑层bean对象,此对象有Spring创建实例化,Action中只进行声明。

3.2.1编业务逻辑层的接口,遵照面向接口编程的思想,所有业务逻辑层的类,都抽象成接口。

         编写TestService接口如下

package com.jshand.ssi.service;

 

/**

 *@file_nameTestService.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun2,2013  2:08:53PM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicinterface TestService {

    publicvoid service();

}

 

3.2.2编写TestService的实现类TestServiceImpl代码如下:

package com.jshand.ssi.service;

 

/**

 *@file_nameTestServiceImpl.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun2,2013  2:08:53PM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicclass TestServiceImpl implements TestService {

   

    publicvoid service()throws Exception {

       System.out.println("this is service function ");

    }

}

 

3.3 编写Spring配置文件,并在配置文件中注册TestActionTestService实现类

    WEB-INF目录下创建aplicationContext.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:aop="http://www.springframework.org/schema/aop"

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

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

    xsi:schemaLocation="  

          http://www.springframework.org/schema/beans   

          http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

          http://www.springframework.org/schema/aop   

          http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  

          http://www.springframework.org/schema/tx   

          http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

     

 

    <bean id="testAction" class="com.jshand.ssi.action.TestAction">

       <property name="testService" ref="testService"></property>

    </bean>

   

    <bean id="testService" class="com.jshand.ssi.service.TestServiceImpl" />

   

</beans>

 

 

3.4TestAction中声明service的应用,并添加setget方法

声明的属性名称需要跟applicationContext.xml中注入的属性的那么相同

<property name="testService">testService</property>

TestActionexecute方法中添加service的调用,testService.service();

Execute方法如下:

    public String execute() throws Exception {

       System.out.println("execute Struts2 Action ...... && actionStr = "+actionStr);

      

         testService.service();

       returnSUCCESS;

    }

 

3.5 指定Struts2Action初始化由Spring接管

由于我们添加Spring依赖的jar包是已经将struts2-spring-plugin-2.3.8.jar添加到应用的环境变量中,该jar包中包含了如下的struts-plugin.xml

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

<!--

/*

 * $Id: struts-plugin.xml 1221225 2011-12-20 12:22:28Z jogep $

 *

 * Licensed to the Apache Software Foundation (ASF) under one

 * or more contributor license agreements.  See the NOTICE file

 * distributed with this work for additional information

 * regarding copyright ownership.  The ASF licenses this file

 * to you under the Apache License, Version 2.0 (the

 * "License"); you may not use this file except in compliance

 * with the License.  You may obtain a copy of the License at

 *

 *  http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing,

 * software distributed under the License is distributed on an

 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

 * KIND, either express or implied.  See the License for the

 * specific language governing permissions and limitations

 * under the License.

 */

-->

<!DOCTYPE struts PUBLIC

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

    "http://struts.apache.org/dtds/struts-2.3.dtd">

   

<struts>

    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

   

    <!--  Make the Spring object factory the automatic default -->

    <constant name="struts.objectFactory" value="spring" />

 

    <constant name="struts.class.reloading.watchList" value="" />

    <constant name="struts.class.reloading.acceptClasses" value="" />

    <constant name="struts.class.reloading.reloadConfig" value="false" />

 

    <package name="spring-default">

        <interceptors>

            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>

        </interceptors>

    </package>   

</struts>

 

 

那么Struts2启动扫描扩展插件时,会把该插件装载。其中如下声明即将Sturts2的创建对象工厂指定给Spring

 <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

如果没有导入此jar包则,需要在Struts2配置文件中进行相应的声明和处理。此处就不进行详细的讲述,感兴趣的可以上网搜索。下面打开浏览器重新敲入刚才的请求,


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

后台打印如下:

 


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

 

打印“execute Struts2 Action ...... && actionStr = testParameter”,说明进入到Actionexecute方法,执行testService.service();时,testService对象我们在声明的时候并没有实例化,说明此处的testService对象是由Spring帮助我们创建的,至此整合SpringStruts2的工作就完成了。

4 程序搭建---整合IbatisSpringStruts2

4.1拷贝Ibatis基本的jar包到工程下的lib目录

ibatis-2.3.4.726.jar     ibatis必备的jar

commons-dbcp-1.4.jar     dbcp连接池必备的包(便于整合Spring使用)

commons-pool-1.6.jar     便于整合Spring使用同上

mysql-connector-java-5.1.18-bin.jar    mysql数据库的驱动

classes12.jar                 Oracle数据库的驱动

4.2在前面的步骤没有添加log4j的属性文件,所以,所有的log4j都无法用,下面我们想使用log4j进行控制台信息的输出,所以此处添加log4j的属性文件,文件如下,此处不过多的对log4j进行介绍,感兴趣的朋友可以上网搜索相关内容,也可以参考我之前的一片文章

http://314649444.iteye.com/blog/1874814

#

# Log4J Settings for log4j 1.2.x (via jakarta-commons-logging)

#

# The five logging levels used by Log are (in order):

#

#   1. DEBUG (the least serious)

#   2. INFO

#   3. WARN

#   4. ERROR

#   5. FATAL (the most serious)

 

 

# Set root logger level to WARN and append to stdout

log4j.rootLogger=DEBUG,stdout

 

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

 

# Pattern to output the caller's file name and line number.

log4j.appender.stdout.layout.ConversionPattern=%d%5p(%c:%L)-%m%n

 

# Print only messages of level ERROR or above in the package noModule.

log4j.logger.noModule=FATAL

 

# OpenSymphony Stuff

log4j.logger.com.opensymphony=INFO

log4j.logger.org.apache.struts2=INFO

 

# Spring Stuff

log4j.logger.org.springframework=INFO

 

 

 

4.3下面首先让我们在数据库中创建一张表,本文采用的是mysql数据库

建表sql如下:

CREATETABLE`person`

(

 

`personid`

VARCHAR(100)

NOT NULL,

`name`

VARCHAR(100)

NOT NULL,

`age`

VARCHAR(100)

NOT NULL,

`sex`

VARCHAR(100)

NOT NULL,

PRIMARYKEY

(`personid`)

 

)

ENGINE=MYISAM

;

4.4.1创建com.jshand.ssi.model包,并在包下创建person表对应的实体类如下:

package com.jshand.ssi.model;

 

/**

 *@file_namePerson.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun26,2013  10:32:22AM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicclass Person {

   

    private String personid="";

    private String name="";

    private String age="";

    private String sex="";

   

   

    public String getPersonid() {

       returnpersonid;

    }

    publicvoid setPersonid(String personid) {

       this.personid = personid;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public String getAge() {

       returnage;

    }

    publicvoid setAge(String age) {

       this.age = age;

    }

    public String getSex() {

       returnsex;

    }

    publicvoid setSex(String sex) {

       this.sex = sex;

    }

}

 

4.4.2添加实体类Person对应的查询语句配置文件

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

 

<!DOCTYPE sqlMap     

    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     

    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

 

<sqlMap namespace="Person">

 

  <!-- Use type aliases to avoid typing the full classname every time. -->

  <typeAlias alias="Person" type="com.jshand.ssi.model.Person"/>

 

  <!-- Result maps describe the mapping between the columns returned

       from a query, and the class properties.  A result map isn't

       necessary if the columns (or aliases) match to the properties

       exactly. -->

  <resultMap id="Person" class="Person">

        <result property="personid"  column="personid" />

       <result property="name"     column="name" />

       <result property="age"  column="age" />

       <result property="sex" column="sex" />

  </resultMap>

 

  <!-- A simpler select example without the result map.  Note the

       aliases to match the properties of the target result class. -->

  <select id="selectPersonById" parameterClass="String" resultClass="Person">

   select personid, name, age, sex  from Person where personid= #id#

  </select>

  

  <!-- Insert example, using the Person parameter class -->

  <insert id="insertPerson" parameterClass="Person">

    insert into Person

        (personid, name, age, sex )

    values

        (#personid#, #name#, #age#, #sex# )

  </insert>

 

  <!-- Update example, using the Person parameter class -->

  <update id="updatePerson" parameterClass="Person">

    update Person

   set name = #name#,

       age = #age#,

       sex = #sex#,

    where personid = #personid#

  </update>

 

  <!-- Delete example, using an integer as the parameter class -->

  <delete id="deletePersonById" parameterClass="String">

    delete from Person where personid = #personid#

  </delete>

 

</sqlMap>

 

 

 

4.5 添加一个sqlMapping.properties文件(当然文件名是可以随便起的,只要Spring读取的时候保持一致即可)用于Spring读取配置连接数据库配置包括驱动类,Url、用户名、密码等,内容如下:

#MY SQL

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://127.0.0.1:3306/test

jdbc.username=root

jdbc.password=root

 

4.6配置sqlMapConfig.xml文件,并在其中注册 TB_Person.xmlSQL

 

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

 

<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

 

<sqlMapConfig>

 

    <settings cacheModelsEnabled="true" enhancementEnabled="true"

       lazyLoadingEnabled="true" errorTracingEnabled="false" maxRequests="32"

       maxSessions="10" maxTransactions="5" useStatementNamespaces="false" />

 

    <sqlMap resource="com/jshand/ssi/model/TB_Person.xml" />

   

</sqlMapConfig>

 

 

4.7 Spring配置文件中声明数据源sqlMapClient操作如下:

Spring配置文件中添加如下xml节点

   <!-- 方便查找类路径下 sqlMapping.properties 并读取到内存中-->

    <bean id="propertyConfigurer"

    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

       <property name="locations">

           <list>

              <value>classpath:sqlMapping.properties</value>

           </list>

       </property>

    </bean>

 

    <!-- 数据源配制 -->

    <bean id="dataSource"

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

       <property name="driverClassName">

           <value>${jdbc.driverClassName}</value>

       </property>

       <property name="url">

           <value>${jdbc.url}</value>

       </property>

       <property name="username">

           <value>${jdbc.username}</value>

       </property>

       <property name="password">

           <value>${jdbc.password}</value>

       </property>

    </bean>

 

    <!-- 此处应注入ibatis配置文件,而非sqlMap文件,否则会出现“there is no statement.....异常” -->

    <bean id="sqlMapClient"

       class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

       <property name="configLocation">

           <value>classpath:SqlMapConfig.xml</value>

       </property>

       <property name="dataSource" ref="dataSource" />

    </bean>

 

 

4.8 编写PersonDao类,并继承由Spring提供的SqlMapClientDaoSupport

实现增删改查的操作,PersonDto内容如下:

package com.jshand.ssi.dao;

 

import java.sql.SQLException;

 

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

 

import com.jshand.ssi.model.Person;

 

/**

 *@file_namePersonDao.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun26,2013  11:05:55AM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicclass PersonDao extends SqlMapClientDaoSupport{

   

    /**

     *按照主键查询

     *@paramid

     *@return

     *@throwsSQLException

     */

    public  Object selectObjectById  (String id) throws SQLException {

       System.out.println("ID = "+id);

       return  getSqlMapClientTemplate().queryForObject("selectPersonById", id);

    }

   

    /**

     *插入一条数据

     *@paramobject

     *@return

     *@throwsSQLException

     */

    public Object insertObject (Person person) throws SQLException {

       return getSqlMapClientTemplate().insert("insertPerson", person);

    }

   

    /**

     *按主键更新一条记录

     *@paramobject

     *@return

     *@throwsSQLException

     */

    public  int updateObject (Person person) throws SQLException {

       return getSqlMapClientTemplate().update("updatePerson", person);

    }

   

    /**

     *按主键删除一条记录

     *@paramid

     *@return

     *@throwsSQLException

     */

    public  int deleteObject (String id) throws SQLException {

       return getSqlMapClientTemplate().delete("deletePerson", id);

    }

}

 

 

 

4.9 PersonDao类交给Spring管理,即在Spring配置文件中注册PersonDao

并将PersonDao注入到上面步骤的testService里面去,最后Spring的完整内容如下:

 

<?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:aop="http://www.springframework.org/schema/aop"

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

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

    xsi:schemaLocation="  

          http://www.springframework.org/schema/beans   

          http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

          http://www.springframework.org/schema/aop   

          http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  

          http://www.springframework.org/schema/tx   

          http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

 

      <!-- 方便查找类路径下 sqlMapping.properties 并读取到内存中-->

    <bean id="propertyConfigurer"

        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

       <property name="locations">

           <list>

              <value>classpath:sqlMapping.properties</value>

           </list>

       </property>

    </bean>

 

    <!-- 数据源配制 -->

    <bean id="dataSource"

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

       <property name="driverClassName">

           <value>${jdbc.driverClassName}</value>

       </property>

       <property name="url">

           <value>${jdbc.url}</value>

       </property>

       <property name="username">

           <value>${jdbc.username}</value>

       </property>

       <property name="password">

           <value>${jdbc.password}</value>

       </property>

    </bean>

 

    <!-- 此处应注入ibatis配置文件,而非sqlMap文件,否则会出现“there is no statement.....异常” -->

    <bean id="sqlMapClient"

       class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

       <property name="configLocation">

           <value>classpath:SqlMapConfig.xml</value>

       </property>

       <property name="dataSource" ref="dataSource" />

    </bean>

     

    <bean id="testAction" class="com.jshand.ssi.action.TestAction">

       <property name="testService" ref="testService"></property>

    </bean>

   

    <bean id="testService" class="com.jshand.ssi.service.TestServiceImpl" >

           <property name="personDao" ref="personDao"></property>

    </bean>

   

    <bean id="personDao" class="com.jshand.ssi.dao.PersonDao" />

   

</beans>

 

4.10下面就是看效果的时候了,我们在testService中声明一个personDao属性,名称与Spring中注册的com.jshand.ssi.dao.PersonDao类的id保持一致即可并设置settergetterpersonDao属性只需声明即可不用实例化,因为此处验证Spring托管

 

因为之前我们整合SpringStruts2的时候Struts2Action接收访问后会调用TestServiceImplservice方法,所以我们在service方法中调用PersonDao的方法插入和查询方法已验证配置是否成功。

内容如下:

package com.jshand.ssi.service;

 

import java.sql.SQLException;

 

import org.apache.log4j.Logger;

 

import com.jshand.ssi.dao.PersonDao;

import com.jshand.ssi.model.Person;

 

/**

 *@file_nameTestService.java

 *@project       ssi-release

 *@author     jshand

 *@createDateJun2,2013  2:08:53PM

 *@version    1.0

 *http://www.jshand.com

 *

 */

 

publicclass TestServiceImpl implements TestService {

    Logger logger = Logger.getLogger(TestServiceImpl.class);

    private PersonDao personDao = null;

   

    publicvoid service() throws SQLException{

       System.out.println("this is service function ");

       Person personInsert  = new Person();

       personInsert.setPersonid("001");

       personInsert.setName("Jhoon");

       personInsert.setAge("23");

       personInsert.setSex("");

       personDao.insertObject(personInsert);

      

       logger.debug("插入成功");

       Person personQuery = null;

       personQuery = (Person) personDao.selectObjectById("001");

      

       logger.debug("查询结果 Name = "+personQuery.getName()+"\t age = "+personQuery.getAge()+"\tsex = "+personQuery.getSex());

      

      

    }

 

    public PersonDao getPersonDao() {

       returnpersonDao;

    }

 

    publicvoid setPersonDao(PersonDao personDao) {

       this.personDao = personDao;

    }

}

 

 

 

 

下面我们来发布一下程序,并查看执行结果:


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 
 
 

控制台打印如上,说明配置成功

5 ibatis的事物交给Spring管理,

即将数据源的事物交给Spring处理,然后Spring在一个指定的切面打开事物,切面执行完之后如果产生异常就将事物回滚,否则提交。

具体配置,在Spring配置文件添加如下xml节点,这里的切面为

public * com.jshand.ssi.services.*.*(..)  即所有Service类的所有方法

<!-- 事务的定义 -->

    <bean id="transactionManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

       <property name="dataSource">

           <ref local="dataSource" />

       </property>

    </bean>

 

    <aop:config>

       <aop:pointcut id="daoMethods" expression="execution(public * com.jshand.ssi.services.*.*(..))" />

       <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" />

    </aop:config>

 

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

       <tx:attributes>

           <tx:method name="*" rollback-for="Exception" propagation="REQUIRED" />

       </tx:attributes>

    </tx:advice>

 

下面我们将TestServiceImpl类的service方法改造一下,因为我们之前已经插入过一条id001的对象,现在我们先插入一条002的后插入一条001的记录,因为id是主键所以在此插入的时候001是不能插入的,按照事物的一致性原则,如果成功开始事物,并且回滚的话这两条记录都应该插入不成功,下面来执行看下效果

改造后如下:

    publicvoid service() throws SQLException{

      

       Person personInsert2  = new Person();

       personInsert2.setPersonid("002");

       personInsert2.setName("Jhoon");

       personInsert2.setAge("23");

       personInsert2.setSex("");

       personDao.insertObject(personInsert2);

      

       Person personInsert1  = new Person();

       personInsert1.setPersonid("001");

       personInsert1.setName("Jhoon");

       personInsert1.setAge("23");

       personInsert1.setSex("");

       personDao.insertObject(personInsert1);

      

    }

 

执行后:后台报错如下,

execute Struts2 Action ...... && actionStr = com.jshand.ssi.action.TestAction

2013-06-26 14:30:58,670 DEBUG (java.sql.Connection:27) - {conn-100000} Connection

2013-06-26 14:30:58,701 DEBUG (java.sql.Connection:27) - {conn-100000} Preparing Statement:      insert into Person     (personid, name, age, sex )  values     (?, ?, ?, ? )  

2013-06-26 14:30:58,780 DEBUG (java.sql.PreparedStatement:27) - {pstm-100001} Executing Statement:      insert into Person     (personid, name, age, sex )  values     (?, ?, ?, ? )  

2013-06-26 14:30:58,780 DEBUG (java.sql.PreparedStatement:27) - {pstm-100001} Parameters: [002, Jhoon, 23, ]

2013-06-26 14:30:58,780 DEBUG (java.sql.PreparedStatement:27) - {pstm-100001} Types: [java.lang.String, java.lang.String, java.lang.String, java.lang.String]

2013-06-26 14:31:21,026 DEBUG (java.sql.Connection:27) - {conn-100002} Connection

2013-06-26 14:31:21,026 DEBUG (java.sql.Connection:27) - {conn-100002} Preparing Statement:      insert into Person     (personid, name, age, sex )  values     (?, ?, ?, ? )  

2013-06-26 14:31:21,041 DEBUG (java.sql.PreparedStatement:27) - {pstm-100003} Executing Statement:      insert into Person     (personid, name, age, sex )  values     (?, ?, ?, ? )  

2013-06-26 14:31:21,041 DEBUG (java.sql.PreparedStatement:27) - {pstm-100003} Parameters: [001, Jhoon, 23, ]

2013-06-26 14:31:21,058 DEBUG (java.sql.PreparedStatement:27) - {pstm-100003} Types: [java.lang.String, java.lang.String, java.lang.String, java.lang.String]

2013-06-26 14:31:21,214  INFO (org.springframework.beans.factory.xml.XmlBeanDefinitionReader:315) - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]

2013-06-26 14:31:21,495  INFO (org.springframework.jdbc.support.SQLErrorCodesFactory:126) - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]

2013-06-26 14:31:24,396 ERROR (org.apache.struts2.dispatcher.Dispatcher:38) - Exception occurred during processing request: SqlMapClient operation; SQL [];  

--- The error occurred in com/jshand/ssi/model/TB_Person.xml. 

--- The error occurred while applying a parameter map. 

--- Check the insertPerson-InlineParameterMap. 

--- Check the statement (update failed). 

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:  

--- The error occurred in com/jshand/ssi/model/TB_Person.xml. 

--- The error occurred while applying a parameter map. 

--- Check the insertPerson-InlineParameterMap. 

--- Check the statement (update failed). 

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1

org.springframework.dao.DuplicateKeyException: SqlMapClient operation; SQL [];  

--- The error occurred in com/jshand/ssi/model/TB_Person.xml. 

--- The error occurred while applying a parameter map. 

--- Check the insertPerson-InlineParameterMap. 

--- Check the statement (update failed). 

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:  

--- The error occurred in com/jshand/ssi/model/TB_Person.xml. 

--- The error occurred while applying a parameter map. 

--- Check the insertPerson-InlineParameterMap. 

--- Check the statement (update failed). 

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1

    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:241)

    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)

    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:203)

    at org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:364)

    at com.jshand.ssi.dao.PersonDao.insertObject(PersonDao.java:39)

    at com.jshand.ssi.service.TestServiceImpl.service(TestServiceImpl.java:38)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

    at java.lang.reflect.Method.invoke(Method.java:597)

    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)

    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)

    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)

    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)

    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)

    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)

    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)

    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)

    at $Proxy4.service(Unknown Source)

    at com.jshand.ssi.action.TestAction.execute(TestAction.java:24)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

    at java.lang.reflect.Method.invoke(Method.java:597)

    at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:446)

    at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:285)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)

    at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)

    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)

    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)

    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:238)

    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:238)

    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)

    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)

    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)

    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)

    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:544)

    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)

    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)

    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)

    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)

    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)

    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)

    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

    at java.lang.Thread.run(Thread.java:619)

Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:  

--- The error occurred in com/jshand/ssi/model/TB_Person.xml. 

--- The error occurred while applying a parameter map. 

--- Check the insertPerson-InlineParameterMap. 

--- Check the statement (update failed). 

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1

    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:107)

    at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:393)

    at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82)

    at org.springframework.orm.ibatis.SqlMapClientTemplate$8.doInSqlMapClient(SqlMapClientTemplate.java:366)

    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:200)

    ... 82 more

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '001' for key 1

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)

    at com.mysql.jdbc.Util.getInstance(Util.java:386)

    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)

    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)

    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)

    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)

    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)

    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)

    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)

    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1362)

    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

    at java.lang.reflect.Method.invoke(Method.java:597)

    at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:62)

    at $Proxy7.execute(Unknown Source)

    at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:80)

    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:216)

    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:94)

    ... 86 more

 

表中的数据还是之前插入的一条,新插入的两条都没成功。


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

下面我们将service方法再次改造一下,将001id换成003,我们DEBUG执行下

改造后的service方法如下:

        publicvoid service() throws SQLException{

      

       Person personInsert2  = new Person();

       personInsert2.setPersonid("002");

       personInsert2.setName("Jhoon");

       personInsert2.setAge("23");

       personInsert2.setSex("");

       personDao.insertObject(personInsert2);

      

       Person personInsert3  = new Person();

       personInsert3.setPersonid("003");

       personInsert3.setName("Jhoon");

       personInsert3.setAge("23");

       personInsert3.setSex("");

       personDao.insertObject(personInsert3);

      

    }

我们在Person personInsert3  = new Person();句话上打一个端点,当我们执行到这酷话的时候如果没有开启事物那么id002的记录应该是插入到数据库中的,在这里测试事物的正确与否:

开始执行:


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

说明插入002的操作已经执行这个时候我们看一下数据库:


Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
 

发现记录中不存在002id所以证明事物成功开启未提交,当把service全部执行完毕后,在查看数据库发现,id002003的记录都已经成功插入,说明数据库事物是正确的。

 

 

总结:至此整合Struts2SpringIbatis已经结束了,需要值得注意的是,

mysql中表创建时需要选择存储引擎,本文中用的是mysql5.4提供七种种Storage Engine

,而其中MyISAM对事物的支持比较特殊,所以没有使用个,本文中建表使用   InnoDB作为存储引擎的。

 

 

 

本文中搭建好的应用可以到下面的地址下载:

http://test-jshand.googlecode.com/files/ssi-release.rar

  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 57.9 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 56.3 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 53.2 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 77.4 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 127.8 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 9.5 KB
  • Ssi的整合(Struts2+Spring+Ibatis)
            
    
    博客分类: web框架 struts2SpringIbatis框架 
  • 大小: 84.5 KB