SpringMvc+Spring+Mybatis整合

SSM框架整合介绍

     SSM是Spring、SpringMvc、MyBatis 这3个框架的简称,是目前最为流行的项目架构。

其中spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

SpringMvc 和 MyBatis 其实是两个独立的框架,它们之间没有直接联系,但是 由于 Spring 框架提供了 IOC 的对象管理,切面编程、良好的ORM封装等非常实用的功能,如果把MyBatis 的对象的创建和维护交给Spring 容器进行管理,不仅能大大增强系统的灵活性,还能扩展功能,简化配置,提高性能、减少工作量,所以 SSM 框架整合其实就是分别实现 Spring 与 SpringMvc 、Spring与 MyBatis的整合,而实现整合的主要工作就是把 MyBatis的对象配置到Spring 容器中,交给 Spring 来管理即可,而SpringMvc 天生与Spring无缝集成

基本结构图如下:

 



简单过程:

当控制器接收到请求后,会调用 Service 层来实现业务,如果需要访问数据库,Service 层则会调用 Dao 层来操作数据库,而 Dao层 则需要使用 SqlSessionFactory 提供的 SqlSession 来实现具体操作,Session最终通过Connection 来实现增删改查等操作,有时为了提高性能,也会从连接池管理的数据源(DataSource)中获取Connection。对于图中,Controller,Service,Dao 的对象的创建和维护都被加入了Spring容器中,SqlSession由SqlSessionFactory创建并管理,所以只要把SqlSessionFactory加入Spring 容器中。Connection由DataSource创建并管理,所以把DataSource加入Spring容器中即可

SSM框架整合步骤

(1)添加三个框架相关的 jar 文件,并创建相关的配置文件

(2)为MyBatis 配置数据源对象

(3)配置数据源和SqlSessionFactory 对象

(4)实现并配置Dao 和Service

(5)使用Spring简化数据库事务处理,即配置声明式事务管理

(6)实现并配置Controller

难点是Spring整个MyBatis

其中步骤 (2)~ (5)属于 Spring 整合MyBatis ,步骤(6)属于Spring整合 SpringMvc

步骤一:添加三个框架相关的 jar 文件,并创建相关的配置文件

  

      1、添加 SpringMvc框架

      2、添加 spring框架

      3、添加MyBatis框架

步骤二:为MyBatis配置数据源对象:在Spring容器中配置 dbcp 和 c3p0 数据源

配置数据源对象的主要目的,通俗来讲就是缓解系统压力,提高性能

 MyBatis是对 Java 数据连接(JDBC)的封装,在访问数据库的时候,同样需要数据库连接,而创建数据库连接是一项开销很大的工作,对于Web应用程序这种多线程并发环境而言,如果每次访问数据库都创建新的连接,会严重影响系统的性能。连接池就是为了解决这个问题而诞生的,它的工作原理并不复杂,其相当于一个容器,里面保存了一定数量的连接对象,当程序到连接池中取对象时,连接池就返回一个可用的,空闲的连接给程序使用,当程序用完这个连接后,并不直接销毁它,而是把这个连接归还给连接池,以供其他线程使用,这样就实现了数据库连接的重复使用,避免多次创建连接对象而带来的系统开销

连接池中的连接对象是由数据源创建的,目前流行的数据源框架有dbcp、c3p0、Proxool等,它们都实现了连接池功能,都能为MyBatis中的SqlSession提供数据库连接,在整合Spring和MyBatis的时候,需要把数据源对象配置到Spring容器中。建议首选c3p0

        下面以c3p0和dbcp为例:首先需要在项目中添加jar文件,大家可以自行下载,这里使用的版本是:

        c3p0-0.9.1.jar 和 commons-dbcp1.4.jar

        根据自己选择的数据源,导入其中一个jar文件即可。接下来在Spring配置文件中配置数据源了。

         c3p0和dbcp的配置略有不同,它们的很多属性名称都不一样,c3p0 的配置代码如下

<!--destroy-method="close":当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用  -->

<bean id="dataSource"destroy-method="close"

class="com.mchange.v2.c3p0.ComboPooledDataSource">

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

<property name="driverClass"

value="oracle.jdbc.driver.OracleDriver">

</property>

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

<property name="jdbcUrl"

value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">

</property>

<property name="user"value="scott"></property>

<property name="password"value="tiger"></property>

<!-- 连接数池的最大连接数-->

<property name="maxPoolSize"value="500"></property>

<!-- 连接数池的最小连接数-->

<property name="minPoolSize"value="1"></property>

<!-- 初始化连接数-->

<property name="initialPoolSize"value="20"></property>

<!-- 连接的最大空闲时间,超时的连接将被丢弃,单位:秒-->

<property name="maxIdleTime"value="60"></property>

<!-- 没有连接可用时,等待的连接时间,单位:毫秒-->

<property name="checkoutTimeout"value="2000"></property>

dbcp的配置代码如下

<beanid="dataSource" destroy-method="close"

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

<propertyname="driverClassName"

value="oracle.jdbc.driver.OracleDriver">

</property>

<propertyname="url"

value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">

</property>

<propertyname="username" value="scott"></property>

<propertyname="password" value="tiger"></property>

<!--最大活动连接数 -->

<propertyname="maxActive" value="500"></property>

<!--最大空闲连接数 -->

<propertyname="maxIdle" value="5"></property>

<!--最小空闲连接数 -->

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

<!--初始化连接数 -->

<propertyname="initialSize" value="10"></property>

<!-- 没有连接可用时,等待的连接时间,单位:毫秒-->

<propertyname="maxWait" value="2000"></property>

</bean>

进行了数据源配置以后,Spring就会把相应的数据库连接管理类的对象加载到容器中,MyBatis就可以使用这个对象来获取并管理连接了

步骤二 :配置MyBatis的SqlSessionFactory工厂

   MyBatis的持久化操作是通过SqlSession来完成的,而SqlSession又是由SqlSessionFactory管理的,当系统需要进行数据库操作的时候,首先通过SqlSessionFactory取得一个SqlSession对象,然后SqlSession可以通过数据源取得的Connection去连接数据库,从而完成操作。所以,接下来要做的是如何把SqlSessionFactory配置到Spring容器中,代码如下

<bean id="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">

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

       <property name="mapperLocations"   value="classpath:com/mapper/*Mapper.xml"/>

       <!--typeAliasesPackage:指定实体类的包名,将类名映射成别名  -->

       <property name="typeAliasesPackage"value="com.entity" />

</bean>

Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的。但是Mybatis-Spring是基于SqlSessionFactoryBean的。在使用Mybatis-Spring的时候,我们也需要SqlSession,而且这个SqlSession是内嵌在程序中的,一般不需要我们直接访问。SqlSession也是由SqlSessionFactory来产生的,但是Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息

步骤2-1 : mybatis自动扫描加载sql映射文件和接口

      mybatis-spring提供了MapperScannerConfigurer这个类,

它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean, MapperFactoryBean的出现为了代替手工使用SqlSessionDaoSupportSqlSessionTemplate编写数据访问对象(DAO)的代码,使用动态代理实现

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

    <property name="basePackage"value="com.mapper"/>

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

</bean>

上述配置会扫描com.mapper下的所有接口,然后创建各自接口的动态代理类。

步骤三:使用Spring简化数据库事务处理

问题1:回忆在MyBatis中我们是怎么进行数据操作的?

在MyBatis中我们每次进行一个操作的的时候我们都是要先打开session,然后进行数据操作,然后提交事务,关闭session

问题2:Spring在整合MyBatis后,事务是怎样管理的?

当Spring对MyBatis进行整合之后,不再是每次都去拿Session进行数据操作了,也不需要每次都开启事务,提交事务了, MapperScannerConfigurer会自动执行完操作后提交事务

虽然Spring提供了自动提交事务,但是这样并不满足我们实际的业务需求,因为有时候在保存一个数据之后,程序希望它能继续保存另一条数据,即希望在保存完两条或者多条之后一起进行事务提 交,这样即使出错,还可以回滚,确保数据的一致性,要么都成功要么都失败,这时候我们就不能每保存完一条数据之后事务就自动提交,因为这样它们不在同一个事务当中,我们不能保证数据的一致行。所以这时候我们就需要手动的来配置我们的事务,这就需要用到Spring为MyBatis提供的事务管理机制

事务是各种类型的应用程序都需要考虑的问题,特别是web应用程序,数据库事务就是一个典型的事务,Spring 提供了一套完整、优秀的事务处理机制,这套机制拥有以下特点:

1、依赖底层实现,但不与底层API耦合,例如,在ssm框架中,Spring依赖MyBatis实现数据库事务管理,但编程时并不需要直接调用MyBatis的事务API

2、提供了编程式事务处理,也提供了声明式事务处理。编程式事务是指在程序中以代码的方式管理事务,这个方式很灵活,但代码具有侵入式,耦合度高;声明式事务是以配置的方式管理事务,它基于AOP实现,与代码完全分离,配置即可用,减少了工作量,但需要有良好的约定,在实际开发中,一般使用后者。

声明式事务处理其实现基本步骤如下:

    配置事务管理类对象

    配置事务的增强处理类(即配置事务的传播特性)

    配置事务的AOP切入点,并织入事务处理

配置事务管理类对象代码如下:

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

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

</bean>

<tx:adviceid="txAdvice" transaction-manager="txManager">

<tx:attributes>

<tx:methodname="search*" read-only="true"propagation="REQUIRED" isolation="DEFAULT"timeout="-1"/>

<tx:methodname="add*"/>

<tx:methodname="update*"/>

<tx:methodname="modify*"/>

<tx:methodname="remove*"/>

<!--<tx:method name="get*"/> --><!--最好不要这么配置,会导致属性的getter也加入事务处理  -->

</tx:attributes>

</tx:advice>

事务的传播特性在<tx:method>中进行设置,Spring支持对不同的方法设置不同的事务属性,所以可以为一个<tx:advice> 配置多个<tx:method>,其中name属性指定匹配的方法(模糊匹配),这里需要对这些方法名进行约定,以保证这些匹配到的方法能够正确被切入。以下是事务的常用属性介绍

read- only : 设置该事务中是否允许修改数据,对于只执行查询功能的事务,把它设置为true,能提高事务的执行速度。

propagation:事务传播机制,一般设置为REQUIRED,如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。如果取值为REQUIRES_NEW,则新建事务,如果当前存在事务,把当前事务挂起

Isolation:事务的隔离等级,即当前事务和其他事务的隔离程度,在并发情况下需要考虑该属性的设置。

取值为 default,使用数据库默认的隔离级别,oracle默认隔离级别为READ COMMITTED:可以避免脏读,但可能会出现不可重复读和幻读

取值 READ_UNCOMMITTED:会出现脏读,不可重复读和幻读

取值 REPEATABLE_READ:会出现幻读

取值SERIALIZABLE:串行化

timeout:允许事务运行的最长时间,以秒为单位,取值-1,则永久运行

配置事务的传播特性以后,最后还需要设置事务的AOP切入点,代码如下:

<!-- 设置切入点 -->

<aop:config>

<aop:pointcutexpression="execution(public * com.serviceImpl..*(..))"id="service"/>

<!-- 在特定的连接点,通知所开启的事务针对所提供的方法-->

<aop:advisoradvice-ref="txAdvice" pointcut-ref="service"/>

</aop:config>

设置的含义是:对com.serviceImpl包及其子包下的所有类的所有公共方法进行切入,当然被切入的方法还要经过<tx:method>筛选,而通常一般是把事务边界设置到service层,因为很多时候都是在服务层来完成一系列的业务操作,如果放到Dao数据层,其粒度太小了,

经过这三个步骤设置好声明式事务以后,当service中的业务方法被调用之前,Spring会获取事务对象并启动事务,并使用try-catch-finally来处理异常,业务方法执行成功则会提交事务,默认情况下如果抛出了RuntimeException就会回滚事务

通过Listener加载Spring容器

对于Spring来说,它需要启动容器后才能为其他框架提供服务,由于Web应用程序的入口是被Web服务器控制的,所以无法在main()方法中通过创建ClassPathXmlApplicationContext 对象来加载Spring容器。为了解决这个问题,Spring 提供了一个监听器来启动容器:org.springframework.web.context.ContextLoaderListener

         

            该监听器实现了ServletContextListener 接口,可以在Web容器启动的时候初始化Spring 容器,从而完成Spring的加载,当然,前提条件是需要在web.xml中配置好这个监听器,代码如下

<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>

其中,contextConfigLocation 用来指定Spring配置文件的路径,<listener-class>节点下配置ContextLoaderListener,经过以上配置,就能在Web 应用程序启动的同时启动Spring 容器了

                                                                       完整配置如下

Web.xml

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

  <display-name>proctice_ssm</display-name>

  <welcome-file-list>

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

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

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

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

    <welcome-file>default.htm</welcome-file>

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

  </welcome-file-list>

 

 

  <!-- 配置mybatis配置文件的映射路径-->

  <context-param>

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

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

  </context-param>

 

  <!-- 监听器类:完成spring框架的初始化操作,例如bean的创建,对象发的注入等 -->

  <listener>

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

  </listener>

 

  <!-- 配置springmvc的前段控制器 -->

  <servlet>

  <servlet-name>springmvc</servlet-name>

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

  <init-param>

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

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

  </init-param>

  <!-- 随着容器一起启动 -->

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

  </servlet>

  <!-- springmvc控制器所控制的请求URL,如若是*.do则向下执行,如若是其他则不经过前段控制器 -->

  <servlet-mapping>

  <servlet-name>springmvc</servlet-name>

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

  </servlet-mapping>

 

  <!-- 配置Spring提供的编码过滤器,设置乱码问题 -->

  <filter>

  <filter-name>charEncoding</filter-name>

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

  <init-param>

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

  <param-value>utf-8</param-value>

  </init-param>

  </filter>

  <filter-mapping>

      <filter-name>charEncoding</filter-name>

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

  </filter-mapping>

 

</web-app>

spring-mvc配置文件

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

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

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

    xsi:schemaLocation="

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

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

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

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

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

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

   <!-- 自动扫描指定包中含有@Repository@Service@Controller注解的对象 -->

   <!-- 注意在指定包的时候,通常是一个controller和一个service实现类,dao层则不需要,

   因为在spring-mybatis的配置文件当中,已经为每个接口生成了动态代理对象,以及通过其内部维护的

   SqlSessionTemplate对象负责打开session,提交和回滚

   因此只需在controllerservice实现类当中添加相应的注解 -->

   <context:component-scan base-package="com.controller,com.serviceImpl"></context:component-scan>

  

   <!-- 将普通字符串配合ResponseBody输出到客户端 -->

   <bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter">   

       <constructor-arg value="UTF-8" />   

   </bean>

  

   <!-- 定义将对象或者集合转换为json格式字符串对象 -->

   <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">

       <property name="supportedMediaTypes" value="application/json;charset=utf-8" />

   </bean>

 

 

   <!-- 配置映射处理器,将url请求映射给某个具体的handler -->

   <!-- 启动springmvc的注解,在ioc容器中注册RequestMappingHandlerMapping -->

   <mvc:annotation-driven>

      <mvc:message-converters>

         <ref bean="stringConverter"/>

         <ref bean="jsonConverter"/>

      </mvc:message-converters>

   </mvc:annotation-driven>

   <!-- 配置视图解析器,作用一:通过InternalResourceViewResolver将逻辑视图转换为真实的物理视图

        作用二:通过View对象渲染数据到jsp

    -->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

      <!-- 前缀:将逻辑视图名拼接指定的url前缀 -->

      <property name="prefix" value="/WEB-INF/jsp/"></property>

      <!-- 后缀:将逻辑视图名拼接成指定的后缀 -->

      <property name="suffix" value=".jsp"></property>

    </bean>

    

   <!-- 文件上传的类型解析器 -->

   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

       <!-- 配置文件的编码方式 -->

       <property name="defaultEncoding" value="utf-8" />

      <!-- 设置上传文件的最大尺寸为5MB -->

       <property name="maxUploadSize" value="5242880"/>

      <!-- 配置缓存 -->

      <property name="maxInMemorySize" value="40960"/>

   </bean>

    

   <!-- 定义拦截器链 -->

<!-- <mvc:interceptors> -->

      <!-- 定义计算控制器耗时的拦截器 -->

<!--     <mvc:interceptor> -->

<!--         mvc:mapping:需要拦截的url请求  -->

<!--         <mvc:mapping path="/**"/> -->

<!--         <bean class="com.userInceptor.ControllerTime"></bean> -->

<!--     </mvc:interceptor> -->

     

      <!-- 定义权限验证拦截器 -->

<!--     <mvc:interceptor> -->

<!--         <mvc:mapping path="/**"/> -->

<!--         <mvc:exclude-mapping path="/login.do"/> -->

<!--         <mvc:exclude-mapping path="/checklogin.do"/> -->

         <!-- 放行指定的url -->

<!--         <bean class="com.userInceptor.CheckUserLogin"></bean> -->

<!--     </mvc:interceptor> -->

     

<!-- </mvc:interceptors> -->

   </beans>

Spring-mybatis

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

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

   xsi:schemaLocation="

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

http://www.springframework.org/schema/beans/spring-beans-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

">

 

   <!--步骤一:配置数据源-->

   <!--destroy-method="close":当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用  -->

   <bean id="dataSource" destroy-method="close" class="com.mchange.v2.c3p0.ComboPooledDataSource">

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

      <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>

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

      <property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"></property>

      <property name="user" value="scott"></property>

      <property name="password" value="tiger"></property>

      <!-- 连接数池的最大连接数-->

      <property name="maxPoolSize" value="500"></property>

      <!-- 连接数池的最小连接数-->

      <property name="minPoolSize" value="1"></property>

      <!-- 初始化连接数-->

      <property name="initialPoolSize" value="20"></property>

      <!-- 连接的最大空闲时间,超时的连接将被丢弃,单位:秒-->

      <property name="maxIdleTime" value="10"></property>

      <!-- 没有连接可用时,等待的连接时间,单位:毫秒-->

      <property name="checkoutTimeout" value="20000"></property>

   </bean>

 

   <!--步骤二:配置MyBatisSqlSessionFactory工厂 -->

   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

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

      <!-- 给指定包中的对象定义类型别名,名称是对象名,然后首字母小写 -->

      <property name="typeAliasesPackage" value="com.entity"></property>

   </bean>

 

   <!--步骤2-1mybatis自动扫描加载sql映射文件和接口 -->

   <!-- MapperScannerConfigurer:负责扫描指定包中的接口和接口对应的sql映射文件,然后给每个接口生成动态代理对象,同时通过其内部维护的SqlSessionTemplate对象负责打开session,提交和回滚

      事务,关闭session等操作 -->

   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

      <property name="basePackage" value="com.mapper"></property>

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

   </bean>

 

   <!-- 声明式事务管理 -->

   <!--步骤三:配置事务管理类对象 -->

   <bean id="tm"

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

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

   </bean>

   <!--步骤四:配置事务的传播特性: 事务所经过的方法约定 -->

   <tx:advice id="txadvice" transaction-manager="tm">

      <tx:attributes>

         <tx:method name="select*" />

         <tx:method name="check*" />

         <tx:method name="insert*" />

         <tx:method name="add*" />

         <tx:method name="update*" />

         <tx:method name="modify*" />

         <tx:method name="delete*" />

         <tx:method name="drop*" />

      </tx:attributes>

   </tx:advice>

   <!--步骤五:配置事务的AOP切入点,并织入事务处理 -->

   <aop:config>

      <!-- 定义切入点 -->

      <aop:pointcut expression="execution(public * com.serviceImpl.*.*(..))"

         id="pt1" />

      <!-- 在特定的连接点,通知所开启的事务针对所提供的方法 -->

      <aop:advisor advice-ref="txadvice" pointcut-ref="pt1" />

   </aop:config>

 

</beans>

                                                                 简单案列

首先是一个请求

@RequestMapping("/emp")

   public ModelAndView getemp(){

      System.out.println("nihao");

      List<Emp> list = empservice.selectemp();

      System.out.println(list);

      ModelAndView m = new ModelAndView();

      //m.addObject("listemp",list);

      m.setViewName("emp");

      returnm;

     

   }

利用注解获取的接口的动态代理对象,Empservice为接口

@Autowired

   private Empservice empservice;

   public Empservice getEmpservice() {

      returnempservice;

   }

   publicvoid setEmpservice(Empservice empservice) {

      this.empservice = empservice;

   }

接口

publicinterface Empservice {

   public List<Emp> selectemp();

}

接口的实现类

@Service

publicclass EmpServiceImpl implements Empservice{

 

   private EmpDaoMapper dao;

   public EmpDaoMapper getDao() {

      returndao;

   }

   @Autowired     Autowired为通过类型注入

   publicvoid setDao(EmpDaoMapper dao) {

      this.dao = dao;

   }

   @Override  重写接口的方法

   public List<Emp> selectemp() {

      System.out.println("service");

      returndao.selectemp();

   }

}

 

注意:EmpDaoMapper为一个接口,表面看来并没有对应的实现类,不能够实例化,得到对应的对象,进而调用其相应的方法,但是在spring-mybatis配置了这个,所以在配置文件中,已经为没和接口生成了动态代理对象,因此在这里能够通过Autowired获取ioc容器当中的对象

<!--步骤2-1mybatis自动扫描加载sql映射文件和接口 -->

   <!-- MapperScannerConfigurer:负责扫描指定包中的接口和接口对应的sql映射文件,然后给每个接口生成动态代理对象,同时通过其内部维护的SqlSessionTemplate对象负责打开session,提交和回滚

      事务,关闭session等操作-->

   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

      <property name="basePackage" value="com.mapper"></property>

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

   </bean>

接口的名称一定要和sql映射文件的类名一致,最好在同一个包地下

Sql映射文件

<!-- 为这个mapper指定一个唯一的namespacenamespace的值习惯上设置成包名+sql映射文件名,

这样就能够保证namespace的值是唯一的 -->

<mapper namespace="com.mapper.EmpDaoMapper">

<select id="selectemp" resultType="com.entity.Emp"> 

   select * from emp

</select>

</mapper>

注意:sql语句的id一定得和service中的调用方法一致,通常来说在一个完整的请求以及处理当中,方法最好在controller,service,dao层保持一致,方便修改使用,减少错误

猜你喜欢

转载自blog.csdn.net/add_del/article/details/79793188