官网:http://mybatis.org/spring/zh/sqlsession.html
SqlSessionDaoSupport
SqlSessionDaoSupport 类的特点:(一个抽象的支持类)
1、持有一个 SqlSession 对象 :SqlSessionTemplate
(这个 SqlSessionTemplate 是线程安全的)。
这个 SqlSessionTemplate 需要通过外部传一个 SqlSessionFactory 实例来构建,或者直接传入一个 SqlSessionTemplate。
2、SqlSessionDaoSupport 的子类可以通过调用它的 getSqlSession()
方法来获取这个 SqlSessionTemplate
public abstract class SqlSessionDaoSupport extends DaoSupport {
private SqlSession sqlSession;
// 通过外部传一个 SqlSessionFactory 实例来构建 SqlSession sqlSessionTemplate (理解set方法的本质)
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
if (!this.externalSqlSession) {
this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
//利用 SqlSessionFactory 创建 SqlSessionTemplate
//SqlSessionTemplate的初始化:看博客:https://blog.csdn.net/weixin_38192427/article/details/123298724
}
}
// 直接传入一个 SqlSession sqlSessionTemplate 实例来构建 SqlSession sqlSessionTemplate
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSession = sqlSessionTemplate;
this.externalSqlSession = true;
}
// 提供给子类获取 SqlSession SqlSessionTemplate
public SqlSession getSqlSession() {
return this.sqlSession;
}
}
例子:
要为 SqlSessionDaoSupport 的子类配置 SqlSessionFactory 来构建 SqlSessionTemplate (SqlSessionDaoSupport 是一个抽象类,不能创建对象,所以只能用子类继承它才能使用)
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
这样,子类 UserDaoImpl 就可以通过 getSqlSession()
来获取 SqlSessionTemplate 使用了 (selectOne、…)
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
public User getUser(int userId) {
return getSqlSession().selectOne("UserMapper.xml 中的 Sql语句 的 ID:getUser", userId);
}
}
这种方式没有使用接口代理,而是使用的是 SqlSession 中的原生的 selectOne()、insert()、update()… 方法
MapperFactoryBean
使用它可以用来向spring容器中注入mapper接口的代理对象
继承了 SqlSessionDaoSupport (可使用getSqlSession()获取SqlSessionTemplate),
实现了 FactoryBean 方法(负责生产mapper接口的代理对象):
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
private Class<T> mapperInterface; //需要代理的接口
...
public MapperFactoryBean(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
...
/**
* 返回一个接口的代理实现,注入到spring容器中
*/
@Override
public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}
}
在 getObject()
方法中调用了 getSqlSession().getMapper(this.mapperInterface) 返回接口的代理对象
因为 MapperFactoryBean 是产生 mapper 接口的代理对象的,所以要为其配置 mapperInterface (目标代理接口)属性
同时,别忘了 SqlSessionDaoSupport 的子类要配置 SqlSessionFactory 来构建 SqlSessionTemplate
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.springdemo.dao.UserDao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
这样,就可以直接从容器中获取 mapper 接口的代理对象:
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
// 使用 userDao...
}
通过配置 MapperFactoryBean 的方式,只能向容器中注入一个接口代理对象。
当有很多 DAO 接口时,就需要为每一个 DAO 接口配置 MapperFactoryBean
这种方式显然是很低效的,为了解决这个问题,我们使用 MapperScannerConfigurer
,让它扫描一个包下的所有接口,成批地向容器中注入接口代理对象。【看下一篇】