一、思路
需要spring通過單例的方式管理SqlSessionFactory。Spring和mybatis整合生成代理對(duì)象,使用SqlSessionFactory創(chuàng)建qlSession。持久層的mapper、dao都需要spring進(jìn)行管理。
二、環(huán)境
這里我們只是初步整合,新建一個(gè)java工程,然后導(dǎo)入相關(guān)的jar包,相關(guān)的jar包有:
-
spring所有的包 -
mybatis的包,一定記得要有兩者的整合包mybatis-spring-1.3.0.jar - 數(shù)據(jù)源,這里用的是
dbcp。
三、使用原始方式開發(fā)dao層
3.1 配置 spring 的配置文件(工程spring-mybatis)
config/spring/applicationContext.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: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-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-4.0.xsd">
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 數(shù)據(jù)源,使用dbcp -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" /><!-- 這里的name不能直接使用driver,必須是driverClassName -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- sqlSessionFactory -->
<bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加載mybatis的配置文件 -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"></property>
<!-- 數(shù)據(jù)源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 原始dao接口 -->
<bean id="userDao" class="cn.itcast.ssm.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
</beans>
說明:
- 首先我們加載了配置文件
db.properties; - 配置了
SqlSessionFactory和dao層。
3.2 mapper.xml
當(dāng)然這里我們使用的UserMapper.xml是使用之前工程中的,只留下了一個(gè)查詢方法。
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "test">
<!-- 查詢,通過用戶id進(jìn)行查詢 -->
<select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itcast.ssm.pojo.User">
<!-- 最后不能有分號(hào) -->
SELECT * FROM USER WHERE id = #{value}
</select>
</mapper>
3.3 SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 別名-->
<typeAliases>
<package name="cn.itcast.ssm.pojo"/>
</typeAliases>
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
3.4 dao層
UserDaoI.java
package cn.itcast.ssm.dao;
import cn.itcast.ssm.pojo.User;
//用戶管理接口
public interface UserDaoI {
//根據(jù)id查詢用戶信息
public User findUserById(int id );
}
UserDaoImpl.java
package cn.itcast.ssm.dao;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import cn.itcast.ssm.pojo.User;
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDaoI {
@Override
public User findUserById(int id) {
SqlSession sqlSession = this.getSqlSession();//繼承了SqlSessionDaoSupport之后這樣得到sqlSession
User user = sqlSession.selectOne("test.findUserById", id);
// 釋放資源不需要了
//sqlSession.close();
return user;
}
}
說明:這里我們需要繼承SqlSessionDaoSupport類,這樣我們就可以直接通過這個(gè)類獲得SqlSession了,不需要再次使用工廠去實(shí)例化了,同時(shí)對(duì)于會(huì)話的管理(如關(guān)閉)也交給spring了。
注意:對(duì)于其他的pojo類和之前工程中的一樣,直接考過來即可。
3.5 測(cè)試
UserDaoImplTest.java
package cn.itcast.ssm.dao;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.ssm.pojo.User;
public class UserDaoImplTest {
private ApplicationContext applicationContext;
//在這里我們得到spring的容器
@Before
public void setUp() throws Exception{
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() {
UserDaoI userDao = (UserDaoI) applicationContext.getBean("userDao");
//調(diào)用userDao的方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
說明:首先我們需要通過spring的配置文件得到spring的容器,之后才可以使用spring注入。
四、使用mybatis的方式開發(fā)dao層
4.1 拷貝之前工程中的mapper.xml 和 mapper.java 進(jìn)行改造。
(工程spring-mybatis01)
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "cn.itcast.ssm.mapper.UserMapper">
<!-- 查詢,通過用戶id進(jìn)行查詢-->
<select id="findUserById" parameterType="java.lang.Integer" resultType="User">
<!-- 最后不能有分號(hào) -->
SELECT * FROM USER WHERE id = #{value}
</select>
</mapper>
UserMapper.java
package cn.itcast.ssm.mapper;
import cn.itcast.ssm.pojo.User;
//用戶管理接口
public interface UserMapper {
//根據(jù)id查詢用戶信息
public User findUserById(int id );
}
4.2 applicationContext.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: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-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 數(shù)據(jù)源,使用dbcp -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" /><!-- 這里的name不能直接使用driver,必須是driverClassName -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- sqlSessionFactory -->
<bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加載mybatis的配置文件 -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"></property>
<!-- 數(shù)據(jù)源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- mapper配置,MapperFactoryBean可以根據(jù)mapper接口來生成代理對(duì)象 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.itcast.ssm.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
說明:其他地方不變,只是對(duì)dao層的配置變動(dòng)了,這里我們需要使用整合包中的一個(gè)類MapperFactoryBean。這個(gè)類可以根據(jù)mapper接口來生成代理對(duì)象。當(dāng)然我們需要將接口和會(huì)話工廠傳遞進(jìn)去。
問題:這種配置mapper的方法比較防鎖,當(dāng)mapper很多的時(shí)候則相當(dāng)麻煩。于是我們這樣配置:
<!-- mapper的批量掃描,從mapper的包中掃描mapper的接口,自動(dòng)創(chuàng)建代理對(duì)象并且在spring的容器中注冊(cè) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定掃描的包名,如果掃描多個(gè)包,每個(gè)包中使用半角逗號(hào)分隔
規(guī)范:要將mapper接口類名和mapper.xml映射文件名稱保持一致,且在一個(gè)目錄中
自動(dòng)掃描出來的mapper的bean的id為mapper類名(首字母小寫) -->
<property name="basePackage" value="cn.itcast.ssm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
而這里配置掃描器之后在SqlMapConfig.xml中配置的掃描器就不需要了:
<mappers>
<!-- 和spring整合后使用的mapper的掃描器,這里不需要再次配置掃描包了
規(guī)范:要將mapper接口類名和mapper.xml映射文件名稱保持一致,且在一個(gè)目錄中 -->
<package name="cn.itcast.ssm.mapper"/>
</mappers>
上面這段就不需要了,但是注意遵守相關(guān)的規(guī)范。
注意:這里我們不用sqlSessionFactory而是使用sqlSessionFactoryBeanName,是因?yàn)闀?huì)先掃描這里的配置,這樣就不會(huì)上秒掃面db.properties文件的掃描器不起作用了。但是我們需要先有數(shù)據(jù)源才行,所以不能使用sqlSessionFactory,同時(shí)也不能使用引用(ref)了,而應(yīng)該使用value來指定工廠。
注意:在此配置文件中對(duì)于類的路徑需要寫全稱,不能像mybatis配置文件中那樣寫簡(jiǎn)稱。
4.3 SqlConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 別名-->
<typeAliases>
<package name="cn.itcast.ssm.pojo"/>
</typeAliases>
<mappers>
<package name="cn.itcast.ssm.mapper"/>
</mappers>
</configuration>
說明:同樣,這里我們使用掃描的方式。
4.4 測(cè)試
測(cè)試方式基本一樣。
UserMapperTest.java
package cn.itcast.ssm.mapper;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.ssm.pojo.User;
public class UserMapperTest {
private ApplicationContext applicationContext;
//在這里我們得到spring的容器
@Before
public void setUp() throws Exception{
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() {
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
User user = userMapper.findUserById(1);
System.out.println(user);
}
}
最后:這里我們只是簡(jiǎn)單整合了一下,在后面再補(bǔ)充使用maven管理的整合方式。當(dāng)然方式基本一致,只是包的管理更為方便。