SSM(Spring+SpringMVC+Mybatis)框架配置例子

SSM(Spring+SpringMVC+Mybatis)框架配置例子

首先从web.xml开始:

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xmlns="http://java.sun.com/xml/ns/javaee"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

   version="3.0">

<!—读取spring的配置文件 -->  

   <context-param>

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

      <param-value>classpath:spring.xml</param-value>

   </context-param>

   <!-- spring的监听器 -->

   <listener>

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

   </listener>

<!—session创建/销毁监听器 -->

   <listener>

   <listener-class>com.org.xcs.listener.SessionListener</listener-class>

   </listener>

<!—字符集过滤器 -->

   <filter>

      <description>字符集过滤器</description>

      <filter-name>encodingFilter</filter-name>

   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

      <init-param>

         <description>字符集编码</description>

         <param-name>encoding</param-name>

         <param-value>UTF-8</param-value>

      </init-param>

   </filter>

   <filter-mapping>

      <filter-name>encodingFilter</filter-name>

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

   </filter-mapping>

   <!-- druid -->

   <servlet>

      <servlet-name>DruidStatView</servlet-name>

      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>

   </servlet>

   <servlet-mapping>

      <servlet-name>DruidStatView</servlet-name>

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

   </servlet-mapping>

   <filter>

      <filter-name>DruidWebStatFilter</filter-name>

      <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>

      <init-param>

         <param-name>exclusions</param-name>

         <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>

      </init-param>

   </filter>

   <filter-mapping>

      <filter-name>DruidWebStatFilter</filter-name>

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

   </filter-mapping>

<!—将所有.do结尾的url请求交给DispatcherServlet处理 -->

   <servlet>

      <description>springmvc servlet</description>

      <servlet-name>springMvc</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

      <init-param>

         <description>springmvc 配置文件</description>

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

         <param-value>classpath:springmvc.xml</param-value>

      </init-param>

      <load-on-startup>1</load-on-startup>

   </servlet>

   <servlet-mapping>

      <servlet-name>springMvc</servlet-name>

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

   </servlet-mapping>

   <welcome-file-list>

      <welcome-file>/index.html</welcome-file>

      <welcome-file>/index.jsp</welcome-file>

   </welcome-file-list>

<!—超时配置,单位为分钟 -->

<session-config>

      <session-timeout>15</session-timeout>

   </session-config>

<!—错误跳转页面 -->

   <error-page>

      <error-code>404</error-code>

      <location>/404.jsp</location>

   </error-page>

   <error-page>

      <error-code>500</error-code>

      <location>/500.jsp</location>

   </error-page>

   <error-page>

      <exception-type>java.lang.Exception</exception-type>

      <location>/500.jsp</location>

   </error-page>

</web-app>

 

可以看到,web.xml中引用了两个xml配置文件:

classpath:spring.xml

classpath:springmvc.xml

其中,classpath就是代表web工程编译后的/WEB-INF/classes/ 这个路径(不理解的话,可以将war包放到tomcat中运行后,去工程目录底下查看);在代码工程中,把这两个文件放到资源目录(resources)下就可以了。

 

接下来,我们看spring.xml的配置:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="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"

   xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:util="http://www.springframework.org/schema/util"

   xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

      http://www.springframework.org/schema/context/spring-context-3.0.xsd

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

      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

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

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

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

      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

   ">

 

   <importresource="config/*.xml"/>

   <!-- 拦截器 -->

   <mvc:interceptors>

      <mvc:interceptor>

         <mvc:mappingpath="/**"/>

         <beanclass="com.org.xcs.interceptor.LoginIntercepter"/>

      </mvc:interceptor>

   </mvc:interceptors>

</beans>

可以看到,这里主要做了两件事:一是配置了一个登录拦截器,即用于拦截未登录的请求,强制重定向到登录页面,拦截器内容我也贴出来供大家参考:

LoginIntercepter.java:

package com.visionvera.cms.interceptor;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

 

public classLoginIntercepter implements HandlerInterceptor {

 

   public voidafterCompletion(HttpServletRequest arg0,

         HttpServletResponsearg1, Object arg2, Exception arg3)

         throws Exception {

   }

 

   public voidpostHandle(HttpServletRequest arg0, HttpServletResponse arg1,

         Objectarg2, ModelAndView arg3) throws Exception {

   }

 

   public booleanpreHandle(HttpServletRequest request, HttpServletResponse response,

         Objectobj) throwsException {

      Stringurl = request.getRequestURI().toString();

      if(url !=null && !"".equals(url)&& isSkipCheck(url)){

         return true;

      }else{

         Objectuser = request.getSession().getAttribute("login_user");

         if(user ==null){

            //判断是否为ajax请求

            if (request.getHeader("x-requested-with")!=null

                   &&request.getHeader("x-requested-with")

                         .equalsIgnoreCase("XMLHttpRequest")){//如果是ajax请求响应头会有x-requested-with

                response.setHeader("sessionTimeOut","yes");

                returnfalse;

            }

             response.sendRedirect(request.getContextPath()+"/index/showLogin.do");//如果用户未登录就强行重定向到登录页面

            return false;

         }

      }

      return true;

   }

  

   private boolean isSkipCheck(Stringurl){

      String[]skipArr = {"login"};

      for(String skip : skipArr){

         if(url.toLowerCase().contains(skip)){

            return true;

         }

      }

      return false;

   }

}

 

二是引入(import)了一些配置文件,这些配置文件存放于资源目录下的config目录中,都是xml格式的文件。

这里我是为了细分各种配置,所有拆分成了多个配置文件,大家可以根据实际情况进行整合,也是没有问题的。

   config目录下,一共放有5个文件:

   annotation.xml

   jdbc.xml

   mybatis.xml

   property.xml

   transation.xml

 

我们来逐个分析这些文件的内容:

annotation.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

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

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

   xsi:schemaLocation="

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

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

     http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd

     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd

     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

   <!--spring 扫包   @Service.....-->

   <context:component-scanbase-package="com.org.xcs">

      <context:exclude-filtertype="annotation"expression="org.springframework.stereotype.Controller"/>

   </context:component-scan>

   <context:annotation-config/>

</beans>

这里定义是扫描Service包,包的位置是在com.org.xcs,并排除了Controller(Controller包的扫描在springmvc.xml中定义)。

 

接着是jdbc.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

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

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

   xsi:schemaLocation="

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

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

     http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd

     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd

     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

   <!-- druid -->

   <beanid="dataSource"class="com.alibaba.druid.pool.DruidDataSource"

      init-method="init"destroy-method="close">

      <!-- <property name="driverClass"value="${mysql.driver}"/> -->

      <propertyname="url"value="${mysql.url}"></property>

      <propertyname="username"value="${mysql.username}"/>

      <propertyname="password"value="${mysql.password}"/>

 

      <!-- 配置初始化大小、最小、最大 -->

      <propertyname="initialSize"value="1"/>

      <propertyname="minIdle"value="1"/>

      <propertyname="maxActive"value="20"/>

 

      <!-- 配置获取连接等待超时的时间 -->

      <propertyname="maxWait"value="60000"/>

 

      <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

      <propertyname="timeBetweenEvictionRunsMillis"value="60000"/>

 

      <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

      <propertyname="minEvictableIdleTimeMillis"value="300000"/>

 

      <propertyname="validationQuery"value="SELECT 'x'"/>

      <propertyname="testWhileIdle"value="true"/>

      <propertyname="testOnBorrow"value="false"/>

      <propertyname="testOnReturn"value="false"/>

 

      <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->

      <propertyname="poolPreparedStatements"value="true"/>

      <propertyname="maxPoolPreparedStatementPerConnectionSize"

         value="20"/>

 

      <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->

      <propertyname="filters"value="stat"/>

   </bean>

</beans>

这里定义了数据源(dataSource),使用阿里巴巴的druid数据库连接池。

 

然后是mybatis.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

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

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

   xsi:schemaLocation="

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

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

     http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd

     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd

     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

   <!--mybatis sessionFactory配置-->

   <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">

      <propertyname="dataSource"ref="dataSource"/>

      <propertyname="mapperLocations"value="classpath:com/visionvera/cms/dao/*.xml"/>

      <propertyname="typeAliasesPackage"value="com.org.xcs.bean"/>

      <propertyname="plugins">

         <array>

            <reflocal="statementHandlerInterceptor"/>

            <reflocal="resultSetHandlerInterceptor"/>

         </array>

      </property>

   </bean>

  

   <beanid="statementHandlerInterceptor"class="com.org.xcs.interceptor.StatementHandlerInterceptor"/>

   <beanid="resultSetHandlerInterceptor"class="com.org.xcs.interceptor.ResultSetHandlerInterceptor"/>

  

   <!-- 扫包  -->

   <beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">

      <propertyname="basePackage"value="com.org.xcs.dao"/>

   </bean>

   <!-- 注册Spring工具类 -->

   <beanid="springContextUtil"class="com.org.xcs.commom.SpringContextUtil"></bean>

</beans>

这里主要是数据源的sessionFactory的定义,使用的是mybatis为spring提供的SqlSessionFactoryBean工厂类。我们来重点分析工厂类定义的几个property:

首先是dataSource,这个很明显,定义的是数据源,指向的就是jdbc.xml中定义的那个;

其次是mapperLocations,定义mybatis的Mapper文件的路径,是一些xml文件,mybatis的数据库操作都是定义在这些文件中的;

再次是typeAliasesPackage,Mapper文件关联的数据库实体(entity)类的存放路径;

最后是plugins,这个是mybatis提供的插件,可以定义拦截器用来实现分页。定义多个拦截器的时候,执行顺序从上到下。

两个拦截器的内容如下:

StatementHandlerInterceptor.java:

package com.org.xcs.interceptor;

 

import java.sql.Connection;

import java.util.Properties;

 

import org.apache.ibatis.executor.statement.PreparedStatementHandler;

import org.apache.ibatis.executor.statement.RoutingStatementHandler;

import org.apache.ibatis.executor.statement.StatementHandler;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.plugin.Interceptor;

import org.apache.ibatis.plugin.Intercepts;

import org.apache.ibatis.plugin.Invocation;

import org.apache.ibatis.plugin.Plugin;

import org.apache.ibatis.plugin.Signature;

import org.apache.ibatis.session.RowBounds;

import org.mybatis.spring.SqlSessionFactoryBean;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.org.xcs.commom.ReflectUtil;

 

@Intercepts({ @Signature(type= StatementHandler.class, method ="prepare", args = { Connection.class }) })

public classStatementHandlerInterceptor implements Interceptor {

   private static String MYSQL_DIALECT="com.org.xcs.dao.interceptor.MySqlDialectPPT";

   private Loggerlog = LoggerFactory

         .getLogger(StatementHandlerInterceptor.class);

 

   public Object intercept(Invocationinvocation)throws Throwable {

      RoutingStatementHandlerstatement = (RoutingStatementHandler)invocation

            .getTarget();

      PreparedStatementHandlerhandler = (PreparedStatementHandler) ReflectUtil

            .getFieldValue(statement,"delegate");

      RowBoundsrowBounds = (RowBounds) ReflectUtil.getFieldValue(handler,

            "rowBounds");

 

      if (rowBounds ==null || rowBounds.getLimit()== RowBounds.NO_ROW_LIMIT) {

         returninvocation.proceed();

      }

      BoundSqlboundSql = statement.getBoundSql();

      Stringsql = boundSql.getSql();

      MySqlDialectPPTdialect = newMySqlDialectPPT();

      sql= dialect.getLimitString(sql, rowBounds.getOffset(),

            rowBounds.getLimit());

      log.info(sql);

      ReflectUtil.setFieldValue(boundSql,"sql",sql);

      return invocation.proceed();

   }

 

   public Object plugin(Objecttarget) {

      return Plugin.wrap(target,this);

   }

 

   public voidsetProperties(Properties properties) {

      SqlSessionFactoryBeanc;

   }

}

ResultSetHandlerInterceptor.java:

packagecom.org.xcs.interceptor;

 

importjava.sql.Statement;

importjava.util.Properties;

 

importorg.apache.ibatis.executor.resultset.FastResultSetHandler;

importorg.apache.ibatis.executor.resultset.ResultSetHandler;

importorg.apache.ibatis.plugin.Interceptor;

importorg.apache.ibatis.plugin.Intercepts;

importorg.apache.ibatis.plugin.Invocation;

importorg.apache.ibatis.plugin.Plugin;

importorg.apache.ibatis.plugin.Signature;

importorg.apache.ibatis.session.RowBounds;

 

importcom.org.xcs.commom.ReflectUtil;

 

@Intercepts({@Signature(type = ResultSetHandler.class, method ="handleResultSets", args = { Statement.class }) })

publicclass ResultSetHandlerInterceptor implements Interceptor {

 

   public Object intercept(Invocationinvocation) throws Throwable {

      FastResultSetHandler resultSet =(FastResultSetHandler) invocation

            .getTarget();

      RowBounds rowBounds = (RowBounds)ReflectUtil.getFieldValue(resultSet,

            "rowBounds");

      if (rowBounds.getLimit() > 0

            && rowBounds.getLimit() <RowBounds.NO_ROW_LIMIT) {

         ReflectUtil.setFieldValue(resultSet,"rowBounds", new RowBounds());

      }

      return invocation.proceed();

   }

 

   public Object plugin(Object target) {

      return Plugin.wrap(target, this);

   }

 

   public void setProperties(Propertiesproperties) {

 

   }

 

}

   另外使用到了ReflectUtil.java:

package com.org.xcs.commom;

importjava.lang.reflect.Field;

importjava.lang.reflect.Modifier;

 

public classReflectUtil {

    public static void setFieldValue(Objectobject, String fieldName,Object value){

        Field field = getDeclaredField(object,fieldName);

        if (field == null)

            throw newIllegalArgumentException("Could not find field ["

                    + fieldName + "] ontarget [" + object + "]");

        makeAccessible(field);

        try {

            field.set(object, value);

        } catch(IllegalAccessException e) {

            e.printStackTrace();

        }

    }

 

    public static Object getFieldValue(Objectobject, String fieldName) {

        Field field = getDeclaredField(object,fieldName);

        if (field == null)

            throw newIllegalArgumentException("Could not find field ["

                    + fieldName + "] ontarget [" + object + "]");

        makeAccessible(field);

        Object result = null;

        try {

            result = field.get(object);

        } catch (IllegalAccessException e) {

            e.printStackTrace();

        }

        return result;

    }

 

    private static FieldgetDeclaredField(Object object, String filedName) {

        for (Class<?> superClass =object.getClass(); superClass != Object.class; superClass = superClass

                .getSuperclass()) {

            try {

                returnsuperClass.getDeclaredField(filedName);

            } catch (NoSuchFieldException e) {

                // Field 不在当前类定义, 继续向上转型

            }

        }

        return null;

    }

 

    private static void makeAccessible(Fieldfield) {

        if(!Modifier.isPublic(field.getModifiers())) {

            field.setAccessible(true);

        }

    }

 

}

以上是分页拦截器所用到的三个类。接下来我们举一个Mapper的例子:

TestDao.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper 3.0//EN"

        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mappernamespace="com.org.xcs.dao.TestDao">

   <selectid="getTimeCount" resultType="ReportVO"parameterType="map">

      …<!--省略-->

   </select>

 

   <selectid="getMemberCount" resultType="ReportVO"parameterType="map">

      …<!--省略-->

</mapper>

可以看到,TestDao.xml的mapper有个namespace属性,这个属性是用于绑定Dao接口的。当你的namespace绑定接口后,你可以不用写接口实现类,mybatis会通过该绑定自动帮你找到对应要执行的SQL语句。这里指定为TestDao,我们来看下TestDao.java的内容:

package com.org.xcs.dao;

 

importjava.util.List;

importjava.util.Map;

 

import com.org.xcs.bean.ReportVO;

 

publicinterface MainDao {

 

   List<ReportVO>getTimeCount(Map<String, Object> paramsMap);

 

   List<ReportVO>getMemberCount(Map<String, Object> paramsMap);

}

可以看到,TestDao.java里只定义了接口。通过namespace绑定后,我们通过Service调用Dao接口时,mybatis会自动帮我们执行mapper中定义好的数据库操作语句。

 

再看property.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

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

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

   xsi:schemaLocation="

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

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

     http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd

     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd

     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

   <!-- 读取jdbc配置 -->

   <beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

      <propertyname="locations">

         <list>

            <!-- jdbc配置 -->

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

            <!-- memcached配置 -->

         </list>

      </property>

   </bean>

  

</beans>

这个比较简单,就是定义了jdbc.properties的存放路径。

jdbc.properties定义了数据库的地址、用户名密码等信息:

mysql.driver=com.mysql.jdbc.Driver

mysql.url=jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=UTF-8

mysql.username=test

mysql.password=123456

 

最后是transation.xml:

<?xmlversion="1.0"encoding="UTF-8"?>

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

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

   xsi:schemaLocation="

    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

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

     http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd

     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd

     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 

   <!-- spring 事务 -->

   <beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

      <propertyname="dataSource"ref="dataSource"/>

   </bean>

   <!-- 开启事务注解 -->

   <tx:annotation-driventransaction-manager="transactionManager"/>

  

</beans>

这个文件定义了数据源使用的事务类型。这里我使用的是spring自带的DataSourceTransactionManager它会将所有具有@Transactional 注解的bean自动配置为声明式事务支持。

注意:要使事务生效,必须在接口或类的声明处 ,写一个@Transactional,例如:

package com.org.xcs.service.impl;

 

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

 

import com.org.xcs.bean.ReportVO;

import com.org.xcs.service.MainService;

 

@Service

@Transactional

public class MainServiceImpl implements MainService {

   …<-- 省略 -->

}

 

至此,一个完整的SSM框架完成了。其中若有遗漏或错误,欢迎大家批评指正。

猜你喜欢

转载自blog.csdn.net/u012799221/article/details/52982017