1、mybatis与spring整合
1.1、整合思路
spring通过单例的方式管理SqlSessiongFactory。
spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession。(spring和mybatis整合自动完成)
持久层的mapper和dao都由spring进行管理。
1.2、整合环境
创建一个新的java工程(接近实际开发的工程结构)
1.3、配置sqlSessionFactory
在applicationContext.xml(spring配置文件)中配置SqlSessionFactory(SqlSessionFactory在mybatis和spring的整合jar包下)
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 加载属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"/>
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 数据源
destroy-method="close":当数据库连接不使用时将链接交给数据库连接池使用而不是直接销毁
-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destory-methond="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 最大连接数 -->
<property name="maxActive" value="10"/>
<!-- 连接池中最多闲置连接数 -->
<property name="maxIdle" value="5"/>
</bean>
</beans>
1.4、mybatis原始dao开发(和spring整合)
1.4.1、mapper.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="com.shuai.mapper.UserMapper">
<!-- 查询用户信息 -->
<select id="selectUserById" parameterType="int" resultType="com.shuai.po.User">
select * from user where id=#{value}
</select>
<update id="updateUserById" parameterType="com.shuai.po.User">
update user set userName=#{userName},address=#{address} where id=#{id}
</update>
</mapper>
1.4.2、sqlMapconfig.xml mybatis全局配置文件
<?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="com.shuai.po"/>
</typeAliases>
<mappers>
<!-- 加载映射文件-->
<mapper resource="sqlmap/UserMapper.xml"/>
</mappers>
</configuration>
1.4.3、dao接口
public interface UserDao {
//根据id查询用户信息
public User selectUserById(Integer id)throws Exception;
}
dao接口实现类需要注入SqlSessionFactory
这里使用spring声明方式配置,配置dao的bean:让userDaoImpl实现类去继承SqlSessionDaoSupport
impl:
/**
* 持久层实现类
* @author guai
*
*/
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
public User selectUserById(Integer id) throws Exception {
// TODO Auto-generated method stub
//通过继承SqlSessionDaoSupport的getSqlSession方法获取sqlSession
SqlSession ss=this.getSqlSession();
User user=ss.selectOne("test.selectById",id);
return user;
}
}
1.4.4、在spring配置文件中配置dao
<!-- 原始dao接口配置
注入SqlSessionFactory -->
<bean id="userDao" class="com.shuai.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
1.4.5、测试
public class UserDaoImplTest {
//在setUp这个方法得到spring容器
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
applicationContext=new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testSelectUserById() {
//从容器中获取对象
UserDao userDao=(UserDao)applicationContext.getBean("userDao");
try {
User user= userDao.selectUserById(1);
System.out.println(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
总结:原始到开发由dao实现层间创建SqlSession去执行xml文件中配置的sql(statement)
过程:在speing配置文件中为dao实现层配置对象注册到spring容器中并为代理对象注入一个SqlSessionFactory工厂,在dao实现层通过继承SqlSessionDaoSupport类再通过父类的getSqlSession方法获取session执行xml文件中配置的sql(statement)
2、mapper代理开发
2.1、mapper.xml和mapper.java
2.2、创建mapper.xml和mapper接口
mapper.xml
<!-- 查询用户信息 -->
<select id="selectUserById" parameterType="int" resultType="com.shuai.po.User">
select * from user where id=#{value}
</select>
<update id="updateUserById" parameterType="com.shuai.po.User">
update user set userName=#{userName},address=#{address} where id=#{id}
</update>
mapper接口:
import com.shuai.po.*;
public interface UserMapper {
//根据id查询用户信息
public User selectUserById(Integer id)throws Exception;
//根据id更新用户信息
public void updateUserById(User user)throws Exception;
}
2.3、在sqlMappingConfig中加载mapper.xml
<mappers>
<!-- 加载映射文件-->
<!--<mapper resource="sqlmap/UserMapper.xml"/> -->
<!-- 通过接口加载映射文件 -->
<package name="com.shuai.mapper"/>
</mappers>
2.4、在applicationContext.xml中通过MapperFactioryBean创建代理对象
<!-- mapper代理开发 配置
配置代理对象并交给spring容器管理
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- 指定mapper接口 -->
<property name="mapperInterface" value="com.shuai.mapper.UserMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
2.5、测试文件
public class userMapperTest {
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
// 创建容器
applicationContext=new ClassPathXmlApplicationContext("spring/applicationContext.xml");
}
@Test
public void testSelectUserById() {
// 对象
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
// 调用接口的方法
try {
//第一次查询id为一得用户
User user=userMapper.selectUserById(1);
System.out.println(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
**总结:mapper映射的方法与原始dao方法相比mapper映射不需要通过sqlSession去执行xml中配置的sql(statement),但mapper.xml与mapper.java接口在创建中必须严格遵循开发规范。
1、在mapper.xml中namespace等于mapper接口的地址
2、mapper.java接口中的方法名和mapper。xml中statement的id一致
3、mapper.java接口中的方法输入参数和mapper。xml中的statement的parameterType指定的类型一致
4、mapper.java接口中的方法返回值的类型和mapper。xml中的statement的resultType指定的类型一致
过程:创建mapper.java接口和mapper.xml映射,在spring配置文件为mapper配置一个代理对象注册到spting容器中并为代理对象指定一个mapper接口并注入一个sqlSessionFactory依赖对象。**
**2.6、问题:使用mapper代理开发时需要为每一个mapper代理对象配置SqlSessionFactory**
2.6.1、使用<bean>继承
<!-- 当需要配置多个mapper时,可单独设置一个用来注入sqlSessionFactory的模板<bean>被继承
abstract="true" :设置bean为模板
lazy-init="true":当需要时实例化bean而不是启动容器时就实例化
-->
<bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<bean id="userMapper" parent="baseMapper">
<property name="mapperInterface" value="com.shuai.mapper.UserMapper"></property>
</bean>
该方法仍然不够简单推荐使用下面方法:
2.6.2、使用MapperScannerConfigurer扫描为mapper代理对象批量注入SqlSessionFactory
此时可使用MapperScannerConfigure批量扫描mapper文件并注入 依赖
<!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并注册到容器中
自动扫描出来色mapper的bean的id为mapper接口名(首字母小写)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描包名
如果扫描多个包 ,包名使用逗号隔开
-->
<property name="basePackage" value="com.shuai.mapper"></property>
<!--注入配置好的sqlSessionFacotory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
2.6.3、测试代码(上面方法都适用):
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
// 创建容器
applicationContext=new ClassPathXmlApplicationContext("spring/applicationContext.xml");
}
@Test
public void testSelectUserById() {
// 从容器中获取对象
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
// 调用接口的方法
try {
//第一次查询id为一得用户
User user=userMapper.selectUserById(1);
System.out.println(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}