mybatis-spring 框架原理与源码解析--初始化过程

mybatis-spring整合了mybatis和spring,使mybatis能参与spring事务。SqlSessionFactoryBean是核心组件,配置数据源后,可通过SqlSessionTemplate或Mapper接口进行DAO操作。SqlSessionFactoryBean实现FactoryBean接口,方便定制bean创建过程。@MapperScan或MapperScannerConfigurer用于扫描Mapper接口,创建MapperFactoryBean。MapperRegistry存储Mapper接口,MapperProxy作为InvocationHandler处理Mapper调用,接入mybatis核心逻辑。
摘要由CSDN通过智能技术生成

mybatis-spring将mybatis无缝集成到spring框架中,使得mybatis能够参与spring的事务,将mybatis mapper和sqlsession注入到其它bean中,将mybatis的异常转换成spring的DataAccessException等。本文将在代码层面,从spring容器启动到一次数据库访问结束期间,mybatis-spring的运行流程,来解析mybatis的原理及其核心技术。

配置mybatis


使用mybatis-spring,我们有多种配置bean的方式。当然无论如何配置,数据源是必不可少的:

<bean id = “dataSource” class = “org.springframework.jdbc.datasource.DriverManagerDatasource”>
    <property name = “driverClassName” value = “com.mysql.jdbc.Driver”/>
    <property name = “url” value = “jdbc:mysql://localhost:3306/test”/>
    <property name = “username” value = “xxx”/>
    <property name = “password” value = “xxx”/>
</bean>

另外,SqlSessionFactoryBean作为mybtis-spring的核心组件,同样不可缺少:

<bean id = “sqlSessionFactory” class = “org.mybatis.spring.SqlSessionFactoryBean”>
    <property name = “dataSource” ref = “dataSource”/>
    <property name = “configLocation” value = “classpath:mybatis.cfg.xml”/>
</bean>

其中,configLocation属性表示mybatis配置文件的路径。mybatis配置文件可以用于指定mapper文件的路径和设置类别名。

方式一:SqlSessionTemplate会话模板

<bean id = “sqlSessionTemplate” class = “org.mybatis.spring.SqlSessionTemplate”>
    <constructor-arg index = “0” ref = “sqlSessionFactory”/>
</bean>

然后我们可以在DAO bean中注入SqlSessionTemplate bean进行dao操作

@Service
public class UserDaoImpl implements UserDao {

    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> selectUser() {
        return sqlSession.selectList(“com.example.mapper.selectAll”);
    }
}

方式二:dao类继承SqlSessionDaoSupport

@Service
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    
    @Autowired
    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate){
         super.setSqlSessionTemplate(sqlSessionTemplate);
    }

    @Override
    public List<User> selectUser() {
        return this.getSqlSession().selectList(“com.example.mapper.selectAll”);
    }
}

由于mybatis-spring在1.2版本之后,将SqlSessionDaoSupport 中setSqlSessionTemplate 和 setSqlSessionFactory方法上的@Autowired注解移除了,因此我们需要重写其中的一个方法,自行注入SqlSessionFactory或者SqlSessionTemplate bean。方式二与方式一本质上无差别。

方式三:基于mapper接口和注解的配置

以上是使用mybatis的传统方式:在mapper文件中编写sql,将sql的id作为方法参数传入SqlSessionTemplate进行dao操作,这种方式并不符合面向对象的思想,因此mybatis引入了Mapper接口,在Mapper接口方法与Mapper xml文件sql id之间建立映射,因此可以直接通过Mapper接口来进行dao操作,原理后面讲。甚至,我们可以在接口方法上使用@Select等注解来编写sql,省去Mapper xml文件。

public interface UserMapper {
    @Select(“select * from USER”)
    List<user> selectUser();
}

然后创建一个对应的MapperFactoryBean

<bean id = “userMapper” class = “org.mybatis.spring.mapper.MapperFactoryBean”>
    <property name = “mapperInterface” value = “com.example.mapper.UserMapper”/>
    <property name = “sqlSessionFactory” ref = “sqlSessionFactory”/>
</bean>

然后我们可以在任何地方注入UserMapper进行dao操作了。事实上,在底层依然是调用SqlSessionTemplate。

手动为每一个Mapper接口创建一个MapperFactoryBean显然是低效的,Mybatis-Spring提供了一个MapperScannerConfigurer,可以自动扫描Mapper接口并创建MapperFactoryBean。只需要设置其basePackage属性即可

<bean class = “org.mybatis.spring.mapper.MapperScannerConfigurer”>
    <property name = “basePackage” value = “com.example.mapper”/>
</bean>

mybatis-spring还提供了另外一种注解的方式,实现跟MapperScannerConfigurer同样的效果:

@Configuration
@MapperScan(basePackages = "org.mybatis.spring.sample.mapper")
public class MybatisConfig {
}

如果mapper xml文件和mapper接口在相同的路径下,那么MapperFactoryBean会自动去寻找和绑定对应的Mapper,此时就没有必要在mybatis配置文件中指明mapper xml文件的路径了。事实上还有另外一种方式来指定mapper xml文件的路径,即在SqlSessionFactoryBean中配置

<bean id = “sqlSessionFactory” class = “org.mybatis.spring.SqlSessionFactoryBean”>
    <property name = “dataSource” ref = “dataSource”/>
    <property name = “mapperLocation” value = “classpath:com/example/mapper/*.xml”/>
</bean>

这样,我们可以将mybatis配置文件也去除了,除非你需要配置类别名。

更多关于mybatis-spring的使用信息,可参考官网http://www.mybatis.org/spring/getting-started.html

原理分析


1. SqlSessionFactoryBean

SqlSessionFactoryBean实现了FactoryBean<SqlSessionFactory>接口,其getObject()方法返回的是一个DefaultSqlSessionFactory实例。这意味着我们可以从Spring容器中获取两个类型的bean:SqlSessionFactoryBean和SqlSessionFactory。关于Spring的BeanFactory在获取bean时如何处理FactoryBean,可以参考https://blog.csdn.net/zknxx/article/details/79572387https://blog.csdn.net/zknxx/article/details/79588391。使用FactoryBean的好处是,我们可以定制bean实例的创建过程;如,实例化SqlSessionFactory是较为复杂的,需要配置大量的信息,但是如果采取编码的方式,在SqlSessionFactoryBean中封装其实例化细节,问题就变得简单多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值