一、思路
需要spring
通过单例的方式管理SqlSessionFactory
。Spring
和mybatis
整合生成代理对象,使用SqlSessionFactory
创建qlSession
。持久层的mapper
、dao
都需要spring
进行管理。
二、环境
这里我们只是初步整合,新建一个java
工程,然后导入相关的jar
包,相关的jar
包有:
-
spring
所有的包 -
mybatis
的包,一定记得要有两者的整合包mybatis-spring-1.3.0.jar
- 数据源,这里用的是
dbcp
。
三、使用原始方式开发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"/>
<!-- 数据源,使用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>
<!-- 数据源 -->
<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
当然这里我们使用的UserMapper.xml
是使用之前工程中的,只留下了一个查询方法。
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进行查询 -->
<select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itcast.ssm.pojo.User">
<!-- 最后不能有分号 -->
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 {
//根据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
类,这样我们就可以直接通过这个类获得SqlSession
了,不需要再次使用工厂去实例化了,同时对于会话的管理(如关闭)也交给spring
了。
注意:对于其他的pojo
类和之前工程中的一样,直接考过来即可。
3.5 测试
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");
//调用userDao的方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
说明:首先我们需要通过spring
的配置文件得到spring
的容器,之后才可以使用spring
注入。
四、使用mybatis的方式开发dao层
4.1 拷贝之前工程中的mapper.xml 和 mapper.java 进行改造。
(工程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进行查询-->
<select id="findUserById" parameterType="java.lang.Integer" resultType="User">
<!-- 最后不能有分号 -->
SELECT * FROM USER WHERE id = #{value}
</select>
</mapper>
UserMapper.java
package cn.itcast.ssm.mapper;
import cn.itcast.ssm.pojo.User;
//用户管理接口
public interface UserMapper {
//根据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"/>
<!-- 数据源,使用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>
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- mapper配置,MapperFactoryBean可以根据mapper接口来生成代理对象 -->
<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>
说明:其他地方不变,只是对dao
层的配置变动了,这里我们需要使用整合包中的一个类MapperFactoryBean
。这个类可以根据mapper
接口来生成代理对象。当然我们需要将接口和会话工厂传递进去。
问题:这种配置mapper
的方法比较防锁,当mapper
很多的时候则相当麻烦。于是我们这样配置:
<!-- mapper的批量扫描,从mapper的包中扫描mapper的接口,自动创建代理对象并且在spring的容器中注册 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描的包名,如果扫描多个包,每个包中使用半角逗号分隔
规范:要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中
自动扫描出来的mapper的bean的id为mapper类名(首字母小写) -->
<property name="basePackage" value="cn.itcast.ssm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
而这里配置扫描器之后在SqlMapConfig.xml
中配置的扫描器就不需要了:
<mappers>
<!-- 和spring整合后使用的mapper的扫描器,这里不需要再次配置扫描包了
规范:要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 -->
<package name="cn.itcast.ssm.mapper"/>
</mappers>
上面这段就不需要了,但是注意遵守相关的规范。
注意:这里我们不用sqlSessionFactory
而是使用sqlSessionFactoryBeanName
,是因为会先扫描这里的配置,这样就不会上秒扫面db.properties
文件的扫描器不起作用了。但是我们需要先有数据源才行,所以不能使用sqlSessionFactory
,同时也不能使用引用(ref
)了,而应该使用value
来指定工厂。
注意:在此配置文件中对于类的路径需要写全称,不能像mybatis
配置文件中那样写简称。
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 测试
测试方式基本一样。
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);
}
}
最后:这里我们只是简单整合了一下,在后面再补充使用maven
管理的整合方式。当然方式基本一致,只是包的管理更为方便。