1.为什么要整合?
1.1 spring框架实现了bean对象的管理,将对象的实例化操作,由new硬编码的方式,改为配置式。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.ibatis.datasource.unpooled.UnpooledDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3309/test"/>
<property name="username" value="root"/>
<property name="password" value="12345"/>
</bean>
</beans>
上述配置文件定义了UnpooledDataSource的一个实例dataSource
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
DataSource dataSource = ctx.getBean("dataSource",DataSource.class);
通过spring容器ctx可以返回该对象。
1.2 mybatis是一个持久化框架,简化数据持久化操作。
一般,我们只要定义持久化接口和映射文件(或注解),框架会给我们生成对应接口的实现类。通常我们可以通过SqlSession的getMapper()方法返回实现了持久化接口的对象。
SqlSession sess = null;
SqlSessionFactory sf = null;
SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
sf = sb.build(this.getClass().getResourceAsStream("/mybatis-cfg.xml") );
sess = sf.openSession();
UserDao userDao = sess.getMapper(UserDao.class);
1.3 spring整合mybatis就是将上述mybatis的new操作返回的对象,改为从容器里获取。
要获得Mapper接口的实现类,需要通过SqlSession对象的getMapper方法,而SqlSession对象,则是通过SqlSessionFactory对象的openSession方法来获取。因此需要通过容器来管理这两个对象。
为了整合方便,mybatis提供了MapperFactoryBean来生成Mapper接口的实现类。具体看以下bean的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.ibatis.datasource.unpooled.UnpooledDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3309/test"/>
<property name="username" value="root"/>
<property name="password" value="004872@jxnu"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mappers/*"/>
<property name="configLocation" value="classpath:mybatis-cfg.xml"/>
</bean>
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.edu.jxnu.sse.dao.UserDao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
在spring配置的bean中,class指定为XXXFactoryBean类,返回的不是该类的实例,而是会调用该实例的方法getObject,该方法会返回一个另一个类的实例。
配置了上述id为userMapper的实例后,程序中可以从容器中取得该实例来完成 。
UserDao userDao = ctx.getBean("userMapper",UserDao.class)
或者通过配置,注入到其他对象中。
以MapperFactoryBean生成Mapper对象,每个Mapper接口都要配置一个bean,配置繁琐。为了减少配置,可以配置MapperScannerConfigurer对象。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.edu.jxnu.sse.dao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
配置该bean,容器注入该对象,且会扫描basePackage属性指定的包及子包,如果该包及子包下的类,添加了bean的相关注解(@Component,@Service,@Repository,@Controller),将自动注入容器。