MyBatis(九) 整合Spring、整合SpringMVC
MyBatis整合Spring分為下面幾個部分
* 配置資料來源
* 配置SqlSessionFactory
* 配置SqlSessionTemplate
* 配置Mapper
* 事務處理
配置SqlSessionFactory
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- jdbc.properties 中的key必須定義為 jdbc.username,格式開頭的 -->
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 依賴資料來源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 依賴mybatis-config.xml配置檔案 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
SqlSessionFactory的建立依賴資料來源和mybatis-config配置檔案(mybatis配置檔案中就不需要再配置資料來源),classpath表示從類路徑下獲取,這樣就建立了mybatis的上下文
需要注意一點,屬性檔案注入時候,key必須是jdbc.開頭的, 比如jdbc.username,jdbc.password,去掉jdbc.會出錯。
SqlSessionFactoryBean的原始碼,看出mybatis的配置可以IOC進行設定,不必全部寫在xml中,再引入,但不建議這麼做。
public class SqlSessionFactoryBean
implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent>
{
private Resource configLocation;
private Resource[] mapperLocations;
private DataSource dataSource;
private TransactionFactory transactionFactory;
private Properties configurationProperties;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
private SqlSessionFactory sqlSessionFactory;
private String environment = SqlSessionFactoryBean.class.getSimpleName();
private boolean failFast;
private Interceptor[] plugins;
private TypeHandler<?>[] typeHandlers;
private String typeHandlersPackage;
private Class<?>[] typeAliases;
private String typeAliasesPackage;
private Class<?> typeAliasesSuperType;
private DatabaseIdProvider databaseIdProvider;
private ObjectFactory objectFactory;
private ObjectWrapperFactory objectWrapperFactory;
配置SqlSessionTemplate
SqlSessionTemplate是一個模板類,通過代理生成SqlSession的代理物件執行資料庫操作。
原始碼看出,建立SqlSessionTemplate需要注入一個SqlSessionFactory
public class SqlSessionTemplate implements SqlSession{
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
private final SqlSession sqlSessionProxy;
private final PersistenceExceptionTranslator exceptionTranslator;
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory)
{
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType)
{
this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator)
{
Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
Assert.notNull(executorType, "Property 'executorType' is required");
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.sqlSessionProxy = ((SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor(null)));
}
配置:
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
<!-- 指定ExecutorType: simple,batch,resume 預設是simple ,可以不指定 -->
<constructor-arg index="1" value="BATCH"></constructor-arg>
</bean>
直接使用SqlSessionTemplate(可以不看)
直接在Dao層使用,將它注入到Dao中,並實現一個公共的Dao的基類
public class BaseDAOImpl {
public SqlSessionTemplate sqlSessionTemplate;
public SqlSessionTemplate getSqlSessionTemplate() {
return sqlSessionTemplate;
}
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
}
public interface StudentDao {
Student getStudent(Integer id);
List<Student> getStudentList(String name);
int deleteInfo(Integer id);
}
public class StudentDaoImpl extends BaseDAOImpl implements StudentDao {
@Override
public Student getStudent(Integer id) {
Student stu = this.sqlSessionTemplate.selectOne("cn.bing.mybatisTest.StudentDao.getStudent", id);
return stu;
}
@Override
public List<Student> getStudentList(String name) {
List<Student> list = this.sqlSessionTemplate.selectList("cn.bing.mybatisTest.StudentDao.getStudentList", name);
return list;
}
@Override
public int deleteInfo(Integer id) {
int count = this.sqlSessionTemplate.delete("cn.bing.mybatisTest.StudentDao.deleteInfo", id);
return count;
}
}
xml中配置這個Dao
<bean id="studentDao" class="cn.bing.mybatisTest.StudentDaoImpl">
<property name="sqlSessionTemplate" ref="sqlSession"></property>
</bean>
這和IBatis時代的程式設計方式一致,不建議使用
配置Mapper
大部分場景不建議直接使用SqlSessionTemplate或者SqlSession的方式,而是採用Mapper介面程式設計的方式,讓SqlSession在開發過程中消失。
在MyBatis中,Mapper只需要一個介面,而不是一個實現類,MyBatis會通過動態代理生成一個代理物件來執行。
MyBatis-Spring團隊提供了一個MapperFactoryBean類作為中介,可以生成Mapper,配置這個類需要三個引數
* mapperInterface,定製mapper介面
* SqlSessionFactory, 當SqlSessionTemplate屬性沒有配置時候,才去啟用
* SqlSessionTemplate,當被設定時候,SqlSessionFactory將作廢
<bean id="studentDao" class = "org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.bing.mapper.StudentMapper"></property>
<!-- sqlSessionTemplate沒有設定時候,才會啟用 -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
<!-- 設定sqlSessionTemplate,sqlSessionFactory設定無效 -->
<property name="sqlSessionTemplate" ref="sqlSession"></property>
</bean>
但是如果存在多個Dao呢?
使用MapperScannerConfigurer,自動掃描的形式來配置對映器
* basePackage屬性,指定Spring掃描的Mapper包
* annotationClass屬性,表示如果類被這個註解標識的時候,才進行掃描
* sqlSessionFactoryBeanName,指定在Spring中定義sqlSessionFactory的bean名稱,如果它被定義,sqlSessionFactory將不起作用
* sqlSessionTemplateBeanName,指定在Spring中定義sqlSessionTemplate的bean名稱,如果它被定義
sqlSessionFactoryBeanName將不起作用
* markerInterface,指定是實現了什麼介面就認為是Mapper。需要提供一個公共的介面去標識。
在Spring配置中給Dao類加上一個註解@Repository標識,標識是Dao類
@Repository
public interface StudentMapper {
public Student queryStudentByNameAndSex(@Param("name")String stuName,@Param("sex")String sex);
public Student queryStudentInfo(@Param("id")int id);
public int getCount(int id);
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.bing.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="annotationClass" value="org.springframework.stereotype.Repository"></property>
</bean>
配置MapperSannerConfigurer 時候,如果是配置sqlSessionFactory屬性,會報錯Could not load driver Class
,後面改為sqlSessionFacotryBeanName
關於Could not load driverClass ${jdbc.driverClassName}問題解決方案
配置事務
使用宣告式事務配置,有兩個解決方法,一種是xml配置使用aop織入事務,還有一種是啟用註解@Transactional配置
最終的xml配置_springContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 註解支援 -->
<context:annotation-config></context:annotation-config>
<!-- 掃描包,自動建立bean -->
<context:component-scan base-package="cn.bing.service"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- jdbc.properties 中的key必須定義為 jdbc.username,格式開頭的 -->
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 依賴資料來源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 依賴mybatis-config.xml配置檔案 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.bing.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="annotationClass" value="org.springframework.stereotype.Repository"></property>
</bean>
<!-- 配置事務 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="query*" propagation="REQUIRED" read-only="true" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="add*" propagation="REQUIRED" read-only="false" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="studentServicePointCut" expression="execution (* cn.bing.service..*.*(..))" />
<aop:advisor advice-ref="advice" pointcut-ref="studentServicePointCut" />
</aop:config>
</beans>
出現的問題:
配置MyBatis的MapperScannerConfigurer的屬性sqlSessionFactory(會出現bug),改為配置為sqlSessionFactoryBeanName,值為SqlSessionFactory配置的Bean的id
整合SpringMVC
將springContext.xml交給ContextLoaderListener載入,優先於SpringMVC.xml被dispatcher載入
出現的問題
springContext.xml 回去掃描@Service的類
SpringMVC.xml會掃描@Controller的類
兩個掃描不能有衝突,否則會出現事務失效的問題
springContext.xml中掃包的時候,加上不能掃描@Controller的類
<context:component-scan base-package="cn.bing.service"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
SpringMVC.xml配置掃包的時候,不能掃描@Service的類
<!-- 配置controller掃描包 -->
<context:component-scan base-package="cn.bing.controller" use-default-filters="false" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!-- !!!最好加上這句讓SpringMVC管理的時候排除Service層,避免事務失效的問題。 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>zhibing_mybatis</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springContext.xml</param-value>
</context-param>
<listener>
<description>spring listener</description>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<servlet>
<description>spring mvc servlet</description>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>springmvc config</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>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
相關文章
- SSM——Spring整合SpringMVC,MyBatisSSMSpringMVCMyBatis
- SSM(SpringMVC + Spring + Mybatis)整合SSMSpringMVCMyBatis
- SSM整合(Spring、SpringMVC、Mybatis)SSMSpringMVCMyBatis
- Spring+SpringMVC+MyBatis+easyUI整合基礎篇(九)版本控制SpringMVCMyBatisUI
- Spring+SpringMVC+MyBatis框架整合SpringMVCMyBatis框架
- Spring+SpringMVC+MyBatis的整合SpringMVCMyBatis
- SpringMVC整合MybatisSpringMVCMyBatis
- springmvc mybatis 整合SpringMVCMyBatis
- Spring+SpringMVC+Mybatis框架整合搭建教程SpringMVCMyBatis框架
- Spring+SpringMvc+Mybatis整合注意事項SpringMVCMyBatis
- Spring+SpringMVC+MyBatis+easyUI整合進階篇(十二)Spring整合Redis快取SpringMVCMyBatisUIRedis快取
- Spring+SpringMVC+MyBatis+easyUI整合最佳化SpringMVCMyBatisUI
- Maven整合SSM框架(maven+spring+springmvc+mybatis)MavenSSM框架SpringMVCMyBatis
- Spring 整合 MyBatisSpringMyBatis
- mybatis整合springMyBatisSpring
- Spring整合MyBatisSpringMyBatis
- SSM(Spring-MyBatis-SpringMVC)框架整合【完整版】SSMMyBatisSpringMVC框架
- SSM框架——詳細整合教程(Spring+SpringMVC+MyBatis)SSM框架SpringMVCMyBatis
- SSM框架——具體整合教程(Spring+SpringMVC+MyBatis)SSM框架SpringMVCMyBatis
- Spring+SpringMVC+MyBatis整合(easyUI、AdminLte3)SpringMVCMyBatisUI
- Spring+SpringMvc+Mybatis框架整合搭建教程二(依賴配置及框架整合)SpringMVCMyBatis框架
- Unit08: Spring與MyBatis整合 、 Spring整合MyBatis應用SpringMyBatis
- Spring+SpringMvc+Mybatis框架整合搭建教程三(框架整合測試程式開發)SpringMVCMyBatis框架
- Spring Boot 整合 MyBatisSpring BootMyBatis
- Spring整合Mybatis plusSpringMyBatis
- Mybatis與Spring整合MyBatisSpring
- spring boot 整合mybatisSpring BootMyBatis
- Spring整合JUnit,MybatisSpringMyBatis
- SSM三大框架整合詳細教程(Spring+SpringMVC+MyBatis)SSM框架SpringMVCMyBatis
- Spring+SpringMvc+Mybatis框架整合搭建教程一(專案建立)SpringMVCMyBatis框架
- Spring+SpringMVC+MyBatis+easyUI整合基礎篇(十)SVN搭建SpringMVCMyBatisUI
- Spring boot 六 整合 MyBatisSpring BootMyBatis
- SpringBoot 實戰 (九) | 整合 MybatisSpring BootMyBatis
- spring:spring與mybatis的整合SpringMyBatis
- [Android]後端之路--整合SSM(Spring+SpringMVC+MyBatis)框架(2)Android後端SSMSpringMVCMyBatis框架
- 最容易的ssm三大框架整合(spring+springmvc+mybatis)教程SSM框架SpringMVCMyBatis
- Mybatis整合Spring(ssm整合待續)-day04MyBatisSpringSSM
- spring 整合 mybatis 及mybatis 的 crud 操作SpringMyBatis