其中mapper定义了接口,其类名与xml中的namespace一致,id与接口定义的方法名一直,这样,把xml加载到spring中后,mybatis的初始化配置sqlsession时就会通过namespace+id的方式找到对应的sql进行执行,mybatis会自动匹配xml与mapper接口的对应关系,需要文件名称一致。
下面进行三个配置文件的配置。
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID"
version="3.0">
<display-name>website1display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>
classpath:config/springmvc-servlet.xml,
classpath:config/ApplicationContext.xml
param-value>
context-param>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>*.dourl-pattern>
filter-mapping>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:config/springmvc-servlet.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
<welcome-file-list>
<welcome-file>index.htmlwelcome-file>
<welcome-file>index.htmwelcome-file>
<welcome-file>index.jspwelcome-file>
<welcome-file>default.htmlwelcome-file>
<welcome-file>default.htmwelcome-file>
<welcome-file>default.jspwelcome-file>
welcome-file-list>
web-app>
<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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.website.controller">context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/">
property>
<property name="suffix" value=".jsp">property>
bean>
beans>
<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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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>
<context:component-scan base-package="com.website.service" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="" />
<property name="mapperLocations" value="classpath:mybatis/*.xml" />
bean>
<bean id="MapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.website.dao" />
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:annotation-driven transaction-manager="transactionManager" />
beans>
在MapperScannerConfigurer中,我们知道sqlSessionFactory的注入方式有四种,分别是sqlSessionFactory,sqlSessionFactoryBeanName,sqlSessionTemplate,sqlSessionTemplateBeanName,而sqlSessionFactory这种已经过时,所以我们用到的是sqlSessionFactoryBeanName,接下来说说这个的好处,为什么要用到它!
原因1:
注入sqlSessionFactory,(可以不用配置)只有当配置多数据源的时候,这时会有多个sqlSessionFactory,可以通过改属性来指定哪一个sqlSessionFactory(综合网上的总结)
原因2(重点):
注入sqlSessionFactory,后面的value是SqlSessionFactory的bean的名字,也就是sqlSessionFactory的id当我们的mapperscannerconfigurer启动的时候,可能会出现我们的jdbc.properties文件未被加载,这样的话它拿到的DataSource就是错误的,因为像${jdbc.url}这类的属性还没有被替换掉,所以通过BeanName后处理的方式,当我们去用我们的Mybatis的时候,它才会去找我们对应的sqlSessionFactory,为了防止它提前初始化我们的sqlSessionFactory .
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="" />
<property name="mapperLocations" value="classpath:mybatis/userMapper.xml" />
bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0">
<ref bean="sqlSessionFactory" />
constructor-arg>
bean>
<bean id="MapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.website.dao" />
<property name="sqlSessionTemplateBeanName" value="sqlSession" />
bean>
注意如果是多数据源则一定要使用sqlSessionFactoryBeanName 或sqlSessionTemplateBeanName 来指定具体的数据源,不知道在上面的配置中有没有注意到,如果使用sqlSessionTemplateBeanName 的话要来创建具体的实例并赋值给sqlSessionTemplateBeanName 这个属性。
我们使用mapper接口的形式,在mapper接口名称和xml的文件名称对应且等于namespace一致,方法名和sql的id一致,这样我们在配置扫描器
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="" />
<property name="mapperLocations" value="classpath:mybatis/*.xml" />
bean>
就能扫描到我们的xml文件,然后我们在配置
<bean id="MapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.website.dao" />
<property name="sqlSessionTemplateBeanName" value="sqlSession" />
bean>
就可以将我们的mapper接口文件扫描到,mybatis将他们匹配生成对应关系,我们在调用的时候,通过namespace+id的方式进行调用sql语句。所以你的映射文件的namespace 必须是接口的类全名称而id 必须是接口中的方法名称,这样动态代理就能找到路劲了也有了参数了。
<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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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>
<context:component-scan base-package="com.website.service ,com.website.dao" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="" />
<property name="mapperLocations" value="classpath:mybatis/UserMapping.xml" />
bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0">
<ref bean="sqlSessionFactory" />
constructor-arg>
bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:annotation-driven transaction-manager="transactionManager" />
beans>
其中少了这样的配置,去掉了动态代理的实现,不采用接口的形式。
<bean id="MapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.website.dao" />
<property name="sqlSessionTemplateBeanName" value="sqlSession" />
bean>
这样就必须我们自己实现mybatis的sql语句的调用,这样我们需要在dao层注入在配置文件中实例化的sqlSession这个bean,使用它进行selectOne,selectList()的调用,传入namespace.id的参数,确定唯一的sql语句。
package com.website.dao;
import java.util.Map;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/**
* @author WHD data 2016年6月5日
*/
@Repository("userDao")
public class UserDao {
@Autowired
private SqlSessionTemplate sqlSession;
public void saveUser(Map map) {
int end = sqlSession.insert("com.website.userMapper.insertUser", map);
System.out.println("end" + end);
}
}
这里进行sqlSession.insert方法调用,第一个参数是string型,statement的id,第二个参数是param。